| # Licensed to the Apache Software Foundation (ASF) under one |
| # or more contributor license agreements. See the NOTICE file |
| # distributed with this work for additional information |
| # regarding copyright ownership. The ASF licenses this file |
| # to you under the Apache License, Version 2.0 (the |
| # "License"); you may not use this file except in compliance |
| # with the License. You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, |
| # software distributed under the License is distributed on an |
| # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| # KIND, either express or implied. See the License for the |
| # specific language governing permissions and limitations |
| # under the License. |
| |
| [project] |
| name = "apache-airflow-task-sdk" |
| dynamic = ["version"] |
| description = "Python Task SDK for Apache Airflow DAG Authors" |
| readme = { file = "README.md", content-type = "text/markdown" } |
| license = "Apache-2.0" |
| license-files = ["LICENSE", "NOTICE"] |
| # Supporting new Python releases typically takes 4-7 months due to all our provider dependencies. |
| # We proactively limit the version to allow time for all dependencies to update. |
| requires-python = ">=3.10,!=3.15" |
| |
| authors = [ |
| {name="Apache Software Foundation", email="dev@airflow.apache.org"}, |
| ] |
| maintainers = [ |
| {name="Apache Software Foundation", email="dev@airflow.apache.org"}, |
| ] |
| keywords = [ "airflow", "orchestration", "workflow", "dag", "pipelines", "automation", "data" ] |
| classifiers = [ |
| "Development Status :: 5 - Production/Stable", |
| "Environment :: Console", |
| "Environment :: Web Environment", |
| "Intended Audience :: Developers", |
| "Intended Audience :: System Administrators", |
| "Framework :: Apache Airflow", |
| "Programming Language :: Python :: 3.10", |
| "Programming Language :: Python :: 3.11", |
| "Programming Language :: Python :: 3.12", |
| "Programming Language :: Python :: 3.13", |
| "Programming Language :: Python :: 3.14", |
| "Topic :: System :: Monitoring", |
| ] |
| dependencies = [ |
| "apache-airflow-core<3.3.0,>=3.2.0", |
| "asgiref>=2.3.0; python_version < '3.14'", |
| "asgiref>=3.11.1; python_version >= '3.14'", |
| "attrs>=24.2.0, !=25.2.0", |
| "babel>=2.17.0", |
| "fsspec>=2023.10.0", |
| "httpx>=0.27.0", |
| "jinja2>=3.1.5", |
| "methodtools>=0.4.7", |
| "msgspec>=0.19.0", |
| "python-dateutil>=2.7.0", |
| "psutil>=6.1.0", |
| "structlog>=25.4.0", |
| "greenback>=1.2.1", |
| "tenacity>=8.3.0", |
| # Start of shared timezones dependencies |
| "pendulum>=3.1.0", |
| # End of shared timezones dependencies |
| # Start of shared secrets_masker dependencies |
| "colorlog>=6.8.2", |
| "pydantic>2.11.0", |
| # End of shared secrets_masker dependencies |
| # Start of shared logging dependencies |
| "pygtrie>=2.5.0", |
| # End of shared logging dependencies |
| # Start of shared configuration dependencies |
| "packaging>=25.0", |
| "typing-extensions>=4.14.1", |
| # End of shared configuration dependencies |
| # Start of shared listeners dependencies |
| "pluggy>=1.5.0", |
| # End of shared listeners dependencies |
| # Start of shared module-loading dependencies |
| 'importlib_metadata>=6.5;python_version<"3.12"', |
| "pathspec>=0.9.0", |
| # End of shared module-loading dependencies |
| # Start of shared providers-discovery dependencies |
| "jsonschema>=4.19.1", |
| # End of shared providers-discovery dependencies |
| ] |
| |
| [project.optional-dependencies] |
| "sentry" = [ |
| "sentry-sdk>=2.30.0", |
| ] |
| "otel" = [ |
| "opentelemetry-api>=1.27.0", |
| "opentelemetry-exporter-otlp>=1.27.0", |
| "opentelemetry-proto<9999,>=1.27.0", |
| ] |
| "statsd" = [ |
| "statsd>=3.3.0", |
| ] |
| "datadog" = [ |
| "datadog>=0.50.0", |
| ] |
| "all" = ["apache-airflow-task-sdk[sentry,otel,statsd,datadog]"] |
| |
| [project.urls] |
| "Bug Tracker" = "https://github.com/apache/airflow/issues" |
| Documentation = "https://airflow.apache.org/docs/" |
| Homepage = "https://airflow.apache.org/" |
| "Slack Chat" = "https://s.apache.org/airflow-slack" |
| "Source Code" = "https://github.com/apache/airflow" |
| Mastodon = "https://fosstodon.org/@airflow" |
| Bluesky = "https://bsky.app/profile/apache-airflow.bsky.social" |
| YouTube = "https://www.youtube.com/channel/UCSXwxpWZQ7XZ1WL3wqevChA/" |
| |
| |
| [build-system] |
| requires = [ |
| "hatchling==1.29.0", |
| "packaging==26.0", |
| "pathspec==1.0.4", |
| "pluggy==1.6.0", |
| "tomli==2.4.1; python_version < '3.11'", |
| "trove-classifiers==2026.1.14.14", |
| ] |
| build-backend = "hatchling.build" |
| |
| [tool.hatch.version] |
| path = "src/airflow/sdk/__init__.py" |
| |
| [tool.hatch.build.targets.sdist.force-include] |
| "../shared/configuration/src/airflow_shared/configuration" = "src/airflow/sdk/_shared/configuration" |
| "../shared/dagnode/src/airflow_shared/dagnode" = "src/airflow/sdk/_shared/dagnode" |
| "../shared/logging/src/airflow_shared/logging" = "src/airflow/sdk/_shared/logging" |
| "../shared/module_loading/src/airflow_shared/module_loading" = "src/airflow/sdk/_shared/module_loading" |
| "../shared/observability/src/airflow_shared/observability" = "src/airflow/sdk/_shared/observability" |
| "../shared/secrets_backend/src/airflow_shared/secrets_backend" = "src/airflow/sdk/_shared/secrets_backend" |
| "../shared/secrets_masker/src/airflow_shared/secrets_masker" = "src/airflow/sdk/_shared/secrets_masker" |
| "../shared/serialization/src/airflow_shared/serialization" = "src/airflow/sdk/_shared/serialization" |
| "../shared/timezones/src/airflow_shared/timezones" = "src/airflow/sdk/_shared/timezones" |
| "../shared/listeners/src/airflow_shared/listeners" = "src/airflow/sdk/_shared/listeners" |
| "../shared/plugins_manager/src/airflow_shared/plugins_manager" = "src/airflow/sdk/_shared/plugins_manager" |
| "../shared/providers_discovery/src/airflow_shared/providers_discovery" = "src/airflow/sdk/_shared/providers_discovery" |
| "../shared/template_rendering/src/airflow_shared/template_rendering" = "src/airflow/sdk/_shared/template_rendering" |
| |
| [tool.hatch.build.targets.wheel] |
| packages = ["src/airflow"] |
| # This file only exists to make pyright/VSCode happy, don't ship it |
| exclude = [ |
| "src/airflow/__init__.py", |
| "src/airflow/sdk/_shared/AGENTS.md", |
| "src/airflow/sdk/_shared/README.md", |
| ] |
| |
| [tool.hatch.build.targets.sdist] |
| exclude = [ |
| "src/airflow/__init__.py", |
| "src/airflow/sdk/_shared/AGENTS.md", |
| "src/airflow/sdk/_shared/README.md", |
| ] |
| |
| [tool.ruff] |
| extend = "../pyproject.toml" |
| src = ["src"] |
| namespace-packages = ["src/airflow"] |
| |
| [tool.ruff.lint.per-file-ignores] |
| |
| # Ignore Doc rules et al for anything outside of tests |
| "!src/*" = ["D", "TID253", "S101", "TRY002"] |
| |
| # Ignore the pytest rules outside the tests folder - https://github.com/astral-sh/ruff/issues/14205 |
| "!tests/*" = ["PT"] |
| |
| # Pycharm barfs if this "stub" file has future imports |
| "src/airflow/__init__.py" = ["I002"] |
| |
| "src/airflow/sdk/__init__.py" = ["TC004"] |
| |
| # msgspec needs types for annotations to be defined, even with future |
| # annotations, so disable the "type check only import" for these files |
| "src/airflow/sdk/api/datamodels/*.py" = ["TC001"] |
| |
| # Only the public API should _require_ docstrings on classes |
| "!src/airflow/sdk/definitions/*" = ["D101"] |
| |
| # Generated file, be less strict |
| "src/airflow/sdk/*/_generated.py" = ["D"] |
| |
| [tool.coverage.run] |
| branch = true |
| relative_files = true |
| source = ["src/airflow"] |
| include_namespace_packages = true |
| |
| [tool.coverage.report] |
| skip_empty = true |
| exclude_also = [ |
| "def __repr__", |
| "raise AssertionError", |
| "raise NotImplementedError", |
| "if __name__ == .__main__.:", |
| "@(abc\\.)?abstractmethod", |
| "@(typing(_extensions)?\\.)?overload", |
| "if (typing(_extensions)?\\.)?TYPE_CHECKING:", |
| ] |
| |
| [dependency-groups] |
| codegen = [ |
| "datamodel-code-generator[http]==0.33.0", |
| "openapi-spec-validator>=0.7.1", |
| "svcs>=25.1.0", |
| "rich>=13.6.0", |
| ] |
| dev = [ |
| "apache-airflow-providers-common-sql", |
| "apache-airflow-providers-standard", |
| "apache-airflow-devel-common", |
| "pandas>=2.1.2; python_version <\"3.13\"", |
| "pandas>=2.2.3; python_version >=\"3.13\" and python_version <\"3.14\"", |
| "pandas>=2.3.3; python_version >=\"3.14\"" |
| ] |
| docs = [ |
| "apache-airflow-devel-common[docs]", |
| ] |
| [tool.uv.sources] |
| # These names must match the names as defined in the pyproject.toml of the workspace items, |
| # *not* the workspace folder paths |
| apache-airflow = {workspace = true} |
| apache-airflow-devel-common = {workspace = true} |
| apache-airflow-providers-common-sql = {workspace = true} |
| apache-airflow-providers-standard = {workspace = true} |
| |
| # To use: |
| # |
| # uv run --active --group codegen --project apache-airflow-task-sdk --directory task-sdk -s dev/generate_task_sdk_models.py |
| [tool.datamodel-codegen] |
| capitalise-enum-members=true # `State.RUNNING` not `State.running` |
| disable-timestamp=true |
| enable-version-header=true |
| enum-field-as-literal='one' # When a single enum member, make it output a `Literal["..."]` |
| input-file-type='openapi' |
| output-model-type='pydantic_v2.BaseModel' |
| output-datetime-class='AwareDatetime' |
| target-python-version='3.10' |
| use-annotated=true |
| use-default=true |
| use-double-quotes=true |
| use-schema-description=true # Desc becomes class doc comment |
| use-standard-collections=true # list[] not List[] |
| use-subclass-enum=true # enum, not union of Literals |
| use-union-operator=true # annotations, not `Union[]` |
| custom-formatters = ['datamodel_code_formatter'] |
| |
| url = 'http://0.0.0.0:8080/execution/openapi.json' |
| output = 'src/airflow/sdk/api/datamodels/_generated.py' |
| |
| ## pytest settings ## |
| [tool.pytest] |
| addopts = [ |
| "--tb=short", |
| "-rasl", |
| "--verbosity=2", |
| # Disable `flaky` plugin for pytest. This plugin conflicts with `rerunfailures` because provide the same marker. |
| "-p", "no:flaky", |
| # Disable `nose` builtin plugin for pytest. This feature is deprecated in 7.2 and will be removed in pytest>=8 |
| "-p", "no:nose", |
| # Disable support of a legacy `LocalPath` in favor of stdlib `pathlib.Path`. |
| "-p", "no:legacypath", |
| # Disable warnings summary, because we use our warning summary. |
| "--disable-warnings", |
| "--asyncio-mode=strict", |
| ] |
| |
| norecursedirs = [ |
| ".eggs", |
| ] |
| log_level = "INFO" |
| filterwarnings = [ |
| "error::pytest.PytestCollectionWarning", |
| ] |
| markers = [ |
| "flaky: mark test as flaky and rerun on failure", |
| ] |
| python_files = [ |
| "test_*.py", |
| ] |
| testpaths = [ |
| "tests", |
| ] |
| asyncio_default_fixture_loop_scope = "function" |
| |
| pythonpath = ["tests"] |
| |
| # Keep temporary directories (created by `tmp_path`) for 2 recent runs only failed tests. |
| tmp_path_retention_count = "2" |
| tmp_path_retention_policy = "failed" |
| |
| [tool.airflow] |
| shared_distributions = [ |
| "apache-airflow-shared-configuration", |
| "apache-airflow-shared-dagnode", |
| "apache-airflow-shared-listeners", |
| "apache-airflow-shared-logging", |
| "apache-airflow-shared-module-loading", |
| "apache-airflow-shared-secrets-backend", |
| "apache-airflow-shared-secrets-masker", |
| "apache-airflow-shared-serialization", |
| "apache-airflow-shared-timezones", |
| "apache-airflow-shared-observability", |
| "apache-airflow-shared-plugins-manager", |
| "apache-airflow-shared-providers-discovery", |
| ] |