Source code for pyapp.conf.loaders.file_loader

"""
File Loader
~~~~~~~~~~~

Loads settings from a file

"""

from pathlib import Path
from typing import Union

from yarl import URL

from pyapp.conf.loaders.base import Loader
from pyapp.conf.loaders.content_types import content_type_from_url, registry
from pyapp.exceptions import InvalidConfiguration


[docs] class FileLoader(Loader): """ Load settings from a file. Usage:: >>> loader = FileLoader('/path/to/settings.json') >>> settings = dict(loader) """ scheme = "file" @classmethod def from_url(cls, url: URL) -> Loader: """ Create an instance of :class:`FileLoader` from :class:`urllib.parse.ParseResult`. """ content_type = content_type_from_url(url) return cls(url.path, content_type) def __init__( self, path: Union[str, Path], content_type: str, *, encoding: str = "UTF8" ): """ :param path: Path to file; can be either absolute or relative to PWD. :param content_type: Content type of the file :param encoding: Encoding of the file; defaults to UTF-8 """ self.path = Path(path) self.content_type = content_type self.encoding = encoding def __iter__(self): try: with self.path.open(encoding=self.encoding) as fp: data = registry.parse_file(fp, self.content_type) except FileNotFoundError as ex: raise InvalidConfiguration(f"Settings file not found: {self}\n{ex}") from ex except OSError as ex: raise InvalidConfiguration(f"Unable to load settings: {self}\n{ex}") from ex except ValueError as ex: raise InvalidConfiguration(f"Unable to parse file: {self}\n{ex}") from ex # Check we have a valid container object if not isinstance(data, dict): raise InvalidConfiguration( f"Invalid root object, expected an Object: {self}" ) return ((k, v) for k, v in data.items() if k.isupper()) def __str__(self): return f"file://{self.path.as_posix()}?type={self.content_type}"