# 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. [build-system] requires = [ "gitdb==4.0.12", "GitPython==3.1.46", "hatchling==1.29.0", "packaging==26.0", "pathspec==1.0.4", "pluggy==1.6.0", "smmap==5.0.3", "tomli==2.4.0; python_version < '3.11'", "trove-classifiers==2026.1.14.14", ] build-backend = "hatchling.build" [project] name = "apache-airflow-core" description = "Core packages for Apache Airflow, schedule and API server" 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 dependencies. # We proactively exclude the next major version to avoid dependency conflicts, then test it and # bump the upper binding once ready. Providers that don't support it yet are marked with # != constraint - until they support it - which also excludes resolving uv workspace dependencies. 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", "Framework :: Apache Airflow", "Intended Audience :: Developers", "Intended Audience :: System Administrators", "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", ] # Version is defined in src/airflow/__init__.py and it is automatically synchronized by prek hook version = "3.2.0" dependencies = [ "a2wsgi>=1.10.8", # aiosqlite 0.22.0 has a problem with hanging pytest sessions and we excluded it # See https://github.com/omnilib/aiosqlite/issues/369 # It seems that while our test issues are fixed in 0.22.1, sqlalchemy 2 itself # is not compatible with it and leaves thread hanging This is already fixed in main of sqlalchemy # But not released yet - and we will likely have to add >=2.0.46+ for sqlalchemy when released to # protect against it https://github.com/sqlalchemy/sqlalchemy/issues/13039 "aiosqlite>=0.20.0,<0.22.0", # Alembic is important to handle our migrations in predictable and performant way. It is developed # together with SQLAlchemy. Our experience with Alembic is that it very stable in minor version # The 1.13.0 of alembic marked some migration code as SQLAlchemy 2+ only so we limit it to 1.13.1 "alembic>=1.13.1, <2.0", "argcomplete>=1.10", "asgiref>=2.3.0; python_version < '3.14'", "asgiref>=3.11.1; python_version >= '3.14'", "attrs>=22.1.0, !=25.2.0", "cadwyn>=6.0.4", "colorlog>=6.8.2", "cron-descriptor>=1.2.24", "croniter>=2.0.2", # Cryptography could be upgraded to 46.0.5, but it does not have overlap with earlier versions # Of Airflow which were limited to <46.0.0 also earlier provider versions will not be compatible with newer # airflow if we do not have overlapping version. We could set minimum version to 46.0.0 when we drop # support for Airflow 3.1. "cryptography>=44.0.3", "deprecated>=1.2.13", "dill>=0.2.2", "fastapi[standard-no-fastapi-cloud-cli]>=0.129.0", "uvicorn>=0.37.0", # Starlette 1.0.0 breaks the API server. Needs more investigation # https://github.com/apache/airflow/issues/64116 "starlette>=0.45.0,<1", "httpx>=0.25.0", 'importlib_metadata>=6.5;python_version<"3.12"', 'importlib_metadata>=7.0;python_version>="3.12"', "itsdangerous>=2.0", "jinja2>=3.1.5", "jsonschema>=4.19.1", "lazy-object-proxy>=1.2.0", 'libcst >=1.8.2; python_version < "3.14"', 'libcst >=1.8.6; python_version >= "3.14"', "linkify-it-py>=2.0.0", "lockfile>=0.12.2", "methodtools>=0.4.7", "natsort>=8.4.0", "opentelemetry-api>=1.27.0", "opentelemetry-exporter-otlp>=1.27.0", # opentelemetry-proto is a transitive dependency of # opentelemetry-exporter-otlp and other OpenTelemetry packages. # opentelemetry-proto adds a very restrictive dependency on # protobuf, causing conflicts with other packages, so to help # the pip resolver we add it as a direct dependency with an upper # bound, which signals to the pip resolver it is a problematic # dependency and should be resolved as early as possible. # This may be removed when future versions of pip are able # to handle this dependency resolution automatically. "opentelemetry-proto<9999,>=1.27.0", "packaging>=25.0", "pathspec>=0.9.0", 'pendulum>=3.1.0', "pluggy>=1.5.0", "psutil>=5.8.0", "pydantic>=2.11.0", # Pygments 2.19.0 improperly renders .ini files with dictionaries as values # See https://github.com/pygments/pygments/issues/2834 "pygments>=2.0.1,!=2.19.0", "pyjwt>=2.11.0", "python-daemon>=3.0.0", "python-dateutil>=2.7.0", "python-slugify>=5.0", # Requests 3 if it will be released, will be heavily breaking. "requests>=2.32.0,<3", "rich-argparse>=1.0.0", "rich>=13.6.0", "setproctitle>=1.3.3", "sqlalchemy[asyncio]>=2.0.48", "svcs>=25.1.0", "tabulate>=0.9.0", "tenacity>=8.3.0", "termcolor>=3.0.0", "typing-extensions>=4.14.1", # https://github.com/apache/airflow/issues/56369 , rework universal-pathlib usage "universal-pathlib>=0.3.8", "uuid6>=2024.7.10", "apache-airflow-task-sdk<1.3.0,>=1.2.0", # pre-installed providers "apache-airflow-providers-common-compat>=1.7.4", "apache-airflow-providers-common-io>=1.6.3", "apache-airflow-providers-common-sql>=1.28.1", "apache-airflow-providers-smtp>=2.3.1", "apache-airflow-providers-standard>=1.9.0", # Start of shared logging dependencies "msgspec>=0.19.0", "pygtrie>=2.5.0", "structlog>=25.4.0", # End of shared logging dependencies # Start of shared configuration dependencies "pyyaml>=6.0.3", # End of shared configuration dependencies # Start of shared listeners dependencies "pluggy>=1.5.0", # End of shared listeners dependencies ] [project.optional-dependencies] "async" = [ "eventlet>=0.37.0", "gevent>=25.4.1", "greenlet>=3.1.0; python_version < '3.14'", "greenlet>=3.3.2; python_version >= '3.14'", "greenback>=1.2.1", ] "graphviz" = [ # The graphviz package creates friction when installing on MacOS as it needs graphviz system package to # be installed, and it's really only used for very obscure features of Airflow, so we can skip it on MacOS # Instead, if someone attempts to use it on MacOS, they will get explanatory error on how to install it "graphviz>=0.20; sys_platform != 'darwin'", ] "kerberos" = [ "pykerberos>=1.1.13", "requests-kerberos>=0.14.0", "thrift-sasl>=0.4.2", ] "memray" = [ "memray>=1.19.0", ] "gunicorn" = [ "gunicorn>=23.0.0,!=25.1.0", ] "otel" = [ "opentelemetry-exporter-prometheus>=0.47b0", ] "statsd" = [ "statsd>=3.3.0", ] "all" = [ "apache-airflow-core[graphviz,gunicorn,kerberos,otel,statsd]" ] [project.scripts] airflow = "airflow.__main__:main" [project.urls] "Bug Tracker" = "https://github.com/apache/airflow/issues" Documentation = "https://airflow.apache.org/docs/" Downloads = "https://archive.apache.org/dist/airflow/" Homepage = "https://airflow.apache.org/" "Release Notes" = "https://airflow.apache.org/docs/apache-airflow/stable/release_notes.html" "Slack Chat" = "https://s.apache.org/airflow-slack" "Source Code" = "https://github.com/apache/airflow" LinkedIn = "https://www.linkedin.com/company/apache-airflow/" Mastodon = "https://fosstodon.org/@airflow" Bluesky = "https://bsky.app/profile/apache-airflow.bsky.social" YouTube = "https://www.youtube.com/channel/UCSXwxpWZQ7XZ1WL3wqevChA/" [tool.hatch.version] path = "src/airflow/__init__.py" [tool.hatch.build.targets.sdist] include = [ "src/airflow", "LICENSE", "NOTICE" ] exclude = [ "src/airflow/ui/node_modules/", "src/airflow/api_fastapi/auth/managers/simple/ui/node_modules", "src/airflow/ui/openapi.merged.json", "src/airflow/_shared/AGENTS.md", "src/airflow/_shared/README.md", ] [tool.hatch.build.targets.sdist.force-include] "../shared/configuration/src/airflow_shared/configuration" = "src/airflow/_shared/configuration" "../shared/dagnode/src/airflow_shared/dagnode" = "src/airflow/_shared/dagnode" "../shared/logging/src/airflow_shared/logging" = "src/airflow/_shared/logging" "../shared/module_loading/src/airflow_shared/module_loading" = "src/airflow/_shared/module_loading" "../shared/observability/src/airflow_shared/observability" = "src/airflow/_shared/observability" "../shared/secrets_backend/src/airflow_shared/secrets_backend" = "src/airflow/_shared/secrets_backend" "../shared/secrets_masker/src/airflow_shared/secrets_masker" = "src/airflow/_shared/secrets_masker" "../shared/serialization/src/airflow_shared/serialization" = "src/airflow/_shared/serialization" "../shared/timezones/src/airflow_shared/timezones" = "src/airflow/_shared/timezones" "../shared/listeners/src/airflow_shared/listeners" = "src/airflow/_shared/listeners" "../shared/plugins_manager/src/airflow_shared/plugins_manager" = "src/airflow/_shared/plugins_manager" "../shared/providers_discovery/src/airflow_shared/providers_discovery" = "src/airflow/_shared/providers_discovery" "../shared/template_rendering/src/airflow_shared/template_rendering" = "src/airflow/_shared/template_rendering" [tool.hatch.build.targets.custom] path = "./hatch_build.py" artifacts = [ "src/airflow/ui/dist/", "src/airflow/api_fastapi/auth/managers/simple/ui/dist/", "src/airflow/git_version", "generated/", ] [tool.hatch.build.targets.wheel] packages = ['src/airflow'] artifacts = [ "src/airflow/ui/dist/", "src/airflow/api_fastapi/auth/managers/simple/ui/dist/", "src/airflow/git_version" ] exclude = [ # Only dist/ (declared as artifacts) is needed "src/airflow/ui/**", "src/airflow/api_fastapi/auth/managers/simple/ui/**", "src/airflow/_shared/AGENTS.md", "src/airflow/_shared/README.md", ] [dependency-groups] dev = [ "apache-airflow-core[all]", "apache-airflow-ctl", "apache-airflow-devel-common", "apache-airflow-task-sdk", # TODO(potiuk): eventually we do not want any providers nor apache-airflow extras to be needed for # airflow-core tests "apache-airflow[pandas,polars]", "apache-airflow-providers-amazon", "apache-airflow-providers-celery", "apache-airflow-providers-cncf-kubernetes", "apache-airflow-providers-fab>=2.2.0", "apache-airflow-providers-git", "apache-airflow-providers-ftp", ] # To build docs: # # uv run --group docs build-docs # # To enable auto-refreshing build with server: # # uv run --group docs build-docs --autobuild # # To see more options: # # uv run --group docs build-docs --help # docs = [ "apache-airflow-devel-common[docs]" ] [tool.uv] required-version = ">=0.6.3" [tool.uv.sources] apache-airflow-core = {workspace = true} apache-airflow-devel-common = { workspace = true } [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-observability", "apache-airflow-shared-secrets-backend", "apache-airflow-shared-secrets-masker", "apache-airflow-shared-serialization", "apache-airflow-shared-timezones", "apache-airflow-shared-plugins-manager", "apache-airflow-shared-providers-discovery", ]