Skip to content

Instantly share code, notes, and snippets.

@JacobCallahan
Last active March 6, 2020 15:09
Show Gist options
  • Save JacobCallahan/050fff8d91600c292d87f7c042ffec18 to your computer and use it in GitHub Desktop.
Save JacobCallahan/050fff8d91600c292d87f7c042ffec18 to your computer and use it in GitHub Desktop.
ridiculously small config loader. i'm not joking. this is tiny!
import inspect
import os
import yaml
from pathlib import Path
CONFIG = None
class MiniConf:
def __init__(self, **kwargs):
self._cfg_file = Path(kwargs.get("cfg_file", "."))
self._name = self._cfg_file.name.replace(self._cfg_file.suffix, "")
self._load_config()
self._pull_envars()
def _load_config(self):
with self._cfg_file.open("r+") as cfg:
try:
cfg_dict = yaml.load(cfg, Loader=yaml.FullLoader)
except:
return
for sub_import in cfg_dict.pop("_import", []):
new_conf = MiniConf.from_path(sub_import)
if isinstance(new_conf, list):
for conf in new_conf:
setattr(self, conf._name, conf)
elif isinstance(new_conf, MiniConf):
setattr(self, new_conf._name, new_conf)
self.__dict__.update(cfg_dict)
def _pull_envars(self):
if getattr(self, "_envar_prefix", ""):
for key, val in os.environ.items():
if key.startswith(self._envar_prefix):
self.__dict__[key] = val
@classmethod
def from_path(cls, conf_path):
conf_path = Path(conf_path)
if not conf_path.exists():
return
if conf_path.is_dir():
return [MiniConf.from_path(p) for p in conf_path.glob("*.mconf") if p]
if conf_path.suffix == ".mconf":
return MiniConf(cfg_file=conf_path)
if not __name__ == "__main__":
for frame in inspect.stack():
filename = getattr(frame, "filename", "")
if ".py" in filename and "miniconf.py" not in filename:
CONFIG = MiniConf.from_path(Path(filename).parent)
if isinstance(CONFIG, list):
CONFIG = [
conf
for conf in CONFIG
if not any(getattr(c, conf._name, False) for c in CONFIG)
]
CONFIG = CONFIG[0] if len(CONFIG) == 1 else CONFIG
break
@JacobCallahan
Copy link
Author

.mconf files are just yaml with two extra features (_import and _envar_prefix)

_import:
    - another.mconf
    - conf
    - sub/whatever.mconf
_envar_prefix: "PROJECT_"
key: "value"
a: 5
things:
    - 1
    - 2
    - 3

@JacobCallahan
Copy link
Author

To use it, simply do

from miniconf import CONFIG

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment