123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657 |
- # 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.
- from __future__ import annotations
- from functools import wraps
- from typing import Callable, TypeVar
- from airflow.typing_compat import ParamSpec
- PS = ParamSpec("PS")
- RT = TypeVar("RT")
- def providers_configuration_loaded(func: Callable[PS, RT]) -> Callable[PS, RT]:
- """
- Make sure that providers configuration is loaded before actually calling the decorated function.
- ProvidersManager initialization of configuration is relatively inexpensive - it walks through
- all providers's entrypoints, retrieve the provider_info and loads config yaml parts of the get_info.
- Unlike initialization of hooks and operators it does not import any of the provider's code, so it can
- be run quickly by all commands that need to access providers configuration. We cannot even import
- ProvidersManager while importing any of the commands, so we need to locally import it here.
- We cannot initialize the configuration in settings/conf because of the way how conf/settings are used
- internally - they are loaded while importing airflow, and we need to access airflow version conf in the
- ProvidesManager initialization, so instead we opt for decorating all the methods that need it with this
- decorator.
- The decorator should be placed below @suppress_logs_and_warning but above @provide_session in order to
- avoid spoiling the output of formatted options with some warnings ar infos, and to be prepared that
- session creation might need some configuration defaults from the providers configuration.
- :param func: function to makes sure that providers configuration is loaded before actually calling
- """
- @wraps(func)
- def wrapped_function(*args, **kwargs) -> RT:
- from airflow.providers_manager import ProvidersManager
- ProvidersManager().initialize_providers_configuration()
- return func(*args, **kwargs)
- return wrapped_function
|