[docs]classSettings(dynaconf.Dynaconf):""" Configuration settings for the Descartes Labs client. Based on the ``Dynaconf`` package. This settings class supports configuration from named "environments" in a ``settings.toml`` file as well as environment variables with names that are prefixed with ``DESCARTESLABS_`` (or the prefix specified in the ``envvar_prefix``). For the full capabilities of ``Dynaconf`` please consult https://www.dynaconf.com/. Note that normally ``Settings`` functions entirely automatically within the client. However, it is possible to perform custom initialization programmatically. In order to do this, the beginning of the client program must execute code like this: .. code-block:: from descarteslabs.config import Settings Settings.select_env(...) Before importing or otherwise accessing anything else within the :py:mod:`descarteslabs` package. """class_EnvDescriptor:# Retrieve the correct env string for `peek_settings()`def__get__(self,obj,objtype=None):ifobjisNone:ifobjtype._settingsisNone:returnNoneelse:returnobjtype._settings.env_for_dynaconfelse:returnobj.env_for_dynaconfenv=_EnvDescriptor()"""str : The current client configuration name or `None` of no environment was selected."""# The global settings instance, can only be set once via select_env or get_settings_settings=None_lock=Lock()
[docs]@classmethoddefselect_env(cls,env=None,settings_file=None,envvar_prefix="DESCARTESLABS"):""" Configure the Descartes Labs client. Parameters ---------- env : str, optional Name of the environment to configure. Must appear in ``descarteslabs/config/settings.toml`` If not supplied will be determined from the `DESCARTESLABS_ENV` environment variable (or use the prefix specified in the `envvar_prefix`_ENV), if set. Otherwise defaults to `aws-production`. settings_file : str, optional If supplied, will be consulted for additional configuration overrides. These are applied over those in the ``descarteslabs/config/settings.toml`` file, but are themselves overwritten by any environment variable settings matching the `envvar_prefix`. envvar_prefix : str, optional Prefix for environment variable names to consult for configuration overrides. Environment variables with a leading prefix of ``"<envvar_prefix>_"`` will override the settings in the resulting configuration after the settings file(s) have been consulted. Returns ------- Settings Returns a ``Settings`` instance, a dict-like object containing the configured settings for the client. Raises ------ ConfigError If no client configuration could be established, or if an invalid configuration name was specified, or if you try to change the client configuration after the client is already configured. """# Once the settings has been lazy evaluated, we cannot change it.# The reviled double-check pattern. Actually ok with CPython and the GIL,# but not necessarily any other Python implementation.settings=cls._settingsifsettingsisNone:withcls._lock:settings=cls._settingsifsettingsisNone:settings=cls._select_env(env=env,settings_file=settings_file,envvar_prefix=envvar_prefix,)ifsettingsisnotNoneandenvisnotNoneandenv!=settings.ENV:raiseConfigError(f"Client configuration '{settings.ENV}' has already been selected")returnsettings
[docs]@classmethoddefget_settings(cls):""" Configure and retrieve the current or default settings for the client. Returns ------- Settings Returns a ``Settings`` instance, a dict-like object containing the configured settings for the client. Raises ------ ConfigError If no client configuration could be established, or if an invalid configuration name was specified, or if you try to change the client configuration after the client is already configured. """# The reviled double-check pattern. Actually ok with CPython and the GIL,# but not necessarily any other Python implementation.settings=cls._settingsifsettingsisNone:withcls._lock:settings=cls._settingsifsettingsisNone:settings=cls._select_env()returnsettings
[docs]@classmethoddefpeek_settings(cls,env=None,settings_file=None,envvar_prefix="DESCARTESLABS"):"""Retrieve the settings without configuring the client. Unlike :py:meth:`~Settings.get_settings` and :py:meth:`~Settings.select_env` which both will configure the client, the :py:meth:`~Settings.peek_settings` will not configure the client and :py:attr:`Settings.env` will not be set. See :py:meth:`select_env` for an explanation of the parameters, return value, and exceptions that can be raised. """selector=f"{envvar_prefix}_ENV"original_selector_value=os.environ.get(selector)settings=cls._get_settings(env=env,settings_file=settings_file,envvar_prefix=envvar_prefix,)# Return the environ back to its original stateiforiginal_selector_valueisNone:os.environ.pop(selector)else:os.environ[selector]=original_selector_valuereturnsettings
@classmethoddef_select_env(cls,env=None,settings_file=None,envvar_prefix="DESCARTESLABS"):# Assign to the global instance.cls._settings=cls._get_settings(env=env,settings_file=settings_file,envvar_prefix=envvar_prefix)# And return the settings object.returncls._settings@classmethoddef_get_settings(cls,env=None,settings_file=None,envvar_prefix="DESCARTESLABS"):# Get the settings. If the settings are retrieved successfully, the os.environ# will contain the selector for the given settings.selector=f"{envvar_prefix}_ENV"original_selector_value=os.environ.get(selector)defrestore_env():iforiginal_selector_valueisNone:os.environ.pop(selector)else:os.environ[selector]=original_selector_valueifenv:os.environ[selector]=envelifnotos.environ.get(selector):# Default it.os.environ[selector]="aws-production"builtin_settings_file=os.path.join(os.path.dirname(os.path.abspath(__file__)),"settings.toml")try:# By default this will load from one or more settings files and# then from the environment.settings=cls(# First load our client settings from TOML file.settings_file=[builtin_settings_file],# Then load the given settings from TOML file, if any.includes=[]ifnotsettings_fileelse[settings_file],# Only allow TOML format.core_loaders=["TOML"],# Allow multiple environments ([default] is always used).environments=True,# Name of environment variable that selects the environment.env_switcher=selector,# Prefix to overwrite loaded settings, e.g,. {envvar_prefix}_MY_SETTING.envvar_prefix=envvar_prefix,)exceptExceptionase:restore_env()raiseConfigError(str(e))frometry:# Make sure we selected an environment!assertsettings.env_for_dynaconf# default_domain must have been setassertsettings.default_domainexcept(AttributeError,KeyError,AssertionError):message=f"Client configuration '{os.environ[selector]}' doesn't exist!"restore_env()ifnotenv:message+=" Check your DESCARTESLABS_ENV environment variable."raiseConfigError(message)fromNonereturnsettings
get_settings=Settings.get_settings"""An alias for :py:meth:`Settings.get_settings`"""peek_settings=Settings.peek_settings"""An alias for :py:meth:`Settings.peek_settings`"""select_env=Settings.select_env"""An alias for :py:meth:`Settings.select_env`"""__all__=["AWS_ENVIRONMENT","GCP_ENVIRONMENT","Settings","get_settings","peek_settings","select_env",]