1
Fork 0
mirror of https://github.com/RYGhub/royalnet.git synced 2024-11-23 03:24:20 +00:00

Remove royalnet.scrolls, superseded by cfig

https://github.com/Steffo99/cfig
This commit is contained in:
Steffo 2022-05-02 04:20:41 +02:00
parent b170c3a5f8
commit 6da801864a
Signed by: steffo
GPG key ID: 6965406171929D01
2 changed files with 0 additions and 184 deletions

View file

@ -1,149 +0,0 @@
"""
This module defines a class that can be used to easily load configuration from a :mod:`json` or :mod:`toml` file and
from :data:`os.environ`.
"""
from __future__ import annotations
import json
import os
import re
import toml
from royalnet.royaltyping import *
from .exc import *
T = TypeVar("T")
class Scroll:
"""
A configuration handler that allows getting values from both the environment variables and a config file.
"""
key_validator = re.compile(r"^[A-Za-z.]+$")
"""
A regex used to validate config keys.
"""
def __init__(self, namespace: str, config: Optional[Dict[str, JSON]] = None):
self.namespace: str = namespace
self.config: Optional[Dict[str, JSON]] = config
@classmethod
def from_toml(cls, namespace: str, file_path: os.PathLike) -> Scroll:
"""
Create a new :class:`.Scroll` from a :mod:`toml` file.
:param namespace: A string prefixed to the environment variable keys to disambiguate between multiple scroll
objects.
:param file_path: The path of the :mod:`toml` file to load.
:return: The created :class:`.Scroll` object.
"""
with open(file_path) as file:
config = toml.load(file)
return cls(namespace, config)
@classmethod
def from_json(cls, namespace: str, file_path: os.PathLike) -> Scroll:
"""
Create a new :class:`.Scroll` from a :mod:`json` file.
:param namespace: A string prefixed to the environment variable keys to disambiguate between multiple scroll
objects.
:param file_path: The path of the :mod:`json` file to load.
:return: The created :class:`.Scroll` object.
"""
with open(file_path) as file:
config = json.load(file)
return cls(namespace, config)
@classmethod
def from_file(cls, namespace: str, file_path: os.PathLike, require_file: bool = False) -> Scroll:
"""
Try to guess the type of the config file and create a new :class:`.Scroll` from it.
:param namespace: A string prefixed to the environment variable keys to disambiguate between multiple scroll
objects.
:param file_path: The path of the file to load.
:param require_file: Require the file to exist for the :class:`.Scroll` to be created.
:raise .exc.InvalidFileType: If the file format isn't supported.
:raise .exc.MissingConfigFile: If ``require_file`` is set to :data:`True` and the config file does not exist.
:return: The created :class:`.Scroll` object.
"""
if require_file and not os.path.exists(file_path):
raise MissingConfigFileError(f"No config file exists at path {file_path}, and require_file is set to True.")
_, ext = os.path.splitext(file_path)
lext = ext.lower()
try:
return cls.loaders[lext](namespace=namespace, file_path=file_path)
except KeyError:
raise InvalidFileType(f"Invalid extension: {lext}")
except FileNotFoundError:
return cls(namespace=namespace)
@classmethod
def _validate_key(cls, item: str):
check = cls.key_validator.match(item)
if not check:
raise InvalidFormatError()
def _get_from_environ(self, item: str) -> JSONScalar:
"""Get a configuration value from the environment variables."""
key = f"{self.namespace}_{item.replace('.', '_')}".upper()
try:
j = os.environ[key]
except KeyError:
raise NotFoundError(f"'{key}' was not found in the environment variables.")
try:
value = json.loads(j)
except json.JSONDecodeError:
raise ParseError(f"'{key}' contains invalid JSON: {j}")
return value
def _get_from_config(self, item: str) -> JSONScalar:
"""Get a configuration value from the configuration file."""
if self.config is None:
raise NotFoundError("No config file has been loaded.")
chain = item.lower().split(".")
current = self.config
for element in chain:
try:
current = current[element]
except KeyError:
raise NotFoundError(f"'{item}' was unreachable: could not find '{element}'")
return current
def __getitem__(self, item: str):
self._validate_key(item)
try:
return self._get_from_environ(item)
except NotFoundError:
return self._get_from_config(item)
def get(self, item: str, default: T) -> Union[JSONScalar, T]:
try:
return self[item]
except NotFoundError:
return default
Scroll.loaders = {
".json": Scroll.from_json,
".toml": Scroll.from_toml,
}
"""
An extension to deserialization function map.
"""
__all__ = ("Scroll",)

View file

@ -1,35 +0,0 @@
from ..exc import RoyalnetException
class ScrollsException(RoyalnetException):
"""An exception raised by the scrolls module."""
class NotFoundError(ScrollsException, KeyError):
"""The requested config key was not found."""
class MissingConfigFileError(ScrollsException, IOError):
"""The config file does not exist, and ``require_file`` is set to :data:`True`."""
class InvalidFormatError(ScrollsException):
"""The requested config key is not valid."""
class ParseError(ScrollsException):
"""The config value could not be parsed correctly."""
class InvalidFileType(ParseError):
"""The type of the specified config file is not currently supported."""
__all__ = (
"ScrollsException",
"NotFoundError",
"MissingConfigFileError",
"InvalidFormatError",
"ParseError",
"InvalidFileType",
)