Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
1d8dbd5
[v3-1-test] Limit urllib3 to <2.6.0 during latest boto tests (#59130)…
github-actions[bot] Dec 6, 2025
16822eb
[v3-1-test] Fix inconsistent Dag hashes when template fields contain …
github-actions[bot] Dec 7, 2025
9aabbe5
Revert "Update refresh token flow (#55506) (#58649)"
ephraimbuddy Dec 8, 2025
76b9aa6
Revert "Find only relevant up/downstream tis when clearing (#57758) (…
ephraimbuddy Dec 8, 2025
7f218c5
[v3-1-test] Update release candidate commands (#59186) (#59187)
github-actions[bot] Dec 8, 2025
b5ccfb2
[v3-1-test] Also limit urllib3 to < 2.6.0 in k8s tests - for use in v…
potiuk Dec 7, 2025
e88d21f
[v3-1-test] Fix task instance and runs tooltips in Grid view (#58359)…
github-actions[bot] Dec 3, 2025
aee50f5
[v3-1-test] Update the documentation for the LocalExecutor (#58990) (…
github-actions[bot] Dec 4, 2025
61d9ab4
[v3-1-test] Add prek check before compiling assets in start-airflow (…
github-actions[bot] Dec 4, 2025
216fc27
[v3-1-test] provide a clear naming and description for the attribute …
github-actions[bot] Dec 4, 2025
2a9d5ce
[v3-1-test] Fix go back button from fab iframe (#58997) (#59007)
github-actions[bot] Dec 4, 2025
3c66ee2
[v3-1-test] Change task log source display to hidden by default (#587…
github-actions[bot] Dec 4, 2025
f142565
[v3-1-test] Move HTTPAuthorizationCredentials import from TYPE_CHECKI…
github-actions[bot] Dec 4, 2025
d9136f5
Backport (#59052)
pierrejeambrun Dec 4, 2025
a97346a
[v3-1-test] Uncomment Python version pin in `check-lazy-logging` (#59…
github-actions[bot] Dec 4, 2025
d966b81
[v3-1-test] Bump ruff to 0.14.8, uv to 0.9.15 (#59058) (#59079)
amoghrajesh Dec 5, 2025
5598f4a
CI: Upgrade important CI environment (#59145)
potiuk Dec 6, 2025
42683e8
[v3-1-test] Breeze exit on incompatible arguments (#59148) (#59157)
jscheffl Dec 7, 2025
36e76d3
[v3-1-test] Fix breeze check-release-files Command for Core+Task SDK …
github-actions[bot] Dec 7, 2025
61d1ca0
[v3-1-test] Fix airflow/task-sdk relase PMC checks (#59164) (#59165)
potiuk Dec 7, 2025
ba8527f
[v3-1-test] Fix mypy error on version check in dev (#59171) (#59172)
github-actions[bot] Dec 7, 2025
b326728
[v3-1-test] fix: Rendered Templates not showing dictionary items in A…
potiuk Dec 7, 2025
8db6403
[v3-1-test] fix flaky TestEmrCreateJobFlowOperator (#59128) (#59137)
jason810496 Dec 7, 2025
a1afa99
[v3-1-test] Align the term Dag in all translations (#59155)
jscheffl Dec 7, 2025
aafbaf2
[v3-1-test] Drop Airflow 2 Support in Edge Provider (#59143) (#59179)
jscheffl Dec 7, 2025
fc2bfe2
[v3-1-test] Fix DagRun.queued_at not updating when clearing (#59066) …
potiuk Dec 7, 2025
9d4458f
Translation gaps in v3-1-test TR (#59169)
bugraoz93 Dec 7, 2025
77c55e4
[v3-1-test] Prevent dag processor crash on encountering excel files i…
github-actions[bot] Dec 7, 2025
eda4e22
[v3-1-test] Add toggle functionality to Dags state filters (#59089)
choo121600 Dec 8, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/actions/breeze/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ inputs:
default: "3.10"
uv-version:
description: 'uv version to use'
default: "0.9.14" # Keep this comment to allow automatic replacement of uv version
default: "0.9.16" # Keep this comment to allow automatic replacement of uv version
outputs:
host-python-version:
description: Python version used in host
Expand Down
2 changes: 1 addition & 1 deletion .github/actions/install-prek/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ inputs:
default: "3.10"
uv-version:
description: 'uv version to use'
default: "0.9.14" # Keep this comment to allow automatic replacement of uv version
default: "0.9.16" # Keep this comment to allow automatic replacement of uv version
prek-version:
description: 'prek version to use'
default: "0.2.19" # Keep this comment to allow automatic replacement of prek version
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/airflow-distributions-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ jobs:
USE_LOCAL_HATCH: "${{ inputs.use-local-venv }}"
run: |
uv tool uninstall hatch || true
uv tool install hatch==1.16.1
uv tool install hatch==1.16.2
breeze release-management "${DISTRIBUTION_TYPE}" --distribution-format wheel
if: ${{ matrix.python-version == inputs.default-python-version }}
- name: "Verify wheel packages with twine"
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/basic-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ on: # yamllint disable-line rule:truthy
type: string
uv-version:
description: 'uv version to use'
default: "0.9.14" # Keep this comment to allow automatic replacement of uv version
default: "0.9.16" # Keep this comment to allow automatic replacement of uv version
type: string
platform:
description: 'Platform for the build - linux/amd64 or linux/arm64'
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release_dockerhub_image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ jobs:
AIRFLOW_VERSION: ${{ github.event.inputs.airflowVersion }}
AMD_ONLY: ${{ github.event.inputs.amdOnly }}
LIMIT_PYTHON_VERSIONS: ${{ github.event.inputs.limitPythonVersions }}
UV_VERSION: "0.9.14" # Keep this comment to allow automatic replacement of uv version
UV_VERSION: "0.9.16" # Keep this comment to allow automatic replacement of uv version
if: contains(fromJSON('[
"ashb",
"bugraoz93",
Expand Down
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ repos:
- "2"
- repo: https://github.com/Lucas-C/pre-commit-hooks
# replace hash with version once PR #103 merged comes in a release
rev: abdd8b62891099da34162217ecb3872d22184a51
rev: f5cfd5fdaf0211dfd1027d9d8442b764a232c7ad
hooks:
- id: insert-license
name: Add license for all SQL files
Expand Down Expand Up @@ -350,7 +350,7 @@ repos:
types_or: [python, pyi]
args: [--fix]
require_serial: true
additional_dependencies: ['ruff==0.14.7']
additional_dependencies: ['ruff==0.14.8']
exclude: ^airflow-core/tests/unit/dags/test_imports\.py$|^performance/tests/test_.*\.py$
- id: ruff-format
name: Run 'ruff format'
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ ARG AIRFLOW_PYTHON_VERSION="3.12.12"
# Also use `force pip` label on your PR to swap all places we use `uv` to `pip`
ARG AIRFLOW_PIP_VERSION=25.3
# ARG AIRFLOW_PIP_VERSION="git+https://github.com/pypa/pip.git@main"
ARG AIRFLOW_UV_VERSION=0.9.14
ARG AIRFLOW_UV_VERSION=0.9.16
ARG AIRFLOW_USE_UV="false"
ARG UV_HTTP_TIMEOUT="300"
ARG AIRFLOW_IMAGE_REPOSITORY="https://github.com/apache/airflow"
Expand Down
8 changes: 6 additions & 2 deletions Dockerfile.ci
Original file line number Diff line number Diff line change
Expand Up @@ -1324,8 +1324,12 @@ function check_boto_upgrade() {
echo
# shellcheck disable=SC2086
${PACKAGING_TOOL_CMD} uninstall ${EXTRA_UNINSTALL_FLAGS} aiobotocore s3fs || true

# Urllib 2.6.0 breaks kubernetes client because kubernetes client uses deprecated in 2.0.0 and
# removed in 2.6.0 `getheaders()` call (instead of `headers` property.
# Tracked in https://github.com/kubernetes-client/python/issues/2477
# shellcheck disable=SC2086
${PACKAGING_TOOL_CMD} install ${EXTRA_INSTALL_FLAGS} --upgrade "boto3<1.38.3" "botocore<1.38.3"
${PACKAGING_TOOL_CMD} install ${EXTRA_INSTALL_FLAGS} --upgrade "boto3<1.38.3" "botocore<1.38.3" "urllib3<2.6.0"
}

function check_upgrade_sqlalchemy() {
Expand Down Expand Up @@ -1695,7 +1699,7 @@ COPY --from=scripts common.sh install_packaging_tools.sh install_additional_depe
# Also use `force pip` label on your PR to swap all places we use `uv` to `pip`
ARG AIRFLOW_PIP_VERSION=25.3
# ARG AIRFLOW_PIP_VERSION="git+https://github.com/pypa/pip.git@main"
ARG AIRFLOW_UV_VERSION=0.9.14
ARG AIRFLOW_UV_VERSION=0.9.16
ARG AIRFLOW_PREK_VERSION="0.2.19"

# UV_LINK_MODE=copy is needed since we are using cache mounted from the host
Expand Down
2 changes: 1 addition & 1 deletion airflow-core/docs/best-practices.rst
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ Installing and Using ruff

.. code-block:: bash

pip install "ruff>=0.14.7"
pip install "ruff>=0.14.8"

2. **Running ruff**: Execute ``ruff`` to check your Dags for potential issues:

Expand Down
23 changes: 21 additions & 2 deletions airflow-core/docs/core-concepts/executor/local.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,27 @@ This parameter must be greater than ``0``.
The :class:`~airflow.executors.local_executor.LocalExecutor` spawns the number of processes equal to the value of ``self.parallelism`` at
``start`` time, using a ``task_queue`` to coordinate the ingestion of tasks and the work distribution among the workers, which will take
a task as soon as they are ready. During the lifecycle of the LocalExecutor, the worker processes are running waiting for tasks, once the
LocalExecutor receives the call to shutdown the executor a poison token is sent to the workers to terminate them. Processes used in this
strategy are of class :class:`~airflow.executors.local_executor.QueuedLocalWorker`.
LocalExecutor receives the call to shutdown the executor a poison token is sent to the workers to terminate them.

The worker spawning behavior differs based on the multiprocessing start method:

- **Fork mode** (default on Linux): Workers are spawned all at once up to ``parallelism`` to prevent memory spikes
caused by Copy-on-Write (COW). See `Discussion <https://github.com/apache/airflow/discussions/58143>`_
for details.
- **Spawn mode** (default on macOS and Windows): Workers are spawned one at a time as needed to prevent
the overhead of spawning many processes simultaneously.

.. note::

The ``parallelism`` parameter can be configured via the ``[core] parallelism`` option in ``airflow.cfg``.
The default value is ``32``.

.. warning::

Since LocalExecutor workers are spawned as sub-processes of the scheduler, in containerized environments
this may appear as excessive memory consumption by the scheduler process. This can potentially trigger
container restarts due to OOM (Out of Memory). Consider adjusting the ``parallelism`` value based on
your container's resource limits.

.. note::

Expand Down
1 change: 1 addition & 0 deletions airflow-core/docs/howto/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,4 @@ configuring an Airflow environment.
dynamic-dag-generation
docker-compose/index
run-with-self-signed-certificate
performance
55 changes: 55 additions & 0 deletions airflow-core/docs/howto/performance.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
.. 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.

Performance tuning (API and UI)
===============================

This guide collects pragmatic tips that improve Airflow performance for API and UI workloads.

Custom metadata indexes
-----------------------

If you observe slowness in some API calls or specific UI views, you should inspect query plans and add indexes yourself
that match your workload. Listing endpoints and UI table views with specific ordering criteria are likely
to benefit from additional indexes if you have a large volume of metadata.

When to use
^^^^^^^^^^^

- Slow API list/detail endpoints caused by frequent scans or lookups on columns like ``start_date``, timestamps (e.g. ``dttm``), or status fields.
- UI pages that load large lists or perform heavy filtering on metadata tables.

Guidance
^^^^^^^^

- Inspect the query planner (e.g., ``EXPLAIN``/``EXPLAIN ANALYZE``) for slow endpoints and identify missing indexes.
- Prefer single or composite indexes that match your most common ordering logic, typically the ``order_by``
query parameter used in API calls. Composite indexes can cover multi criteria ordering.
- Your optimal indexes depend on how you use the API and UI; there is no one-size-fits-all set we can ship by default.

Upgrade considerations
^^^^^^^^^^^^^^^^^^^^^^

To avoid conflicts with Airflow database upgrades, delete your custom indexes before running an Airflow DB upgrade
and re-apply them after the upgrade succeeds.

Notes
^^^^^

- Review query plans (e.g. via ``EXPLAIN``) to choose effective column sets and ordering for your workload.
- Composite indexes should list columns in selectivity order appropriate to your most common predicates.
- Indexes incur write overhead; add only those that materially improve your read paths.
2 changes: 0 additions & 2 deletions airflow-core/src/airflow/api_fastapi/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
init_config,
init_error_handlers,
init_flask_plugins,
init_middlewares,
init_ui_plugins,
init_views,
)
Expand Down Expand Up @@ -100,7 +99,6 @@ def create_app(apps: str = "all") -> FastAPI:
init_ui_plugins(app)
init_views(app) # Core views need to be the last routes added - it has a catch all route
init_error_handlers(app)
init_middlewares(app)

init_config(app)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,15 +135,12 @@ def get_url_logout(self) -> str | None:
"""
return None

def refresh_user(self, *, user: T) -> T | None:
def get_url_refresh(self) -> str | None:
"""
Refresh the user if needed.
Return the URL to refresh the authentication token.

By default, does nothing. Some auth managers might need to refresh the user to, for instance,
refresh some tokens that are needed to communicate with a service/tool.

This method is called by every single request, it must be lightweight otherwise the overall API
server latency will increase.
This is used to refresh the authentication token when it expires.
The default implementation returns None, which means that the auth manager does not support refresh token.
"""
return None

Expand Down

This file was deleted.

This file was deleted.

7 changes: 1 addition & 6 deletions airflow-core/src/airflow/api_fastapi/common/parameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
from fastapi import Depends, HTTPException, Query, status
from pendulum.parsing.exceptions import ParserError
from pydantic import AfterValidator, BaseModel, NonNegativeInt
from sqlalchemy import Column, and_, case, func, not_, or_, select as sql_select
from sqlalchemy import Column, and_, func, not_, or_, select as sql_select
from sqlalchemy.inspection import inspect

from airflow._shared.timezones import timezone
Expand Down Expand Up @@ -248,11 +248,6 @@ def to_orm(self, select: Select) -> Select:
if column is None:
column = getattr(self.model, lstriped_orderby)

# MySQL does not support `nullslast`, and True/False ordering depends on the
# database implementation.
nullscheck = case((column.isnot(None), 0), else_=1)

columns.append(nullscheck)
if order_by_value.startswith("-"):
columns.append(column.desc())
else:
Expand Down
6 changes: 0 additions & 6 deletions airflow-core/src/airflow/api_fastapi/core_api/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,12 +181,6 @@ def init_error_handlers(app: FastAPI) -> None:
app.add_exception_handler(handler.exception_cls, handler.exception_handler)


def init_middlewares(app: FastAPI) -> None:
from airflow.api_fastapi.auth.middlewares.refresh_token import JWTRefreshMiddleware

app.add_middleware(JWTRefreshMiddleware)


def init_ui_plugins(app: FastAPI) -> None:
"""Initialize UI plugins."""
from airflow import plugins_manager
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8478,6 +8478,40 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/HTTPExceptionResponse'
/api/v2/auth/refresh:
get:
tags:
- Login
summary: Refresh
description: Refresh the authentication token.
operationId: refresh
parameters:
- name: next
in: query
required: false
schema:
anyOf:
- type: string
- type: 'null'
title: Next
responses:
'200':
description: Successful Response
content:
application/json:
schema: {}
'307':
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPExceptionResponse'
description: Temporary Redirect
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
components:
schemas:
AppBuilderMenuItemResponse:
Expand Down
Loading