|
27 | 27 | from collections import defaultdict |
28 | 28 | from collections.abc import Collection, Iterable |
29 | 29 | from datetime import datetime, timedelta |
30 | | -from functools import cache |
31 | 30 | from typing import TYPE_CHECKING, Any |
32 | 31 | from urllib.parse import quote |
33 | 32 |
|
34 | 33 | import attrs |
35 | 34 | import dill |
36 | | -import lazy_object_proxy |
37 | 35 | import uuid6 |
38 | 36 | from sqlalchemy import ( |
39 | 37 | JSON, |
|
72 | 70 | from airflow.assets.manager import asset_manager |
73 | 71 | from airflow.configuration import conf |
74 | 72 | from airflow.listeners.listener import get_listener_manager |
75 | | -from airflow.models.asset import AssetEvent, AssetModel |
| 73 | +from airflow.models.asset import AssetModel |
76 | 74 | from airflow.models.base import Base, StringID, TaskInstanceDependencies |
77 | 75 | from airflow.models.dag_version import DagVersion |
78 | 76 |
|
|
106 | 104 | from datetime import datetime |
107 | 105 | from typing import Literal |
108 | 106 |
|
109 | | - import pendulum |
110 | 107 | from sqlalchemy.engine import Connection as SAConnection, Engine |
111 | 108 | from sqlalchemy.orm.session import Session |
112 | 109 | from sqlalchemy.sql import Update |
|
115 | 112 | from airflow.api_fastapi.execution_api.datamodels.asset import AssetProfile |
116 | 113 | from airflow.models.dag import DagModel |
117 | 114 | from airflow.models.dagrun import DagRun |
118 | | - from airflow.sdk import Context |
119 | 115 | from airflow.serialization.definitions.dag import SerializedDAG |
120 | 116 | from airflow.serialization.definitions.mappedoperator import Operator |
121 | 117 | from airflow.serialization.definitions.taskgroup import SerializedTaskGroup |
@@ -1567,160 +1563,6 @@ def is_eligible_to_retry(self) -> bool: |
1567 | 1563 |
|
1568 | 1564 | return bool(self.task.retries and self.try_number <= self.max_tries) |
1569 | 1565 |
|
1570 | | - # TODO (GH-52141): We should remove this entire function (only makes sense at runtime). |
1571 | | - def get_template_context( |
1572 | | - self, |
1573 | | - session: Session | None = None, |
1574 | | - ignore_param_exceptions: bool = True, |
1575 | | - ) -> Context: |
1576 | | - """ |
1577 | | - Return TI Context. |
1578 | | -
|
1579 | | - :param session: SQLAlchemy ORM Session |
1580 | | - :param ignore_param_exceptions: flag to suppress value exceptions while initializing the ParamsDict |
1581 | | - """ |
1582 | | - # Do not use provide_session here -- it expunges everything on exit! |
1583 | | - if not session: |
1584 | | - session = settings.get_session()() |
1585 | | - |
1586 | | - from airflow.exceptions import NotMapped |
1587 | | - from airflow.sdk.api.datamodels._generated import ( |
1588 | | - DagRun as DagRunSDK, |
1589 | | - PrevSuccessfulDagRunResponse, |
1590 | | - TIRunContext, |
1591 | | - ) |
1592 | | - from airflow.sdk.definitions.param import process_params |
1593 | | - from airflow.sdk.execution_time.context import InletEventsAccessors |
1594 | | - from airflow.sdk.execution_time.task_runner import RuntimeTaskInstance |
1595 | | - from airflow.serialization.definitions.mappedoperator import get_mapped_ti_count |
1596 | | - from airflow.utils.context import ( |
1597 | | - ConnectionAccessor, |
1598 | | - OutletEventAccessors, |
1599 | | - VariableAccessor, |
1600 | | - ) |
1601 | | - |
1602 | | - if TYPE_CHECKING: |
1603 | | - assert session |
1604 | | - |
1605 | | - def _get_dagrun(session: Session) -> DagRun: |
1606 | | - dag_run = self.get_dagrun(session) |
1607 | | - if dag_run in session: |
1608 | | - return dag_run |
1609 | | - # The dag_run may not be attached to the session anymore since the |
1610 | | - # code base is over-zealous with use of session.expunge_all(). |
1611 | | - # Re-attach it if the relation is not loaded so we can load it when needed. |
1612 | | - info: Any = inspect(dag_run) |
1613 | | - if info.attrs.consumed_asset_events.loaded_value is not NO_VALUE: |
1614 | | - return dag_run |
1615 | | - # If dag_run is not flushed to db at all (e.g. CLI commands using |
1616 | | - # in-memory objects for ad-hoc operations), just set the value manually. |
1617 | | - if not info.has_identity: |
1618 | | - dag_run.consumed_asset_events = [] |
1619 | | - return dag_run |
1620 | | - return session.merge(dag_run, load=False) |
1621 | | - |
1622 | | - task: Any = self.task |
1623 | | - dag = task.dag |
1624 | | - dag_run = _get_dagrun(session) |
1625 | | - |
1626 | | - validated_params = process_params(dag, task, dag_run.conf, suppress_exception=ignore_param_exceptions) |
1627 | | - runtime_ti = RuntimeTaskInstance.model_construct( |
1628 | | - id=self.id, |
1629 | | - task_id=self.task_id, |
1630 | | - dag_id=self.dag_id, |
1631 | | - run_id=self.run_id, |
1632 | | - try_numer=self.try_number, |
1633 | | - map_index=self.map_index, |
1634 | | - task=self.task, |
1635 | | - max_tries=self.max_tries, |
1636 | | - hostname=self.hostname, |
1637 | | - _ti_context_from_server=TIRunContext( |
1638 | | - dag_run=DagRunSDK.model_validate(dag_run, from_attributes=True), |
1639 | | - max_tries=self.max_tries, |
1640 | | - should_retry=self.is_eligible_to_retry(), |
1641 | | - ), |
1642 | | - start_date=self.start_date, |
1643 | | - dag_version_id=self.dag_version_id, |
1644 | | - ) |
1645 | | - |
1646 | | - context: Context = runtime_ti.get_template_context() |
1647 | | - |
1648 | | - @cache # Prevent multiple database access. |
1649 | | - def _get_previous_dagrun_success() -> PrevSuccessfulDagRunResponse: |
1650 | | - dr_from_db = self.get_previous_dagrun(state=DagRunState.SUCCESS, session=session) |
1651 | | - if dr_from_db: |
1652 | | - return PrevSuccessfulDagRunResponse.model_validate(dr_from_db, from_attributes=True) |
1653 | | - return PrevSuccessfulDagRunResponse() |
1654 | | - |
1655 | | - def get_prev_data_interval_start_success() -> pendulum.DateTime | None: |
1656 | | - return timezone.coerce_datetime(_get_previous_dagrun_success().data_interval_start) |
1657 | | - |
1658 | | - def get_prev_data_interval_end_success() -> pendulum.DateTime | None: |
1659 | | - return timezone.coerce_datetime(_get_previous_dagrun_success().data_interval_end) |
1660 | | - |
1661 | | - def get_prev_start_date_success() -> pendulum.DateTime | None: |
1662 | | - return timezone.coerce_datetime(_get_previous_dagrun_success().start_date) |
1663 | | - |
1664 | | - def get_prev_end_date_success() -> pendulum.DateTime | None: |
1665 | | - return timezone.coerce_datetime(_get_previous_dagrun_success().end_date) |
1666 | | - |
1667 | | - def get_triggering_events() -> dict[str, list[AssetEvent]]: |
1668 | | - asset_events = dag_run.consumed_asset_events |
1669 | | - triggering_events: dict[str, list[AssetEvent]] = defaultdict(list) |
1670 | | - for event in asset_events: |
1671 | | - if event.asset: |
1672 | | - triggering_events[event.asset.uri].append(event) |
1673 | | - |
1674 | | - return triggering_events |
1675 | | - |
1676 | | - # NOTE: If you add to this dict, make sure to also update the following: |
1677 | | - # * Context in task-sdk/src/airflow/sdk/definitions/context.py |
1678 | | - # * KNOWN_CONTEXT_KEYS in airflow/utils/context.py |
1679 | | - # * Table in docs/apache-airflow/templates-ref.rst |
1680 | | - |
1681 | | - context.update( |
1682 | | - { |
1683 | | - "outlet_events": OutletEventAccessors(), |
1684 | | - "inlet_events": InletEventsAccessors(task.inlets), |
1685 | | - "params": validated_params, |
1686 | | - "prev_data_interval_start_success": get_prev_data_interval_start_success(), |
1687 | | - "prev_data_interval_end_success": get_prev_data_interval_end_success(), |
1688 | | - "prev_start_date_success": get_prev_start_date_success(), |
1689 | | - "prev_end_date_success": get_prev_end_date_success(), |
1690 | | - "test_mode": self.test_mode, |
1691 | | - # ti/task_instance are added here for ti.xcom_{push,pull} |
1692 | | - "task_instance": self, |
1693 | | - "ti": self, |
1694 | | - "triggering_asset_events": lazy_object_proxy.Proxy(get_triggering_events), |
1695 | | - "var": { |
1696 | | - "json": VariableAccessor(deserialize_json=True), |
1697 | | - "value": VariableAccessor(deserialize_json=False), |
1698 | | - }, |
1699 | | - "conn": ConnectionAccessor(), |
1700 | | - } |
1701 | | - ) |
1702 | | - |
1703 | | - try: |
1704 | | - expanded_ti_count: int | None = get_mapped_ti_count(task, self.run_id, session=session) |
1705 | | - context["expanded_ti_count"] = expanded_ti_count |
1706 | | - if expanded_ti_count: |
1707 | | - setattr( |
1708 | | - self, |
1709 | | - "_upstream_map_indexes", |
1710 | | - { |
1711 | | - upstream.task_id: self.get_relevant_upstream_map_indexes( |
1712 | | - upstream, |
1713 | | - expanded_ti_count, |
1714 | | - session=session, |
1715 | | - ) |
1716 | | - for upstream in task.upstream_list |
1717 | | - }, |
1718 | | - ) |
1719 | | - except NotMapped: |
1720 | | - pass |
1721 | | - |
1722 | | - return context |
1723 | | - |
1724 | 1566 | def set_duration(self) -> None: |
1725 | 1567 | """Set task instance duration.""" |
1726 | 1568 | if self.end_date and self.start_date: |
|
0 commit comments