| # 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.11,!=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.11", | |
| "Programming Language :: Python :: 3.12", | |
| "Programming Language :: Python :: 3.13", | |
| "Programming Language :: Python :: 3.14", | |
| "Topic :: System :: Monitoring", | |
| ] | |
| dependencies = [ | |
| "apache-airflow-core<3.5.0,>=3.4.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", | |
| "cadwyn>=6.1.1", | |
| "fsspec>=2023.10.0", | |
| "greenback>=1.2.1", | |
| "httpx2>=2.0.0", | |
| "jinja2>=3.1.5", | |
| "methodtools>=0.4.7", | |
| "msgspec>=0.19.0", | |
| "psutil>=6.1.0", | |
| "python-dateutil>=2.7.0", | |
| "pyyaml>=6.0.3", | |
| "structlog>=26.1.0", | |
| "tenacity>=8.3.0", | |
| "truststore>=0.10.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 | |
| # Start of shared observability dependencies | |
| "opentelemetry-api>=1.27.0", | |
| # End of shared observability dependencies | |
| "isoduration>=20.11.0" | |
| ] | |
| [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.32.4", | |
| "packaging==26.3", | |
| "pathspec==1.1.1", | |
| "pluggy==1.6.0", | |
| "tomlkit==0.15.1", | |
| "trove-classifiers==2026.9.21.13", | |
| ] | |
| 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/state/src/airflow_shared/state" = "src/airflow/sdk/_shared/state" | |
| "../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.ruff.lint.flake8-tidy-imports.extend-banned-api] | |
| "httpx".msg = "Use httpx2; httpx objects do not interoperate with the httpx2-based Task SDK client. See https://github.com/apache/airflow/issues/70522" | |
| [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.71.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]", | |
| ] | |
| mypy = [ | |
| "apache-airflow-devel-common[mypy]", | |
| ] | |
| [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} | |
| apache-airflow-shared-state = {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.11' | |
| 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[]` | |
| use-specialized-enum=false # (str, Enum), not StrEnum: str() and format() keep returning `Class.MEMBER` | |
| 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-state", | |
| "apache-airflow-shared-timezones", | |
| "apache-airflow-shared-observability", | |
| "apache-airflow-shared-plugins-manager", | |
| "apache-airflow-shared-providers-discovery", | |
| ] |