Last active
March 13, 2023 19:29
-
-
Save pedro-psb/bd857bf49c93c7fd83dac9c5d0968867 to your computer and use it in GitHub Desktop.
dynaconf: custom loader boilerplate example #750
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from __future__ import annotations | |
from io import TextIOWrapper | |
from typing import Callable, TypeAlias | |
FileParser: TypeAlias = Callable[[TextIOWrapper], dict[str, str]] | |
def load_data(obj, file_parser: FileParser, extensions: tuple[str, ...], **kwargs): | |
""" | |
Utility to load data to dynaconf settings from files that match `extensions` using custom file_reader | |
:obj: the obj provided by `load()` (a settings instance) | |
:param file_parser: a function that receives a file stream and return it's content as a dict | |
:extensions: the extensions used to select which files will be read. | |
""" | |
if filename := kwargs.get("filename"): | |
with open(filename) as open_file: | |
data = file_parser(open_file) | |
obj.update(data) | |
obj._loaded_files.append(filename) | |
else: | |
# get all filenames with given extension | |
all_files = obj.settings_file or obj.settings_files | |
sff_files = [file for file in all_files if file.endswith(extensions)] | |
# read all selected files | |
for file in all_files: | |
with open(file) as open_file: | |
data = file_parser(open_file) | |
obj.update(data) | |
obj._loaded_files.append(file) | |
def load(obj, *args, **kwargs): | |
""" | |
Reads and loads in to "obj" a single key or all keys from source | |
:param obj: the settings instance | |
:param env: settings current env (upper case) default='DEVELOPMENT' | |
:param silent: if errors should raise | |
:param key: if defined load a single key, else load all from `env` | |
:param filename: Custom filename to load (useful for tests) | |
:return: None | |
""" | |
# Load data from your custom data source (file, database, memory etc) | |
# use `obj.set(key, value)` or `obj.update(dict)` to load data | |
# use `obj.find_file('filename.ext')` to find the file in search tree | |
# Return nothing | |
# This loader reads the .sff file // Stupid File Format | |
SFF_EXTENSIONS = (".sff", ".sfx") | |
def file_parser(file: TextIOWrapper): | |
"""Should be implemented by the user to parse his own filetype""" | |
keys = [] | |
values = [] | |
for line in file.readlines(): | |
if line.startswith("#"): | |
continue | |
if line.startswith("KEYS:"): | |
keys = line.strip("KEYS:").strip("\n").split(";") | |
if line.startswith("VALUES:"): | |
values = line.strip("VALUES:").strip("\n").split(";") | |
return dict(zip(keys, values)) | |
load_data(obj, file_parser, SFF_EXTENSIONS, **kwargs) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment