From d6b2c9b15ceec8932755949a7ca8359540494afb Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Tue, 19 Apr 2022 01:32:10 +0200 Subject: [PATCH] :wrench: Split sources into their own namespace package --- cfig/__init__.py | 2 -- cfig/config.py | 12 +++++---- cfig/sources/base.py | 23 ++++++++++++++++ cfig/{sources.py => sources/env.py} | 41 ++--------------------------- cfig/sources/envfile.py | 27 +++++++++++++++++++ 5 files changed, 59 insertions(+), 46 deletions(-) create mode 100644 cfig/sources/base.py rename cfig/{sources.py => sources/env.py} (51%) create mode 100644 cfig/sources/envfile.py diff --git a/cfig/__init__.py b/cfig/__init__.py index 196487e..503cd2f 100644 --- a/cfig/__init__.py +++ b/cfig/__init__.py @@ -95,8 +95,6 @@ Configuration # noinspection PyUnresolvedReferences from .config import * # noinspection PyUnresolvedReferences -from .sources import * -# noinspection PyUnresolvedReferences from .errors import * # noinspection PyUnresolvedReferences from .customtyping import * diff --git a/cfig/config.py b/cfig/config.py index ad0ef0e..175c6ad 100644 --- a/cfig/config.py +++ b/cfig/config.py @@ -8,7 +8,9 @@ import logging import collections from . import errors from . import customtyping as ct -from . import sources as s +from cfig.sources.base import Source +from cfig.sources.env import EnvironmentSource +from cfig.sources.envfile import EnvironmentFileSource log = logging.getLogger(__name__) @@ -19,8 +21,8 @@ class Configuration: """ DEFAULT_SOURCES = [ - s.EnvironmentSource(), - s.EnvironmentFileSource(), + EnvironmentSource(), + EnvironmentFileSource(), ] """ The sources used in :meth:`__init__` if no other source is specified. @@ -73,14 +75,14 @@ class Configuration: log.debug(f"Unresolving: {item!r}") del item.__wrapped__ - def __init__(self, *, sources: t.Optional[t.Collection[s.Source]] = None): + def __init__(self, *, sources: t.Optional[t.Collection[Source]] = None): """ Create a new :class:`Configuration`. """ log.debug(f"Initializing a new {self.__class__.__qualname__} object...") - self.sources: t.Collection[s.Source] = sources or self.DEFAULT_SOURCES + self.sources: t.Collection[Source] = sources or self.DEFAULT_SOURCES """ Collection of sources to use for values of this configuration. """ diff --git a/cfig/sources/base.py b/cfig/sources/base.py new file mode 100644 index 0000000..bf9dbb6 --- /dev/null +++ b/cfig/sources/base.py @@ -0,0 +1,23 @@ +import abc +import typing as t + + +class Source(metaclass=abc.ABCMeta): + """ + A source of values to be tapped by configurations. + + **Abstract class.** Cannot be instantiated. Should be inherited from other source classes. + + Other packages can add more sources directly to the :mod:`cfig.sources` namespace package. + """ + + @abc.abstractmethod + def get(self, key: str) -> t.Optional[str]: + """ + Get the value with the given key from the source. + """ + + +__all__ = ( + "Source", +) diff --git a/cfig/sources.py b/cfig/sources/env.py similarity index 51% rename from cfig/sources.py rename to cfig/sources/env.py index 5247ddb..b47620b 100644 --- a/cfig/sources.py +++ b/cfig/sources/env.py @@ -1,18 +1,6 @@ -import typing as t -import abc import os - - -class Source(metaclass=abc.ABCMeta): - """ - A source of values to be tapped by configurations. - """ - - @abc.abstractmethod - def get(self, key: str) -> t.Optional[str]: - """ - Get the value with the given key from the source - """ +import typing as t +from cfig.sources.base import Source class EnvironmentSource(Source): @@ -49,28 +37,3 @@ class EnvironmentSource(Source): key = self._process_key(key) return self.environment.get(key) - -class EnvironmentFileSource(EnvironmentSource): - """ - A source which gets values from files at paths specified in environment variables. - """ - - def __init__(self, *, prefix: str = "", suffix: str = "_FILE", environment=os.environ): - super().__init__(prefix=prefix, suffix=suffix, environment=environment) - - def get(self, key: str) -> t.Optional[str]: - path = super().get(key) - if path is None: - return None - try: - with open(path, "r") as file: - return file.read() - except FileNotFoundError: - return None - - -__all__ = ( - "Source", - "EnvironmentSource", - "EnvironmentFileSource", -) diff --git a/cfig/sources/envfile.py b/cfig/sources/envfile.py new file mode 100644 index 0000000..41a1275 --- /dev/null +++ b/cfig/sources/envfile.py @@ -0,0 +1,27 @@ +import os +import typing as t +from cfig.sources.env import EnvironmentSource + + +class EnvironmentFileSource(EnvironmentSource): + """ + A source which gets values from files at paths specified in environment variables. + """ + + def __init__(self, *, prefix: str = "", suffix: str = "_FILE", environment=os.environ): + super().__init__(prefix=prefix, suffix=suffix, environment=environment) + + def get(self, key: str) -> t.Optional[str]: + path = super().get(key) + if path is None: + return None + try: + with open(path, "r") as file: + return file.read() + except FileNotFoundError: + return None + + +__all__ = ( + "EnvironmentFileSource", +)