@@ -190,12 +190,16 @@ async def _async_get_connection(conn_id: str) -> Connection:
190190
191191 from airflow .sdk .execution_time .supervisor import ensure_secrets_backend_loaded
192192
193- # Try secrets backends using async wrapper (which may include SupervisorCommsSecretsBackend
194- # in worker contexts or MetastoreBackend in API server contexts)
193+ # Try secrets backends
195194 backends = ensure_secrets_backend_loaded ()
196195 for secrets_backend in backends :
197196 try :
198- conn = await sync_to_async (secrets_backend .get_connection )(conn_id ) # type: ignore[assignment]
197+ # Use async method if available, otherwise wrap sync method
198+ if hasattr (secrets_backend , "aget_connection" ):
199+ conn = await secrets_backend .aget_connection (conn_id ) # type: ignore[assignment]
200+ else :
201+ conn = await sync_to_async (secrets_backend .get_connection )(conn_id ) # type: ignore[assignment]
202+
199203 if conn :
200204 SecretCache .save_connection_uri (conn_id , conn .get_uri ())
201205 _mask_connection_secrets (conn )
@@ -233,7 +237,8 @@ def _get_variable(key: str, deserialize_json: bool) -> Any:
233237 pass # Continue to check backends
234238
235239 backends = ensure_secrets_backend_loaded ()
236- # iterate over backends if not in cache (or expired)
240+
241+ # Iterate over backends if not in cache (or expired)
237242 for secrets_backend in backends :
238243 try :
239244 var_val = secrets_backend .get_variable (key = key )
@@ -253,31 +258,13 @@ def _get_variable(key: str, deserialize_json: bool) -> Any:
253258 type (secrets_backend ).__name__ ,
254259 )
255260
256- if backends :
257- log .debug (
258- "Variable not found in any of the configured Secrets Backends. Trying to retrieve from API server" ,
259- key = key ,
260- )
261-
262- # TODO: This should probably be moved to a separate module like `airflow.sdk.execution_time.comms`
263- # or `airflow.sdk.execution_time.variable`
264- # A reason to not move it to `airflow.sdk.execution_time.comms` is that it
265- # will make that module depend on Task SDK, which is not ideal because we intend to
266- # keep Task SDK as a separate package than execution time mods.
267- from airflow .sdk .execution_time .comms import ErrorResponse , GetVariable
268- from airflow .sdk .execution_time .task_runner import SUPERVISOR_COMMS
269-
270- msg = SUPERVISOR_COMMS .send (GetVariable (key = key ))
271-
272- if isinstance (msg , ErrorResponse ):
273- raise AirflowRuntimeError (msg )
261+ # If no backend found the variable, raise a not found error (mirrors _get_connection)
262+ from airflow .sdk .exceptions import AirflowRuntimeError , ErrorType
263+ from airflow .sdk .execution_time .comms import ErrorResponse
274264
275- if TYPE_CHECKING :
276- assert isinstance (msg , VariableResult )
277- variable = _convert_variable_result_to_variable (msg , deserialize_json )
278- # Save raw value to ensure cache consistency regardless of deserialize_json parameter
279- SecretCache .save_variable (key , msg .value )
280- return variable .value
265+ raise AirflowRuntimeError (
266+ ErrorResponse (error = ErrorType .VARIABLE_NOT_FOUND , detail = {"message" : f"Variable { key } not found" })
267+ )
281268
282269
283270def _set_variable (key : str , value : Any , description : str | None = None , serialize_json : bool = False ) -> None :
@@ -290,18 +277,21 @@ def _set_variable(key: str, value: Any, description: str | None = None, serializ
290277
291278 from airflow .sdk .execution_time .cache import SecretCache
292279 from airflow .sdk .execution_time .comms import PutVariable
280+ from airflow .sdk .execution_time .secrets .execution_api import ExecutionAPISecretsBackend
293281 from airflow .sdk .execution_time .supervisor import ensure_secrets_backend_loaded
294282 from airflow .sdk .execution_time .task_runner import SUPERVISOR_COMMS
295283
296284 # check for write conflicts on the worker
297285 for secrets_backend in ensure_secrets_backend_loaded ():
286+ if isinstance (secrets_backend , ExecutionAPISecretsBackend ):
287+ continue
298288 try :
299289 var_val = secrets_backend .get_variable (key = key )
300290 if var_val is not None :
301291 _backend_name = type (secrets_backend ).__name__
302292 log .warning (
303293 "The variable %s is defined in the %s secrets backend, which takes "
304- "precedence over reading from the database . The value in the database will be "
294+ "precedence over reading from the API Server . The value from the API Server will be "
305295 "updated, but to read it you have to delete the conflicting variable "
306296 "from %s" ,
307297 key ,
@@ -362,12 +352,16 @@ def __eq__(self, other):
362352 return True
363353
364354 def get (self , conn_id : str , default_conn : Any = None ) -> Any :
355+ from airflow .exceptions import AirflowNotFoundException
356+
365357 try :
366358 return _get_connection (conn_id )
367359 except AirflowRuntimeError as e :
368360 if e .error .error == ErrorType .CONNECTION_NOT_FOUND :
369361 return default_conn
370362 raise
363+ except AirflowNotFoundException :
364+ return default_conn
371365
372366
373367class VariableAccessor :
0 commit comments