# 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.50",
    "hatchling==1.30.1",
    "packaging==26.2",
    "pathspec==1.1.1",
    "pluggy==1.6.0",
    "smmap==5.0.3",
    "tomli==2.4.1; python_version < '3.11'",
    "trove-classifiers==2026.6.1.19",
]
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.3.0"

dependencies = [
    "a2wsgi>=1.10.8",
    "cachetools>=6.0.0",
    # 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.1.1",
    "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",
    # Cap below 0.137.0: FastAPI 0.137 switched to lazy router inclusion, which breaks cadwyn's
    # versioned router generation (RouterGenerationError) and fails api-server / dag-processor
    # startup. Relax once cadwyn supports FastAPI 0.137. See
    # https://github.com/apache/airflow/issues/68562
    "fastapi[standard-no-fastapi-cloud-cli]>=0.129.0,<0.137.0",
    "uvicorn>=0.37.0",
    "starlette>=1.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",
    "universal-pathlib>=0.3.8",
    "uuid6>=2024.7.10",
    "apache-airflow-task-sdk==1.3.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
    "isoduration>=20.11.0",
]


[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/state/src/airflow_shared/state" = "src/airflow/_shared/state"
"../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]"
]
mypy = [
    "apache-airflow-devel-common[mypy]",
]



[tool.uv]
required-version = ">=0.11.8"

[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-state",
    "apache-airflow-shared-timezones",
    "apache-airflow-shared-plugins-manager",
    "apache-airflow-shared-providers-discovery",
]
