Exemple #1
0
def from_pyfile(self, filename: str) -> bool:
    """Update the values in the config from a Python file.
    Only the uppercase variables in that module are stored in the config.

    :param filename: an absolute path to the config file
    """

    warn(
        "Using `from_pyfile` method is deprecated and will be removed in "
        "v21.3, use `app.update_config` method instead.",
        DeprecationWarning,
        stacklevel=2,
    )

    module = types.ModuleType("config")
    module.__file__ = filename
    try:
        with open(filename) as config_file:
            exec(  # nosec
                compile(config_file.read(), filename, "exec"),
                module.__dict__,
            )
    except IOError as e:
        e.strerror = "Unable to load configuration file (e.strerror)"
        raise
    except Exception as e:
        raise PyFileError(filename) from e

    self.from_object(module)
    return True
Exemple #2
0
    def from_pyfile(self, filename):
        """Update the values in the config from a Python file.
        Only the uppercase variables in that module are stored in the config.

        :param filename: an absolute path to the config file
        """
        module = types.ModuleType('config')
        module.__file__ = filename
        try:
            with open(filename) as config_file:
                exec(compile(config_file.read(), filename, 'exec'),
                     module.__dict__)
        except IOError as e:
            e.strerror = 'Unable to load configuration file (%s)' % e.strerror
            raise
        except Exception as e:
            raise PyFileError(filename) from e

        self.from_object(module)
        return True
Exemple #3
0
def load_module_from_file_location(
    location: Union[bytes, str, Path], encoding: str = "utf8", *args, **kwargs
):  # noqa
    """Returns loaded module provided as a file path.

    :param args:
        Coresponds to importlib.util.spec_from_file_location location
        parameters,but with this differences:
        - It has to be of a string or bytes type.
        - You can also use here environment variables
          in format ${some_env_var}.
          Mark that $some_env_var will not be resolved as environment variable.
    :encoding:
        If location parameter is of a bytes type, then use this encoding
        to decode it into string.
    :param args:
        Coresponds to the rest of importlib.util.spec_from_file_location
        parameters.
    :param kwargs:
        Coresponds to the rest of importlib.util.spec_from_file_location
        parameters.

    For example You can:

        some_module = load_module_from_file_location(
            "some_module_name",
            "/some/path/${some_env_var}"
        )
    """
    if isinstance(location, bytes):
        location = location.decode(encoding)

    if isinstance(location, Path) or "/" in location or "$" in location:

        if not isinstance(location, Path):
            # A) Check if location contains any environment variables
            #    in format ${some_env_var}.
            env_vars_in_location = set(re_findall(r"\${(.+?)}", location))

            # B) Check these variables exists in environment.
            not_defined_env_vars = env_vars_in_location.difference(
                os_environ.keys()
            )
            if not_defined_env_vars:
                raise LoadFileException(
                    "The following environment variables are not set: "
                    f"{', '.join(not_defined_env_vars)}"
                )

            # C) Substitute them in location.
            for env_var in env_vars_in_location:
                location = location.replace(
                    "${" + env_var + "}", os_environ[env_var]
                )

        location = str(location)
        if ".py" in location:
            name = location.split("/")[-1].split(".")[
                0
            ]  # get just the file name without path and .py extension
            _mod_spec = spec_from_file_location(
                name, location, *args, **kwargs
            )
            assert _mod_spec is not None  # type assertion for mypy
            module = module_from_spec(_mod_spec)
            _mod_spec.loader.exec_module(module)  # type: ignore

        else:
            module = types.ModuleType("config")
            module.__file__ = str(location)
            try:
                with open(location) as config_file:
                    exec(  # nosec
                        compile(config_file.read(), location, "exec"),
                        module.__dict__,
                    )
            except IOError as e:
                e.strerror = "Unable to load configuration file (e.strerror)"
                raise
            except Exception as e:
                raise PyFileError(location) from e

        return module
    else:
        try:
            return import_string(location)
        except ValueError:
            raise IOError("Unable to load configuration %s" % str(location))