apache-airflow-providers-standard 1.5.0rc1__tar.gz → 1.6.0rc1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of apache-airflow-providers-standard might be problematic. Click here for more details.
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/PKG-INFO +6 -6
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/README.rst +3 -3
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/docs/changelog.rst +34 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/docs/index.rst +1 -1
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/docs/operators/python.rst +7 -7
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/provider.yaml +2 -1
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/pyproject.toml +3 -3
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/__init__.py +1 -1
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/example_dags/example_external_task_parent_deferrable.py +5 -1
- apache_airflow_providers_standard-1.6.0rc1/src/airflow/providers/standard/example_dags/example_hitl_operator.py +170 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/operators/hitl.py +33 -12
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/sensors/time.py +8 -3
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/triggers/hitl.py +11 -3
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/tests/unit/standard/operators/test_hitl.py +61 -2
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/tests/unit/standard/sensors/test_date_time.py +2 -1
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/tests/unit/standard/sensors/test_python.py +1 -1
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/tests/unit/standard/sensors/test_time.py +14 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/tests/unit/standard/sensors/test_time_delta.py +12 -15
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/tests/unit/standard/sensors/test_weekday.py +4 -6
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/tests/unit/standard/triggers/test_hitl.py +33 -25
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/tests/unit/standard/utils/test_python_virtualenv.py +1 -1
- apache_airflow_providers_standard-1.5.0rc1/src/airflow/providers/standard/example_dags/example_hitl_operator.py +0 -81
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/docs/commits.rst +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/docs/conf.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/docs/configurations-ref.rst +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/docs/installing-providers-from-sources.rst +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/docs/operators/bash.rst +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/docs/operators/datetime.rst +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/docs/operators/index.rst +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/docs/operators/latest_only.rst +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/docs/operators/trigger_dag_run.rst +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/docs/security.rst +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/docs/sensors/bash.rst +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/docs/sensors/datetime.rst +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/docs/sensors/external_task_sensor.rst +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/docs/sensors/file.rst +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/docs/sensors/index.rst +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/docs/sensors/python.rst +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/__init__.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/__init__.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/LICENSE +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/decorators/__init__.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/decorators/bash.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/decorators/branch_external_python.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/decorators/branch_python.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/decorators/branch_virtualenv.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/decorators/external_python.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/decorators/python.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/decorators/python_virtualenv.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/decorators/sensor.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/decorators/short_circuit.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/example_dags/__init__.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/example_dags/example_bash_decorator.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/example_dags/example_bash_operator.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/example_dags/example_branch_datetime_operator.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/example_dags/example_branch_day_of_week_operator.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/example_dags/example_branch_operator.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/example_dags/example_branch_operator_decorator.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/example_dags/example_external_task_child_deferrable.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/example_dags/example_external_task_marker_dag.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/example_dags/example_latest_only.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/example_dags/example_python_decorator.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/example_dags/example_python_operator.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/example_dags/example_sensor_decorator.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/example_dags/example_sensors.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/example_dags/example_short_circuit_decorator.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/example_dags/example_short_circuit_operator.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/example_dags/example_trigger_controller_dag.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/example_dags/sql/__init__.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/example_dags/sql/sample.sql +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/exceptions.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/get_provider_info.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/hooks/__init__.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/hooks/filesystem.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/hooks/package_index.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/hooks/subprocess.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/models/__init__.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/operators/__init__.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/operators/bash.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/operators/branch.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/operators/datetime.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/operators/empty.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/operators/latest_only.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/operators/python.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/operators/smooth.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/operators/trigger_dagrun.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/operators/weekday.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/sensors/__init__.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/sensors/bash.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/sensors/date_time.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/sensors/external_task.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/sensors/filesystem.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/sensors/python.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/sensors/time_delta.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/sensors/weekday.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/triggers/__init__.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/triggers/external_task.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/triggers/file.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/triggers/temporal.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/utils/__init__.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/utils/python_virtualenv.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/utils/python_virtualenv_script.jinja2 +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/utils/sensor_helper.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/utils/skipmixin.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/utils/weekday.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/src/airflow/providers/standard/version_compat.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/tests/conftest.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/tests/unit/__init__.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/tests/unit/standard/__init__.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/tests/unit/standard/decorators/__init__.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/tests/unit/standard/decorators/test_bash.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/tests/unit/standard/decorators/test_branch_external_python.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/tests/unit/standard/decorators/test_branch_python.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/tests/unit/standard/decorators/test_branch_virtualenv.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/tests/unit/standard/decorators/test_external_python.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/tests/unit/standard/decorators/test_python.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/tests/unit/standard/decorators/test_python_virtualenv.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/tests/unit/standard/decorators/test_sensor.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/tests/unit/standard/decorators/test_short_circuit.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/tests/unit/standard/hooks/__init__.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/tests/unit/standard/hooks/test_filesystem.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/tests/unit/standard/hooks/test_package_index.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/tests/unit/standard/hooks/test_subprocess.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/tests/unit/standard/operators/__init__.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/tests/unit/standard/operators/test_bash.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/tests/unit/standard/operators/test_branch_operator.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/tests/unit/standard/operators/test_datetime.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/tests/unit/standard/operators/test_latest_only_operator.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/tests/unit/standard/operators/test_python.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/tests/unit/standard/operators/test_smooth.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/tests/unit/standard/operators/test_trigger_dagrun.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/tests/unit/standard/operators/test_weekday.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/tests/unit/standard/sensors/__init__.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/tests/unit/standard/sensors/test_bash.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/tests/unit/standard/sensors/test_external_task_sensor.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/tests/unit/standard/test_exceptions.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/tests/unit/standard/triggers/__init__.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/tests/unit/standard/triggers/test_external_task.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/tests/unit/standard/triggers/test_file.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/tests/unit/standard/triggers/test_temporal.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/tests/unit/standard/utils/__init__.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/tests/unit/standard/utils/test_sensor_helper.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/tests/unit/standard/utils/test_skipmixin.py +0 -0
- {apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/tests/unit/standard/utils/test_weekday.py +0 -0
{apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: apache-airflow-providers-standard
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.6.0rc1
|
|
4
4
|
Summary: Provider package apache-airflow-providers-standard for Apache Airflow
|
|
5
5
|
Keywords: airflow-provider,standard,airflow,integration
|
|
6
6
|
Author-email: Apache Software Foundation <dev@airflow.apache.org>
|
|
@@ -22,8 +22,8 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
22
22
|
Classifier: Topic :: System :: Monitoring
|
|
23
23
|
Requires-Dist: apache-airflow>=2.10.0rc1
|
|
24
24
|
Project-URL: Bug Tracker, https://github.com/apache/airflow/issues
|
|
25
|
-
Project-URL: Changelog, https://airflow.staged.apache.org/docs/apache-airflow-providers-standard/1.
|
|
26
|
-
Project-URL: Documentation, https://airflow.staged.apache.org/docs/apache-airflow-providers-standard/1.
|
|
25
|
+
Project-URL: Changelog, https://airflow.staged.apache.org/docs/apache-airflow-providers-standard/1.6.0/changelog.html
|
|
26
|
+
Project-URL: Documentation, https://airflow.staged.apache.org/docs/apache-airflow-providers-standard/1.6.0
|
|
27
27
|
Project-URL: Mastodon, https://fosstodon.org/@airflow
|
|
28
28
|
Project-URL: Slack Chat, https://s.apache.org/airflow-slack
|
|
29
29
|
Project-URL: Source Code, https://github.com/apache/airflow
|
|
@@ -54,7 +54,7 @@ Project-URL: YouTube, https://www.youtube.com/channel/UCSXwxpWZQ7XZ1WL3wqevChA/
|
|
|
54
54
|
|
|
55
55
|
Package ``apache-airflow-providers-standard``
|
|
56
56
|
|
|
57
|
-
Release: ``1.
|
|
57
|
+
Release: ``1.6.0``
|
|
58
58
|
|
|
59
59
|
Release Date: ``|PypiReleaseDate|``
|
|
60
60
|
|
|
@@ -68,7 +68,7 @@ This is a provider package for ``standard`` provider. All classes for this provi
|
|
|
68
68
|
are in ``airflow.providers.standard`` python package.
|
|
69
69
|
|
|
70
70
|
You can find package information and changelog for the provider
|
|
71
|
-
in the `documentation <https://airflow.apache.org/docs/apache-airflow-providers-standard/1.
|
|
71
|
+
in the `documentation <https://airflow.apache.org/docs/apache-airflow-providers-standard/1.6.0/>`_.
|
|
72
72
|
|
|
73
73
|
Installation
|
|
74
74
|
------------
|
|
@@ -89,5 +89,5 @@ PIP package Version required
|
|
|
89
89
|
================== ==================
|
|
90
90
|
|
|
91
91
|
The changelog for the provider package can be found in the
|
|
92
|
-
`changelog <https://airflow.apache.org/docs/apache-airflow-providers-standard/1.
|
|
92
|
+
`changelog <https://airflow.apache.org/docs/apache-airflow-providers-standard/1.6.0/changelog.html>`_.
|
|
93
93
|
|
{apache_airflow_providers_standard-1.5.0rc1 → apache_airflow_providers_standard-1.6.0rc1}/README.rst
RENAMED
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
|
|
24
24
|
Package ``apache-airflow-providers-standard``
|
|
25
25
|
|
|
26
|
-
Release: ``1.
|
|
26
|
+
Release: ``1.6.0``
|
|
27
27
|
|
|
28
28
|
Release Date: ``|PypiReleaseDate|``
|
|
29
29
|
|
|
@@ -37,7 +37,7 @@ This is a provider package for ``standard`` provider. All classes for this provi
|
|
|
37
37
|
are in ``airflow.providers.standard`` python package.
|
|
38
38
|
|
|
39
39
|
You can find package information and changelog for the provider
|
|
40
|
-
in the `documentation <https://airflow.apache.org/docs/apache-airflow-providers-standard/1.
|
|
40
|
+
in the `documentation <https://airflow.apache.org/docs/apache-airflow-providers-standard/1.6.0/>`_.
|
|
41
41
|
|
|
42
42
|
Installation
|
|
43
43
|
------------
|
|
@@ -58,4 +58,4 @@ PIP package Version required
|
|
|
58
58
|
================== ==================
|
|
59
59
|
|
|
60
60
|
The changelog for the provider package can be found in the
|
|
61
|
-
`changelog <https://airflow.apache.org/docs/apache-airflow-providers-standard/1.
|
|
61
|
+
`changelog <https://airflow.apache.org/docs/apache-airflow-providers-standard/1.6.0/changelog.html>`_.
|
|
@@ -35,6 +35,40 @@
|
|
|
35
35
|
Changelog
|
|
36
36
|
---------
|
|
37
37
|
|
|
38
|
+
1.6.0
|
|
39
|
+
.....
|
|
40
|
+
|
|
41
|
+
Features
|
|
42
|
+
~~~~~~~~
|
|
43
|
+
|
|
44
|
+
* ``feat(htil): add 'notifiers' to HITLOperator (#54128)``
|
|
45
|
+
* ``feat(hitl): add HITLBranchOperator (#53960)``
|
|
46
|
+
* ``feat(HITL): improve hitl trigger logging message (#53850)``
|
|
47
|
+
* ``feat(hitl): add "timedout" column to HITLTriggerEventSuccessPayload (#53852)``
|
|
48
|
+
|
|
49
|
+
Bug Fixes
|
|
50
|
+
~~~~~~~~~
|
|
51
|
+
|
|
52
|
+
* ``Restore 'execute_complete' functionality 'TimeSensor' when 'deferrable=True' (#53669)``
|
|
53
|
+
* ``Fix several deprecation warnings related to airflow.sdk (#53791)``
|
|
54
|
+
|
|
55
|
+
Misc
|
|
56
|
+
~~~~
|
|
57
|
+
|
|
58
|
+
* ``refactor(hitl): replace timezone usage with airflow.sdk.timezone (#53962)``
|
|
59
|
+
* ``refactor(HITL): make default options class variables to avoid typo (#53849)``
|
|
60
|
+
|
|
61
|
+
Doc-only
|
|
62
|
+
~~~~~~~~
|
|
63
|
+
|
|
64
|
+
* ``Fix BranchPythonOperator doc (#54205)``
|
|
65
|
+
|
|
66
|
+
.. Below changes are excluded from the changelog. Move them to
|
|
67
|
+
appropriate section above if needed. Do not delete the lines(!):
|
|
68
|
+
* ``Documentation for Human-in-the-loop operator (#53694)``
|
|
69
|
+
* ``Correct HITL version warnings to avoid confusion (#53876)``
|
|
70
|
+
* ``Move functions in 'airflow.utils.decorator' to more appropriate places (#53420)``
|
|
71
|
+
|
|
38
72
|
1.5.0
|
|
39
73
|
.....
|
|
40
74
|
|
|
@@ -298,16 +298,16 @@ Templating
|
|
|
298
298
|
Jinja templating can be used in same way as described for the :ref:`howto/operator:PythonOperator`.
|
|
299
299
|
|
|
300
300
|
|
|
301
|
-
.. _howto/operator:
|
|
301
|
+
.. _howto/operator:BranchPythonOperator:
|
|
302
302
|
|
|
303
|
-
|
|
303
|
+
BranchPythonOperator
|
|
304
304
|
====================
|
|
305
305
|
|
|
306
|
-
Use the :class:`~airflow.providers.standard.operators.python.
|
|
306
|
+
Use the :class:`~airflow.providers.standard.operators.python.BranchPythonOperator` to execute Python :ref:`branching <concepts:branching>`
|
|
307
307
|
tasks.
|
|
308
308
|
|
|
309
309
|
.. tip::
|
|
310
|
-
The ``@task.branch`` decorator is recommended over the classic ``
|
|
310
|
+
The ``@task.branch`` decorator is recommended over the classic ``BranchPythonOperator``
|
|
311
311
|
to execute Python code.
|
|
312
312
|
|
|
313
313
|
.. tab-set::
|
|
@@ -321,7 +321,7 @@ tasks.
|
|
|
321
321
|
:start-after: [START howto_operator_branch_python]
|
|
322
322
|
:end-before: [END howto_operator_branch_python]
|
|
323
323
|
|
|
324
|
-
.. tab-item::
|
|
324
|
+
.. tab-item:: BranchPythonOperator
|
|
325
325
|
:sync: operator
|
|
326
326
|
|
|
327
327
|
.. exampleinclude:: /../src/airflow/providers/standard/example_dags/example_branch_operator.py
|
|
@@ -341,7 +341,7 @@ BranchPythonVirtualenvOperator
|
|
|
341
341
|
==============================
|
|
342
342
|
|
|
343
343
|
Use the :class:`~airflow.providers.standard.operators.python.BranchPythonVirtualenvOperator` decorator to execute Python :ref:`branching <concepts:branching>`
|
|
344
|
-
tasks and is a hybrid of the :class:`~airflow.providers.standard.operators.python.
|
|
344
|
+
tasks and is a hybrid of the :class:`~airflow.providers.standard.operators.python.BranchPythonOperator` with execution in a virtual environment.
|
|
345
345
|
|
|
346
346
|
.. tip::
|
|
347
347
|
The ``@task.branch_virtualenv`` decorator is recommended over the classic
|
|
@@ -378,7 +378,7 @@ BranchExternalPythonOperator
|
|
|
378
378
|
============================
|
|
379
379
|
|
|
380
380
|
Use the :class:`~airflow.providers.standard.operators.python.BranchExternalPythonOperator` to execute Python :ref:`branching <concepts:branching>`
|
|
381
|
-
tasks and is a hybrid of the :class:`~airflow.providers.standard.operators.python.
|
|
381
|
+
tasks and is a hybrid of the :class:`~airflow.providers.standard.operators.python.BranchPythonOperator` with execution in an
|
|
382
382
|
external Python environment.
|
|
383
383
|
|
|
384
384
|
.. tip::
|
|
@@ -21,12 +21,13 @@ name: Standard
|
|
|
21
21
|
description: |
|
|
22
22
|
Airflow Standard Provider
|
|
23
23
|
state: ready
|
|
24
|
-
source-date-epoch:
|
|
24
|
+
source-date-epoch: 1754503555
|
|
25
25
|
# Note that those versions are maintained by release manager - do not update them manually
|
|
26
26
|
# with the exception of case where other provider in sources has >= new provider version.
|
|
27
27
|
# In such case adding >= NEW_VERSION and bumping to NEW_VERSION in a provider have
|
|
28
28
|
# to be done in the same PR
|
|
29
29
|
versions:
|
|
30
|
+
- 1.6.0
|
|
30
31
|
- 1.5.0
|
|
31
32
|
- 1.4.1
|
|
32
33
|
- 1.4.0
|
|
@@ -25,7 +25,7 @@ build-backend = "flit_core.buildapi"
|
|
|
25
25
|
|
|
26
26
|
[project]
|
|
27
27
|
name = "apache-airflow-providers-standard"
|
|
28
|
-
version = "1.
|
|
28
|
+
version = "1.6.0rc1"
|
|
29
29
|
description = "Provider package apache-airflow-providers-standard for Apache Airflow"
|
|
30
30
|
readme = "README.rst"
|
|
31
31
|
authors = [
|
|
@@ -95,8 +95,8 @@ apache-airflow-providers-common-sql = {workspace = true}
|
|
|
95
95
|
apache-airflow-providers-standard = {workspace = true}
|
|
96
96
|
|
|
97
97
|
[project.urls]
|
|
98
|
-
"Documentation" = "https://airflow.staged.apache.org/docs/apache-airflow-providers-standard/1.
|
|
99
|
-
"Changelog" = "https://airflow.staged.apache.org/docs/apache-airflow-providers-standard/1.
|
|
98
|
+
"Documentation" = "https://airflow.staged.apache.org/docs/apache-airflow-providers-standard/1.6.0"
|
|
99
|
+
"Changelog" = "https://airflow.staged.apache.org/docs/apache-airflow-providers-standard/1.6.0/changelog.html"
|
|
100
100
|
"Bug Tracker" = "https://github.com/apache/airflow/issues"
|
|
101
101
|
"Source Code" = "https://github.com/apache/airflow"
|
|
102
102
|
"Slack Chat" = "https://s.apache.org/airflow-slack"
|
|
@@ -29,7 +29,7 @@ from airflow import __version__ as airflow_version
|
|
|
29
29
|
|
|
30
30
|
__all__ = ["__version__"]
|
|
31
31
|
|
|
32
|
-
__version__ = "1.
|
|
32
|
+
__version__ = "1.6.0"
|
|
33
33
|
|
|
34
34
|
if packaging.version.parse(packaging.version.parse(airflow_version).base_version) < packaging.version.parse(
|
|
35
35
|
"2.10.0"
|
|
@@ -20,7 +20,11 @@ from airflow import DAG
|
|
|
20
20
|
from airflow.providers.standard.operators.empty import EmptyOperator
|
|
21
21
|
from airflow.providers.standard.operators.trigger_dagrun import TriggerDagRunOperator
|
|
22
22
|
from airflow.providers.standard.sensors.external_task import ExternalTaskSensor
|
|
23
|
-
|
|
23
|
+
|
|
24
|
+
try:
|
|
25
|
+
from airflow.sdk.timezone import datetime
|
|
26
|
+
except ImportError:
|
|
27
|
+
from airflow.utils.timezone import datetime # type: ignore[no-redef]
|
|
24
28
|
|
|
25
29
|
with DAG(
|
|
26
30
|
dag_id="example_external_task",
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
# Licensed to the Apache Software Foundation (ASF) under one
|
|
2
|
+
# or more contributor license agreements. See the NOTICE file
|
|
3
|
+
# distributed with this work for additional information
|
|
4
|
+
# regarding copyright ownership. The ASF licenses this file
|
|
5
|
+
# to you under the Apache License, Version 2.0 (the
|
|
6
|
+
# "License"); you may not use this file except in compliance
|
|
7
|
+
# with the License. You may obtain a copy of the License at
|
|
8
|
+
#
|
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
#
|
|
11
|
+
# Unless required by applicable law or agreed to in writing,
|
|
12
|
+
# software distributed under the License is distributed on an
|
|
13
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
14
|
+
# KIND, either express or implied. See the License for the
|
|
15
|
+
# specific language governing permissions and limitations
|
|
16
|
+
# under the License.
|
|
17
|
+
|
|
18
|
+
from __future__ import annotations
|
|
19
|
+
|
|
20
|
+
import datetime
|
|
21
|
+
from typing import TYPE_CHECKING
|
|
22
|
+
|
|
23
|
+
import pendulum
|
|
24
|
+
|
|
25
|
+
from airflow.providers.standard.operators.hitl import (
|
|
26
|
+
ApprovalOperator,
|
|
27
|
+
HITLBranchOperator,
|
|
28
|
+
HITLEntryOperator,
|
|
29
|
+
HITLOperator,
|
|
30
|
+
)
|
|
31
|
+
from airflow.sdk import DAG, Param, task
|
|
32
|
+
from airflow.sdk.bases.notifier import BaseNotifier
|
|
33
|
+
|
|
34
|
+
if TYPE_CHECKING:
|
|
35
|
+
from airflow.sdk.definitions.context import Context
|
|
36
|
+
|
|
37
|
+
# [START hitl_tutorial]
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class LocalLogNotifier(BaseNotifier):
|
|
41
|
+
"""Simple notifier to demonstrate HITL notification without setup any connection."""
|
|
42
|
+
|
|
43
|
+
template_fields = ("message",)
|
|
44
|
+
|
|
45
|
+
def __init__(self, message: str) -> None:
|
|
46
|
+
self.message = message
|
|
47
|
+
|
|
48
|
+
def notify(self, context: Context) -> None:
|
|
49
|
+
self.log.info(self.message)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
# [START htil_notifer]
|
|
53
|
+
hitl_request_callback = LocalLogNotifier(
|
|
54
|
+
message="""
|
|
55
|
+
[HITL]
|
|
56
|
+
Subject: {{ task.subject }}
|
|
57
|
+
Body: {{ task.body }}
|
|
58
|
+
Options: {{ task.options }}
|
|
59
|
+
Is Multiple Option: {{ task.multiple }}
|
|
60
|
+
Default Options: {{ task.defaults }}
|
|
61
|
+
Params: {{ task.params }}
|
|
62
|
+
"""
|
|
63
|
+
)
|
|
64
|
+
hitl_success_callback = LocalLogNotifier(
|
|
65
|
+
message="{% set task_id = task.task_id -%}{{ ti.xcom_pull(task_ids=task_id) }}"
|
|
66
|
+
)
|
|
67
|
+
hitl_failure_callback = LocalLogNotifier(message="Request to response to '{{ task.subject }}' failed")
|
|
68
|
+
# [END htil_notifer]
|
|
69
|
+
|
|
70
|
+
with DAG(
|
|
71
|
+
dag_id="example_hitl_operator",
|
|
72
|
+
start_date=pendulum.datetime(2021, 1, 1, tz="UTC"),
|
|
73
|
+
catchup=False,
|
|
74
|
+
tags=["example", "HITL"],
|
|
75
|
+
):
|
|
76
|
+
# [START howto_hitl_entry_operator]
|
|
77
|
+
wait_for_input = HITLEntryOperator(
|
|
78
|
+
task_id="wait_for_input",
|
|
79
|
+
subject="Please provide required information: ",
|
|
80
|
+
params={"information": Param("", type="string")},
|
|
81
|
+
notifiers=[hitl_request_callback],
|
|
82
|
+
on_success_callback=hitl_success_callback,
|
|
83
|
+
on_failure_callback=hitl_failure_callback,
|
|
84
|
+
)
|
|
85
|
+
# [END howto_hitl_entry_operator]
|
|
86
|
+
|
|
87
|
+
# [START howto_hitl_operator]
|
|
88
|
+
wait_for_option = HITLOperator(
|
|
89
|
+
task_id="wait_for_option",
|
|
90
|
+
subject="Please choose one option to proceed: ",
|
|
91
|
+
options=["option 1", "option 2", "option 3"],
|
|
92
|
+
notifiers=[hitl_request_callback],
|
|
93
|
+
on_success_callback=hitl_success_callback,
|
|
94
|
+
on_failure_callback=hitl_failure_callback,
|
|
95
|
+
)
|
|
96
|
+
# [END howto_hitl_operator]
|
|
97
|
+
|
|
98
|
+
# [START howto_hitl_operator_muliple]
|
|
99
|
+
wait_for_multiple_options = HITLOperator(
|
|
100
|
+
task_id="wait_for_multiple_options",
|
|
101
|
+
subject="Please choose option to proceed: ",
|
|
102
|
+
options=["option 4", "option 5", "option 6"],
|
|
103
|
+
multiple=True,
|
|
104
|
+
notifiers=[hitl_request_callback],
|
|
105
|
+
on_success_callback=hitl_success_callback,
|
|
106
|
+
on_failure_callback=hitl_failure_callback,
|
|
107
|
+
)
|
|
108
|
+
# [END howto_hitl_operator_muliple]
|
|
109
|
+
|
|
110
|
+
# [START howto_hitl_operator_timeout]
|
|
111
|
+
wait_for_default_option = HITLOperator(
|
|
112
|
+
task_id="wait_for_default_option",
|
|
113
|
+
subject="Please choose option to proceed: ",
|
|
114
|
+
options=["option 7", "option 8", "option 9"],
|
|
115
|
+
defaults=["option 7"],
|
|
116
|
+
execution_timeout=datetime.timedelta(seconds=1),
|
|
117
|
+
notifiers=[hitl_request_callback],
|
|
118
|
+
on_success_callback=hitl_success_callback,
|
|
119
|
+
on_failure_callback=hitl_failure_callback,
|
|
120
|
+
)
|
|
121
|
+
# [END howto_hitl_operator_timeout]
|
|
122
|
+
|
|
123
|
+
# [START howto_hitl_approval_operator]
|
|
124
|
+
valid_input_and_options = ApprovalOperator(
|
|
125
|
+
task_id="valid_input_and_options",
|
|
126
|
+
subject="Are the following input and options valid?",
|
|
127
|
+
body="""
|
|
128
|
+
Input: {{ ti.xcom_pull(task_ids='wait_for_input')["params_input"]["information"] }}
|
|
129
|
+
Option: {{ ti.xcom_pull(task_ids='wait_for_option')["chosen_options"] }}
|
|
130
|
+
Multiple Options: {{ ti.xcom_pull(task_ids='wait_for_option')["chosen_options"] }}
|
|
131
|
+
Timeout Option: {{ ti.xcom_pull(task_ids='wait_for_option')["chosen_options"] }}
|
|
132
|
+
""",
|
|
133
|
+
defaults="Reject",
|
|
134
|
+
execution_timeout=datetime.timedelta(minutes=1),
|
|
135
|
+
notifiers=[hitl_request_callback],
|
|
136
|
+
on_success_callback=hitl_success_callback,
|
|
137
|
+
on_failure_callback=hitl_failure_callback,
|
|
138
|
+
)
|
|
139
|
+
# [END howto_hitl_approval_operator]
|
|
140
|
+
|
|
141
|
+
# [START howto_hitl_branch_operator]
|
|
142
|
+
choose_a_branch_to_run = HITLBranchOperator(
|
|
143
|
+
task_id="choose_a_branch_to_run",
|
|
144
|
+
subject="You're now allowed to proceeded. Please choose one task to run: ",
|
|
145
|
+
options=["task_1", "task_2", "task_3"],
|
|
146
|
+
notifiers=[hitl_request_callback],
|
|
147
|
+
on_success_callback=hitl_success_callback,
|
|
148
|
+
on_failure_callback=hitl_failure_callback,
|
|
149
|
+
)
|
|
150
|
+
# [END howto_hitl_branch_operator]
|
|
151
|
+
|
|
152
|
+
# [START howto_hitl_workflow]
|
|
153
|
+
@task
|
|
154
|
+
def task_1(): ...
|
|
155
|
+
|
|
156
|
+
@task
|
|
157
|
+
def task_2(): ...
|
|
158
|
+
|
|
159
|
+
@task
|
|
160
|
+
def task_3(): ...
|
|
161
|
+
|
|
162
|
+
(
|
|
163
|
+
[wait_for_input, wait_for_option, wait_for_default_option, wait_for_multiple_options]
|
|
164
|
+
>> valid_input_and_options
|
|
165
|
+
>> choose_a_branch_to_run
|
|
166
|
+
>> [task_1(), task_2(), task_3()]
|
|
167
|
+
)
|
|
168
|
+
# [END howto_hitl_workflow]
|
|
169
|
+
|
|
170
|
+
# [END hitl_tutorial]
|
|
@@ -20,21 +20,23 @@ import logging
|
|
|
20
20
|
|
|
21
21
|
from airflow.exceptions import AirflowOptionalProviderFeatureException
|
|
22
22
|
from airflow.providers.standard.version_compat import AIRFLOW_V_3_1_PLUS
|
|
23
|
+
from airflow.sdk.bases.notifier import BaseNotifier
|
|
23
24
|
|
|
24
25
|
if not AIRFLOW_V_3_1_PLUS:
|
|
25
26
|
raise AirflowOptionalProviderFeatureException("Human in the loop functionality needs Airflow 3.1+.")
|
|
26
27
|
|
|
27
28
|
|
|
28
|
-
from collections.abc import Collection, Mapping
|
|
29
|
-
from datetime import datetime, timezone
|
|
29
|
+
from collections.abc import Collection, Mapping, Sequence
|
|
30
30
|
from typing import TYPE_CHECKING, Any
|
|
31
31
|
|
|
32
32
|
from airflow.providers.standard.exceptions import HITLTimeoutError, HITLTriggerEventError
|
|
33
|
+
from airflow.providers.standard.operators.branch import BranchMixIn
|
|
33
34
|
from airflow.providers.standard.triggers.hitl import HITLTrigger, HITLTriggerEventSuccessPayload
|
|
34
35
|
from airflow.providers.standard.utils.skipmixin import SkipMixin
|
|
35
36
|
from airflow.providers.standard.version_compat import BaseOperator
|
|
36
37
|
from airflow.sdk.definitions.param import ParamsDict
|
|
37
38
|
from airflow.sdk.execution_time.hitl import upsert_hitl_detail
|
|
39
|
+
from airflow.sdk.timezone import utcnow
|
|
38
40
|
|
|
39
41
|
if TYPE_CHECKING:
|
|
40
42
|
from airflow.sdk.definitions.context import Context
|
|
@@ -65,6 +67,7 @@ class HITLOperator(BaseOperator):
|
|
|
65
67
|
defaults: str | list[str] | None = None,
|
|
66
68
|
multiple: bool = False,
|
|
67
69
|
params: ParamsDict | dict[str, Any] | None = None,
|
|
70
|
+
notifiers: Sequence[BaseNotifier] | BaseNotifier | None = None,
|
|
68
71
|
**kwargs,
|
|
69
72
|
) -> None:
|
|
70
73
|
super().__init__(**kwargs)
|
|
@@ -77,6 +80,9 @@ class HITLOperator(BaseOperator):
|
|
|
77
80
|
self.multiple = multiple
|
|
78
81
|
|
|
79
82
|
self.params: ParamsDict = params if isinstance(params, ParamsDict) else ParamsDict(params or {})
|
|
83
|
+
self.notifiers: Sequence[BaseNotifier] = (
|
|
84
|
+
[notifiers] if isinstance(notifiers, BaseNotifier) else notifiers or []
|
|
85
|
+
)
|
|
80
86
|
|
|
81
87
|
self.validate_defaults()
|
|
82
88
|
|
|
@@ -107,11 +113,16 @@ class HITLOperator(BaseOperator):
|
|
|
107
113
|
multiple=self.multiple,
|
|
108
114
|
params=self.serialized_params,
|
|
109
115
|
)
|
|
116
|
+
|
|
110
117
|
if self.execution_timeout:
|
|
111
|
-
timeout_datetime =
|
|
118
|
+
timeout_datetime = utcnow() + self.execution_timeout
|
|
112
119
|
else:
|
|
113
120
|
timeout_datetime = None
|
|
121
|
+
|
|
114
122
|
self.log.info("Waiting for response")
|
|
123
|
+
for notifier in self.notifiers:
|
|
124
|
+
notifier(context)
|
|
125
|
+
|
|
115
126
|
# Defer the Human-in-the-loop response checking process to HITLTrigger
|
|
116
127
|
self.defer(
|
|
117
128
|
trigger=HITLTrigger(
|
|
@@ -170,6 +181,9 @@ class ApprovalOperator(HITLOperator, SkipMixin):
|
|
|
170
181
|
|
|
171
182
|
FIXED_ARGS = ["options", "multiple"]
|
|
172
183
|
|
|
184
|
+
APPROVE = "Approve"
|
|
185
|
+
REJECT = "Reject"
|
|
186
|
+
|
|
173
187
|
def __init__(self, ignore_downstream_trigger_rules: bool = False, **kwargs) -> None:
|
|
174
188
|
for arg in self.FIXED_ARGS:
|
|
175
189
|
if arg in kwargs:
|
|
@@ -177,13 +191,17 @@ class ApprovalOperator(HITLOperator, SkipMixin):
|
|
|
177
191
|
|
|
178
192
|
self.ignore_downstream_trigger_rules = ignore_downstream_trigger_rules
|
|
179
193
|
|
|
180
|
-
super().__init__(
|
|
194
|
+
super().__init__(
|
|
195
|
+
options=[self.APPROVE, self.REJECT],
|
|
196
|
+
multiple=False,
|
|
197
|
+
**kwargs,
|
|
198
|
+
)
|
|
181
199
|
|
|
182
200
|
def execute_complete(self, context: Context, event: dict[str, Any]) -> Any:
|
|
183
201
|
ret = super().execute_complete(context=context, event=event)
|
|
184
202
|
|
|
185
203
|
chosen_option = ret["chosen_options"][0]
|
|
186
|
-
if chosen_option ==
|
|
204
|
+
if chosen_option == self.APPROVE:
|
|
187
205
|
self.log.info("Approved. Proceeding with downstream tasks...")
|
|
188
206
|
return ret
|
|
189
207
|
|
|
@@ -211,24 +229,27 @@ class ApprovalOperator(HITLOperator, SkipMixin):
|
|
|
211
229
|
return ret
|
|
212
230
|
|
|
213
231
|
|
|
214
|
-
class HITLBranchOperator(HITLOperator):
|
|
232
|
+
class HITLBranchOperator(HITLOperator, BranchMixIn):
|
|
215
233
|
"""BranchOperator based on Human-in-the-loop Response."""
|
|
216
234
|
|
|
217
|
-
|
|
218
|
-
super().__init__(**kwargs)
|
|
235
|
+
inherits_from_skipmixin = True
|
|
219
236
|
|
|
220
|
-
def execute_complete(self, context: Context, event: dict[str, Any]) ->
|
|
221
|
-
|
|
237
|
+
def execute_complete(self, context: Context, event: dict[str, Any]) -> Any:
|
|
238
|
+
ret = super().execute_complete(context=context, event=event)
|
|
239
|
+
chosen_options = ret["chosen_options"]
|
|
240
|
+
return self.do_branch(context=context, branches_to_execute=chosen_options)
|
|
222
241
|
|
|
223
242
|
|
|
224
243
|
class HITLEntryOperator(HITLOperator):
|
|
225
244
|
"""Human-in-the-loop Operator that is used to accept user input through TriggerForm."""
|
|
226
245
|
|
|
246
|
+
OK = "OK"
|
|
247
|
+
|
|
227
248
|
def __init__(self, **kwargs) -> None:
|
|
228
249
|
if "options" not in kwargs:
|
|
229
|
-
kwargs["options"] = [
|
|
250
|
+
kwargs["options"] = [self.OK]
|
|
230
251
|
|
|
231
252
|
if "defaults" not in kwargs:
|
|
232
|
-
kwargs["defaults"] = [
|
|
253
|
+
kwargs["defaults"] = [self.OK]
|
|
233
254
|
|
|
234
255
|
super().__init__(**kwargs)
|
|
@@ -42,7 +42,10 @@ except ImportError:
|
|
|
42
42
|
timeout: datetime.timedelta | None = None
|
|
43
43
|
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
try:
|
|
46
|
+
from airflow.sdk import timezone
|
|
47
|
+
except ImportError:
|
|
48
|
+
from airflow.utils import timezone # type: ignore[attr-defined,no-redef]
|
|
46
49
|
|
|
47
50
|
if TYPE_CHECKING:
|
|
48
51
|
try:
|
|
@@ -116,9 +119,11 @@ class TimeSensor(BaseSensorOperator):
|
|
|
116
119
|
),
|
|
117
120
|
method_name="execute_complete",
|
|
118
121
|
)
|
|
122
|
+
else:
|
|
123
|
+
super().execute(context)
|
|
119
124
|
|
|
120
|
-
def execute_complete(self, context: Context) -> None:
|
|
121
|
-
return
|
|
125
|
+
def execute_complete(self, context: Context, event: Any = None) -> None:
|
|
126
|
+
return None
|
|
122
127
|
|
|
123
128
|
def poke(self, context: Context) -> bool:
|
|
124
129
|
self.log.info("Checking if the time (%s) has come", self.target_datetime)
|
|
@@ -34,8 +34,8 @@ from airflow.sdk.execution_time.hitl import (
|
|
|
34
34
|
get_hitl_detail_content_detail,
|
|
35
35
|
update_htil_detail_response,
|
|
36
36
|
)
|
|
37
|
+
from airflow.sdk.timezone import utcnow
|
|
37
38
|
from airflow.triggers.base import BaseTrigger, TriggerEvent
|
|
38
|
-
from airflow.utils import timezone
|
|
39
39
|
|
|
40
40
|
|
|
41
41
|
class HITLTriggerEventSuccessPayload(TypedDict, total=False):
|
|
@@ -43,6 +43,7 @@ class HITLTriggerEventSuccessPayload(TypedDict, total=False):
|
|
|
43
43
|
|
|
44
44
|
chosen_options: list[str]
|
|
45
45
|
params_input: dict[str, Any]
|
|
46
|
+
timedout: bool
|
|
46
47
|
|
|
47
48
|
|
|
48
49
|
class HITLTriggerEventFailurePayload(TypedDict):
|
|
@@ -96,7 +97,7 @@ class HITLTrigger(BaseTrigger):
|
|
|
96
97
|
async def run(self) -> AsyncIterator[TriggerEvent]:
|
|
97
98
|
"""Loop until the Human-in-the-loop response received or timeout reached."""
|
|
98
99
|
while True:
|
|
99
|
-
if self.timeout_datetime and self.timeout_datetime <
|
|
100
|
+
if self.timeout_datetime and self.timeout_datetime < utcnow():
|
|
100
101
|
if self.defaults is None:
|
|
101
102
|
yield TriggerEvent(
|
|
102
103
|
HITLTriggerEventFailurePayload(
|
|
@@ -111,21 +112,28 @@ class HITLTrigger(BaseTrigger):
|
|
|
111
112
|
chosen_options=self.defaults,
|
|
112
113
|
params_input=self.params,
|
|
113
114
|
)
|
|
115
|
+
self.log.info(
|
|
116
|
+
"[HITL] timeout reached before receiving response, fallback to default %s", self.defaults
|
|
117
|
+
)
|
|
114
118
|
yield TriggerEvent(
|
|
115
119
|
HITLTriggerEventSuccessPayload(
|
|
116
120
|
chosen_options=self.defaults,
|
|
117
121
|
params_input=self.params,
|
|
122
|
+
timedout=True,
|
|
118
123
|
)
|
|
119
124
|
)
|
|
120
125
|
return
|
|
121
126
|
|
|
122
127
|
resp = await sync_to_async(get_hitl_detail_content_detail)(ti_id=self.ti_id)
|
|
123
128
|
if resp.response_received and resp.chosen_options:
|
|
124
|
-
self.log.info(
|
|
129
|
+
self.log.info(
|
|
130
|
+
"[HITL] user=%s options=%s at %s", resp.user_id, resp.chosen_options, resp.response_at
|
|
131
|
+
)
|
|
125
132
|
yield TriggerEvent(
|
|
126
133
|
HITLTriggerEventSuccessPayload(
|
|
127
134
|
chosen_options=resp.chosen_options,
|
|
128
135
|
params_input=resp.params_input,
|
|
136
|
+
timedout=False,
|
|
129
137
|
)
|
|
130
138
|
)
|
|
131
139
|
return
|