Exemplo n.º 1
0
    def load(self, filename=None, key=None, silent=True):
        """
        Reads and loads in to `self.obj` a single key or all keys from source

        :param filename: Optional filename to load
        :param key: if provided load a single key
        :param silent: if load erros should be silenced
        """

        filename = filename or self.obj.get(self.identifier.upper())
        if not filename:
            return

        if not isinstance(filename, (list, tuple)):
            split_files = ensure_a_list(filename)
            if all([f.endswith(self.extensions) for f in split_files]):  # noqa
                files = split_files  # it is a ['file.ext', ...]
            else:  # it is a single config as string
                files = [filename]
        else:  # it is already a list/tuple
            files = filename

        source_data = self.get_source_data(files)

        if self.obj.get("ENVIRONMENTS_FOR_DYNACONF") is False:
            self._envless_load(source_data, silent, key)
        else:
            self._load_all_envs(source_data, silent, key)
Exemplo n.º 2
0
    def load(self, filename=None, key=None, silent=True):
        """
        Reads and loads in to `self.obj` a single key or all keys from source

        :param filename: Optional filename to load
        :param key: if provided load a single key
        :param silent: if load erros should be silenced
        """
        filename = filename or self.obj.get(self.identifier.upper())
        if not filename:
            return

        if not isinstance(filename, (list, tuple)):
            split_files = ensure_a_list(filename)
            if all([f.endswith(self.extensions) for f in split_files]):  # noqa
                files = split_files  # it is a ['file.ext', ...]
            else:  # it is a single config as string
                files = [filename]
        else:  # it is already a list/tuple
            files = filename

        self.obj._loaded_files.extend(files)

        env_list = build_env_list(self.obj, self.env)

        # load all envs
        self._read(files, env_list, silent, key)
Exemplo n.º 3
0
 def load_includes(self, env, silent, key):
     """Do we have any nested includes we need to process?"""
     includes = self.get("DYNACONF_INCLUDE", [])
     includes.extend(ensure_a_list(self.get("INCLUDES_FOR_DYNACONF")))
     if includes:
         self.logger.debug("Processing includes %s", includes)
         self.load_file(path=includes, env=env, silent=silent, key=key)
Exemplo n.º 4
0
 def load_includes(self, env, silent, key):
     """Do we have any nested includes we need to process?"""
     includes = self.get("DYNACONF_INCLUDE", [])
     includes.extend(ensure_a_list(self.get("INCLUDES_FOR_DYNACONF")))
     if includes:
         self.load_file(path=includes, env=env, silent=silent, key=key)
         # ensure env vars are the last thing loaded after all includes
         last_loader = self.loaders and self.loaders[-1]
         if last_loader and last_loader == env_loader:
             last_loader.load(self, env, silent, key)
Exemplo n.º 5
0
    def validate(
        self,
        settings: Any,
        only: Optional[Union[str, Sequence]] = None,
        exclude: Optional[Union[str, Sequence]] = None,
    ) -> None:
        """Raise ValidationError if invalid"""
        # If only or exclude are not set, this value always passes startswith
        only = ensure_a_list(only or [""])
        if only and not isinstance(only[0], str):
            raise ValueError("'only' must be a string or list of strings.")

        exclude = ensure_a_list(exclude)
        if exclude and not isinstance(exclude[0], str):
            raise ValueError("'exclude' must be a string or list of strings.")

        if self.envs is None:
            self.envs = [settings.current_env]

        if self.when is not None:
            try:
                # inherit env if not defined
                if self.when.envs is None:
                    self.when.envs = self.envs

                self.when.validate(settings, only=only, exclude=exclude)
            except ValidationError:
                # if when is invalid, return canceling validation flow
                return

        # If only using current_env, skip using_env decoration (reload)
        if (len(self.envs) == 1
                and self.envs[0].upper() == settings.current_env.upper()):
            self._validate_items(settings,
                                 settings.current_env,
                                 only=only,
                                 exclude=exclude)
            return

        for env in self.envs:
            self._validate_items(settings.from_env(env),
                                 only=only,
                                 exclude=exclude)
Exemplo n.º 6
0
    def load_file(self, path=None, env=None, silent=True, key=None):
        """Programmatically load files from ``path``.

        :param path: A single filename or a file list
        :param env: Which env to load from file (default current_env)
        :param silent: Should raise errors?
        :param key: Load a single key?
        """
        env = (env or self.current_env).upper()
        files = ensure_a_list(path)
        if files:
            already_loaded = set()
            for _filename in files:

                if py_loader.try_to_load_from_py_module_name(
                    obj=self, name=_filename, silent=True
                ):
                    # if it was possible to load from module name
                    # continue the loop.
                    continue

                # python 3.6 does not resolve Pathlib basedirs
                # issue #494
                root_dir = str(self._root_path or os.getcwd())
                if (
                    isinstance(_filename, Path)
                    and str(_filename.parent) in root_dir
                ):  # pragma: no cover
                    filepath = str(_filename)
                else:
                    filepath = os.path.join(
                        self._root_path or os.getcwd(), str(_filename)
                    )

                paths = [
                    p
                    for p in sorted(glob.glob(filepath))
                    if ".local." not in p
                ]
                local_paths = [
                    p for p in sorted(glob.glob(filepath)) if ".local." in p
                ]
                # Handle possible *.globs sorted alphanumeric
                for path in paths + local_paths:
                    if path in already_loaded:  # pragma: no cover
                        continue
                    settings_loader(
                        obj=self,
                        env=env,
                        silent=silent,
                        key=key,
                        filename=path,
                    )
                    already_loaded.add(path)
Exemplo n.º 7
0
    def load_file(self, path=None, env=None, silent=True, key=None):
        """Programmatically load files from ``path``.

        :param path: A single filename or a file list
        :param env: Which env to load from file (default current_env)
        :param silent: Should raise errors?
        :param key: Load a single key?
        """
        env = (env or self.current_env).upper()
        files = ensure_a_list(path)
        if files:
            self.logger.debug(f"Got {files} files to process")
            already_loaded = set()
            for _filename in files:
                self.logger.debug(f"Processing file {_filename}")

                if py_loader.try_to_load_from_py_module_name(
                    obj=self, name=_filename, silent=True
                ):
                    # if it was possible to load from module name
                    # continue the loop.
                    continue

                filepath = os.path.join(
                    self._root_path or os.getcwd(), _filename
                )
                self.logger.debug(f"File path is {filepath}")
                paths = [
                    p
                    for p in sorted(glob.glob(filepath))
                    if ".local." not in p
                ]
                local_paths = [
                    p for p in sorted(glob.glob(filepath)) if ".local." in p
                ]
                # Handle possible *.globs sorted alphanumeric
                for path in paths + local_paths:
                    self.logger.debug(f"Loading {path}")
                    if path in already_loaded:  # pragma: no cover
                        self.logger.debug(f"Skipping {path}, already loaded")
                        continue
                    settings_loader(
                        obj=self,
                        env=env,
                        silent=silent,
                        key=key,
                        filename=path,
                    )
                    already_loaded.add(path)
            if not already_loaded:
                self.logger.warning(
                    f"Not able to locate the files {files} " "to load"
                )
Exemplo n.º 8
0
def test_ensure_a_list():

    # No data is empty list
    assert ensure_a_list(None) == []

    # Sequence types is only converted
    assert ensure_a_list([1, 2]) == [1, 2]
    assert ensure_a_list((1, 2)) == [1, 2]
    assert ensure_a_list({1, 2}) == [1, 2]

    # A string is trimmed_splitted
    assert ensure_a_list("ab.toml") == ["ab.toml"]
    assert ensure_a_list("ab.toml,cd.toml") == ["ab.toml", "cd.toml"]
    assert ensure_a_list("ab.toml;cd.toml") == ["ab.toml", "cd.toml"]

    # other types get wrapped in a list
    assert ensure_a_list(1) == [1]
Exemplo n.º 9
0
    def load(self, filename=None, key=None, silent=True):
        """
        Reads and loads in to `self.obj` a single key or all keys from source

        :param filename: Optional filename to load
        :param key: if provided load a single key
        :param silent: if load erros should be silenced
        """
        filename = filename or self.obj.get(self.identifier.upper())
        if not filename:
            return

        if not isinstance(filename, (list, tuple)):
            split_files = ensure_a_list(filename)
            if all([f.endswith(self.extensions) for f in split_files]):  # noqa
                files = split_files  # it is a ['file.ext', ...]
            else:  # it is a single config as string
                files = [filename]
        else:  # it is already a list/tuple
            files = filename

        self.obj._loaded_files.extend(files)

        # add the [default] env
        env_list = [self.obj.get("DEFAULT_ENV_FOR_DYNACONF")]

        # compatibility with older versions that still uses [dynaconf] as
        # [default] env
        global_env = self.obj.get("ENVVAR_PREFIX_FOR_DYNACONF") or "DYNACONF"
        if global_env not in env_list:
            env_list.append(global_env)

        # add the current [env]
        if self.env not in env_list:
            env_list.append(self.env)

        # add the [global] env
        env_list.append("GLOBAL")

        # load all envs
        self._read(files, env_list, silent, key)
Exemplo n.º 10
0
def settings_loader(obj,
                    settings_module=None,
                    env=None,
                    silent=True,
                    key=None,
                    filename=None):
    """Loads from defined settings module

    :param obj: A dynaconf instance
    :param settings_module: A path or a list of paths e.g settings.toml
    :param env: Env to look for data defaults: development
    :param silent: Boolean to raise loading errors
    :param key: Load a single key if provided
    :param filename: optional filename to override the settings_module
    """
    if filename is None:
        settings_module = settings_module or obj.settings_module
        if not settings_module:  # pragma: no cover
            return
        files = ensure_a_list(settings_module)
    else:
        files = ensure_a_list(filename)

    files.extend(ensure_a_list(obj.get("SECRETS_FOR_DYNACONF", None)))

    found_files = []
    modules_names = []
    for item in files:
        if item.endswith(ct.ALL_EXTENSIONS + (".py", )):
            p_root = obj._root_path or (os.path.dirname(found_files[0])
                                        if found_files else None)
            found = obj.find_file(item, project_root=p_root)
            if found:
                found_files.append(found)
        else:
            # a bare python module name w/o extension
            modules_names.append(item)

    enabled_core_loaders = obj.get("CORE_LOADERS_FOR_DYNACONF")

    for mod_file in modules_names + found_files:
        # can be set to multiple files settings.py,settings.yaml,...

        # Cascade all loaders
        loaders = [
            {
                "ext": ct.YAML_EXTENSIONS,
                "name": "YAML",
                "loader": yaml_loader
            },
            {
                "ext": ct.TOML_EXTENSIONS,
                "name": "TOML",
                "loader": toml_loader
            },
            {
                "ext": ct.INI_EXTENSIONS,
                "name": "INI",
                "loader": ini_loader
            },
            {
                "ext": ct.JSON_EXTENSIONS,
                "name": "JSON",
                "loader": json_loader
            },
        ]

        for loader in loaders:
            if loader["name"] not in enabled_core_loaders:
                continue

            if mod_file.endswith(loader["ext"]):
                loader["loader"].load(obj,
                                      filename=mod_file,
                                      env=env,
                                      silent=silent,
                                      key=key)
                continue

        if mod_file.endswith(ct.ALL_EXTENSIONS):
            continue

        if "PY" not in enabled_core_loaders:
            # pyloader is disabled
            continue

        # must be Python file or module
        # load from default defined module settings.py or .secrets.py if exists
        py_loader.load(obj, mod_file, key=key)

        # load from the current env e.g: development_settings.py
        env = env or obj.current_env
        if mod_file.endswith(".py"):
            if ".secrets.py" == mod_file:
                tmpl = ".{0}_{1}{2}"
                mod_file = "secrets.py"
            else:
                tmpl = "{0}_{1}{2}"

            dirname = os.path.dirname(mod_file)
            filename, extension = os.path.splitext(os.path.basename(mod_file))
            new_filename = tmpl.format(env.lower(), filename, extension)
            env_mod_file = os.path.join(dirname, new_filename)
            global_filename = tmpl.format("global", filename, extension)
            global_mod_file = os.path.join(dirname, global_filename)
        else:
            env_mod_file = "{0}_{1}".format(env.lower(), mod_file)
            global_mod_file = "{0}_{1}".format("global", mod_file)

        py_loader.load(
            obj,
            env_mod_file,
            identifier="py_{0}".format(env.upper()),
            silent=True,
            key=key,
        )

        # load from global_settings.py
        py_loader.load(obj,
                       global_mod_file,
                       identifier="py_global",
                       silent=True,
                       key=key)