From 76db41cacf0acdbf0b80dea2efd0bbe3f3c8f289 Mon Sep 17 00:00:00 2001 From: Dev-iL <6509619+Dev-iL@users.noreply.github.com> Date: Sun, 15 Mar 2026 17:10:17 +0200 Subject: [PATCH] Remove module-level import from `airflow.configuration` Importing airflow.models.Connection pulled in airflow.configuration, and airflow.configuration initializes secrets backends at import time. That initialization itself does `from airflow.models import Connection`, so under Python 3.14 the lazy import path could re-enter `airflow.models.__getattr__ before connection.py` had finished defining the Connection class. The result was the ImportError: Module "airflow.models.connection" does not define a "Connection"; plus repeated SQLAlchemy warnings about redefining the model during partial imports. By deferring: `from airflow.configuration import conf, ensure_secrets_loaded` until the method actually needs them, importing the module no longer triggers that cycle. `Connection` gets fully defined first, and only later, when get_connection_from_secrets() runs, do we touch configuration and secrets loading. That keeps behavior the same at runtime, but removes the import-time recursion. --- airflow-core/src/airflow/models/connection.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/airflow-core/src/airflow/models/connection.py b/airflow-core/src/airflow/models/connection.py index 0e1505f4667dd..d58f2b3202dbd 100644 --- a/airflow-core/src/airflow/models/connection.py +++ b/airflow-core/src/airflow/models/connection.py @@ -32,7 +32,6 @@ from airflow._shared.module_loading import import_string from airflow._shared.secrets_masker import mask_secret -from airflow.configuration import conf, ensure_secrets_loaded from airflow.exceptions import AirflowException, AirflowNotFoundException from airflow.models.base import ID_LEN, Base from airflow.models.crypto import get_fernet @@ -528,6 +527,8 @@ def get_connection_from_secrets(cls, conn_id: str, team_name: str | None = None) raise AirflowNotFoundException(f"The conn_id `{conn_id}` isn't defined") from None raise + from airflow.configuration import conf, ensure_secrets_loaded + if team_name and not conf.getboolean("core", "multi_team"): raise ValueError( "Multi-team mode is not configured in the Airflow environment but the task trying to access the connection belongs to a team"