from __future__ import annotations import importlib import os import sys import warnings from dynaconf.utils import RENAMED_VARS from dynaconf.utils import upperfy from dynaconf.utils import warn_deprecations from dynaconf.utils.files import find_file from dynaconf.utils.parse_conf import parse_conf_data from dynaconf.vendor.dotenv import load_dotenv def try_renamed(key, value, older_key, current_key): if value is None: if key == current_key: if older_key in os.environ: warnings.warn( f"{older_key} is deprecated please use {current_key}", DeprecationWarning, ) value = os.environ[older_key] return value def get(key, default=None): value = os.environ.get(upperfy(key)) # compatibility with renamed variables for old, new in RENAMED_VARS.items(): value = try_renamed(key, value, old, new) return ( parse_conf_data(value, tomlfy=True, box_settings={}) if value is not None else default ) def start_dotenv(obj=None, root_path=None): # load_from_dotenv_if_installed obj = obj or {} _find_file = getattr(obj, "find_file", find_file) root_path = ( root_path or getattr(obj, "_root_path", None) or get("ROOT_PATH_FOR_DYNACONF") ) dotenv_path = ( obj.get("DOTENV_PATH_FOR_DYNACONF") or get("DOTENV_PATH_FOR_DYNACONF") or _find_file(".env", project_root=root_path) ) load_dotenv( dotenv_path, verbose=obj.get("DOTENV_VERBOSE_FOR_DYNACONF", False), override=obj.get("DOTENV_OVERRIDE_FOR_DYNACONF", False), ) warn_deprecations(os.environ) def reload(load_dotenv=None, *args, **kwargs): if load_dotenv: start_dotenv(*args, **kwargs) importlib.reload(sys.modules[__name__]) # default proj root # pragma: no cover ROOT_PATH_FOR_DYNACONF = get("ROOT_PATH_FOR_DYNACONF", None) # Default settings file SETTINGS_FILE_FOR_DYNACONF = get("SETTINGS_FILE_FOR_DYNACONF", []) # MISPELLS `FILES` when/if it happens mispelled_files = get("SETTINGS_FILES_FOR_DYNACONF", None) if not SETTINGS_FILE_FOR_DYNACONF and mispelled_files is not None: SETTINGS_FILE_FOR_DYNACONF = mispelled_files # # ENV SETTINGS # # In dynaconf 1.0.0 `NAMESPACE` got renamed to `ENV` # If provided environments will be loaded separately ENVIRONMENTS_FOR_DYNACONF = get("ENVIRONMENTS_FOR_DYNACONF", False) MAIN_ENV_FOR_DYNACONF = get("MAIN_ENV_FOR_DYNACONF", "MAIN") # If False dynaconf will allow access to first level settings only in upper LOWERCASE_READ_FOR_DYNACONF = get("LOWERCASE_READ_FOR_DYNACONF", True) # The environment variable to switch current env ENV_SWITCHER_FOR_DYNACONF = get( "ENV_SWITCHER_FOR_DYNACONF", "ENV_FOR_DYNACONF" ) # The current env by default is DEVELOPMENT # to switch is needed to `export ENV_FOR_DYNACONF=PRODUCTION` # or put that value in .env file # this value is used only when reading files like .toml|yaml|ini|json ENV_FOR_DYNACONF = get(ENV_SWITCHER_FOR_DYNACONF, "DEVELOPMENT") # This variable exists to support `from_env` method FORCE_ENV_FOR_DYNACONF = get("FORCE_ENV_FOR_DYNACONF", None) # Default values is taken from DEFAULT pseudo env # this value is used only when reading files like .toml|yaml|ini|json DEFAULT_ENV_FOR_DYNACONF = get("DEFAULT_ENV_FOR_DYNACONF", "DEFAULT") # Global values are taken from DYNACONF env used for exported envvars # Values here overwrites all other envs # This namespace is used for files and also envvars ENVVAR_PREFIX_FOR_DYNACONF = get("ENVVAR_PREFIX_FOR_DYNACONF", "DYNACONF") # By default all environment variables (filtered by `envvar_prefix`) will # be pulled into settings space. In case some of them are polluting the space, # setting this flag to `True` will change this behaviour. # Only "known" variables will be considered -- that is variables defined before # in settings files (or includes/preloads). IGNORE_UNKNOWN_ENVVARS_FOR_DYNACONF = get( "IGNORE_UNKNOWN_ENVVARS_FOR_DYNACONF", False ) AUTO_CAST_FOR_DYNACONF = get("AUTO_CAST_FOR_DYNACONF", True) # The default encoding to open settings files ENCODING_FOR_DYNACONF = get("ENCODING_FOR_DYNACONF", "utf-8") # Merge objects on load MERGE_ENABLED_FOR_DYNACONF = get("MERGE_ENABLED_FOR_DYNACONF", False) # Lookup keys considering dots as separators DOTTED_LOOKUP_FOR_DYNACONF = get("DOTTED_LOOKUP_FOR_DYNACONF", True) # BY default `__` is the separator for nested env vars # export `DYNACONF__DATABASE__server=server.com` # export `DYNACONF__DATABASE__PORT=6666` # Should result in settings.DATABASE == {'server': 'server.com', 'PORT': 6666} # To disable it one can set `NESTED_SEPARATOR_FOR_DYNACONF=false` NESTED_SEPARATOR_FOR_DYNACONF = get("NESTED_SEPARATOR_FOR_DYNACONF", "__") # The env var specifying settings module ENVVAR_FOR_DYNACONF = get("ENVVAR_FOR_DYNACONF", "SETTINGS_FILE_FOR_DYNACONF") # Default values for redis configs default_redis = { "host": get("REDIS_HOST_FOR_DYNACONF", "localhost"), "port": int(get("REDIS_PORT_FOR_DYNACONF", 6379)), "db": int(get("REDIS_DB_FOR_DYNACONF", 0)), "decode_responses": get("REDIS_DECODE_FOR_DYNACONF", True), "username": get("REDIS_USERNAME_FOR_DYNACONF", None), "password": get("REDIS_PASSWORD_FOR_DYNACONF", None), } REDIS_FOR_DYNACONF = get("REDIS_FOR_DYNACONF", default_redis) REDIS_ENABLED_FOR_DYNACONF = get("REDIS_ENABLED_FOR_DYNACONF", False) # Hashicorp Vault Project vault_scheme = get("VAULT_SCHEME_FOR_DYNACONF", "http") vault_host = get("VAULT_HOST_FOR_DYNACONF", "localhost") vault_port = get("VAULT_PORT_FOR_DYNACONF", "8200") default_vault = { "url": get( "VAULT_URL_FOR_DYNACONF", f"{vault_scheme}://{vault_host}:{vault_port}" ), "token": get("VAULT_TOKEN_FOR_DYNACONF", None), "cert": get("VAULT_CERT_FOR_DYNACONF", None), "verify": get("VAULT_VERIFY_FOR_DYNACONF", None), "timeout": get("VAULT_TIMEOUT_FOR_DYNACONF", None), "proxies": get("VAULT_PROXIES_FOR_DYNACONF", None), "allow_redirects": get("VAULT_ALLOW_REDIRECTS_FOR_DYNACONF", None), "namespace": get("VAULT_NAMESPACE_FOR_DYNACONF", None), } VAULT_FOR_DYNACONF = get("VAULT_FOR_DYNACONF", default_vault) VAULT_ENABLED_FOR_DYNACONF = get("VAULT_ENABLED_FOR_DYNACONF", False) VAULT_PATH_FOR_DYNACONF = get("VAULT_PATH_FOR_DYNACONF", "dynaconf") VAULT_MOUNT_POINT_FOR_DYNACONF = get( "VAULT_MOUNT_POINT_FOR_DYNACONF", "secret" ) VAULT_ROOT_TOKEN_FOR_DYNACONF = get("VAULT_ROOT_TOKEN_FOR_DYNACONF", None) VAULT_KV_VERSION_FOR_DYNACONF = get("VAULT_KV_VERSION_FOR_DYNACONF", 1) VAULT_AUTH_WITH_IAM_FOR_DYNACONF = get( "VAULT_AUTH_WITH_IAM_FOR_DYNACONF", False ) VAULT_AUTH_ROLE_FOR_DYNACONF = get("VAULT_AUTH_ROLE_FOR_DYNACONF", None) VAULT_ROLE_ID_FOR_DYNACONF = get("VAULT_ROLE_ID_FOR_DYNACONF", None) VAULT_SECRET_ID_FOR_DYNACONF = get("VAULT_SECRET_ID_FOR_DYNACONF", None) # Only core loaders defined on this list will be invoked core_loaders = ["YAML", "TOML", "INI", "JSON", "PY"] CORE_LOADERS_FOR_DYNACONF = get("CORE_LOADERS_FOR_DYNACONF", core_loaders) # External Loaders to read vars from different data stores default_loaders = [ "dynaconf.loaders.env_loader", # 'dynaconf.loaders.redis_loader' # 'dynaconf.loaders.vault_loader' ] LOADERS_FOR_DYNACONF = get("LOADERS_FOR_DYNACONF", default_loaders) # Errors in loaders should be silenced? SILENT_ERRORS_FOR_DYNACONF = get("SILENT_ERRORS_FOR_DYNACONF", True) # always fresh variables FRESH_VARS_FOR_DYNACONF = get("FRESH_VARS_FOR_DYNACONF", []) DOTENV_PATH_FOR_DYNACONF = get("DOTENV_PATH_FOR_DYNACONF", None) DOTENV_VERBOSE_FOR_DYNACONF = get("DOTENV_VERBOSE_FOR_DYNACONF", False) DOTENV_OVERRIDE_FOR_DYNACONF = get("DOTENV_OVERRIDE_FOR_DYNACONF", False) # Currently this is only used by cli. INSTANCE_FOR_DYNACONF specifies python # dotted path to custom LazySettings instance. Last dotted path item should be # instance of LazySettings. INSTANCE_FOR_DYNACONF = get("INSTANCE_FOR_DYNACONF", None) # https://msg.pyyaml.org/load YAML_LOADER_FOR_DYNACONF = get("YAML_LOADER_FOR_DYNACONF", "safe_load") # Use commentjson? https://commentjson.readthedocs.io/en/latest/ COMMENTJSON_ENABLED_FOR_DYNACONF = get( "COMMENTJSON_ENABLED_FOR_DYNACONF", False ) # Extra file, or list of files where to look for secrets # useful for CI environment like jenkins # where you can export this variable pointing to a local # absolute path of the secrets file. SECRETS_FOR_DYNACONF = get("SECRETS_FOR_DYNACONF", None) # To include extra paths based on envvar INCLUDES_FOR_DYNACONF = get("INCLUDES_FOR_DYNACONF", []) # To pre-load extra paths based on envvar PRELOAD_FOR_DYNACONF = get("PRELOAD_FOR_DYNACONF", []) # Files to skip if found on search tree SKIP_FILES_FOR_DYNACONF = get("SKIP_FILES_FOR_DYNACONF", []) # YAML reads empty vars as None, should dynaconf apply validator defaults? # this is set to None, then evaluated on base.Settings.setdefault # possible values are True/False APPLY_DEFAULT_ON_NONE_FOR_DYNACONF = get( "APPLY_DEFAULT_ON_NONE_FOR_DYNACONF", None ) # Backwards compatibility with renamed variables for old, new in RENAMED_VARS.items(): setattr(sys.modules[__name__], old, locals()[new])