providers_configuration_loader.py 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. # Licensed to the Apache Software Foundation (ASF) under one
  2. # or more contributor license agreements. See the NOTICE file
  3. # distributed with this work for additional information
  4. # regarding copyright ownership. The ASF licenses this file
  5. # to you under the Apache License, Version 2.0 (the
  6. # "License"); you may not use this file except in compliance
  7. # with the License. You may obtain a copy of the License at
  8. #
  9. # http://www.apache.org/licenses/LICENSE-2.0
  10. #
  11. # Unless required by applicable law or agreed to in writing,
  12. # software distributed under the License is distributed on an
  13. # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  14. # KIND, either express or implied. See the License for the
  15. # specific language governing permissions and limitations
  16. # under the License.
  17. from __future__ import annotations
  18. from functools import wraps
  19. from typing import Callable, TypeVar
  20. from airflow.typing_compat import ParamSpec
  21. PS = ParamSpec("PS")
  22. RT = TypeVar("RT")
  23. def providers_configuration_loaded(func: Callable[PS, RT]) -> Callable[PS, RT]:
  24. """
  25. Make sure that providers configuration is loaded before actually calling the decorated function.
  26. ProvidersManager initialization of configuration is relatively inexpensive - it walks through
  27. all providers's entrypoints, retrieve the provider_info and loads config yaml parts of the get_info.
  28. Unlike initialization of hooks and operators it does not import any of the provider's code, so it can
  29. be run quickly by all commands that need to access providers configuration. We cannot even import
  30. ProvidersManager while importing any of the commands, so we need to locally import it here.
  31. We cannot initialize the configuration in settings/conf because of the way how conf/settings are used
  32. internally - they are loaded while importing airflow, and we need to access airflow version conf in the
  33. ProvidesManager initialization, so instead we opt for decorating all the methods that need it with this
  34. decorator.
  35. The decorator should be placed below @suppress_logs_and_warning but above @provide_session in order to
  36. avoid spoiling the output of formatted options with some warnings ar infos, and to be prepared that
  37. session creation might need some configuration defaults from the providers configuration.
  38. :param func: function to makes sure that providers configuration is loaded before actually calling
  39. """
  40. @wraps(func)
  41. def wrapped_function(*args, **kwargs) -> RT:
  42. from airflow.providers_manager import ProvidersManager
  43. ProvidersManager().initialize_providers_configuration()
  44. return func(*args, **kwargs)
  45. return wrapped_function