Loading configs in Python

Motivation

  • The loading nested configurations can be difficult.
  • Pythons yaml loader does not deal with it nicely.
  • loading as dict -> key access, dot access would be nicer.
  • many dependencies otherwise (Hydra, OmegaConf, …)

Simple solution for loading.

  • No external dependencies.
  • Allows dot access.
  • Allows the use of safe_load.
    • yaml.load poses security risks -> Loads arbitrary code.

Possible extensions:

  • Add Pydantic for convenient validation of configs.
  • Add typing.
import yaml 
import json
from types import SimpleNamespace

def load_object(dct):
    return SimpleNamespace(**dct)

def load_config(path):
    """
    Loads the configuration yaml and parses it into an object with dot access.
    """
    with open(path, encoding="utf-8") as stream:
        # Load dict
        config_dict = yaml.safe_load(stream)

        # Convert to namespace (access via config.data etc)
        config = json.loads(json.dumps(config_dict), object_hook=load_object)
    return config, config_dict

For typing one can use the following construction:

from dataclasses import dataclass

@dataclass
class MyModelConfig: 
	module: models.mymodel
	hidden_size: int 



class MyModel: 
	def __init__(self, config: MyModelConfig):
		# Model def goes here.
		# Typing allows autocomplete.
		pass 
	
	...

References in yaml

  • Yaml allows for references
  • Avoids duplicates.
  • Great when configs need to be passed to multiple modules
    • Data and model for instance.
  experimentconfig: &id-exp
  name: MyCoolExperiment

model: 
  module: models.mymodel
  hidden_size: 10 
  expconfig: *id-exp

data: 
  module: data.mydata
  root: ./data 
  expconfig: *id-exp

Saving configs

  • tbd

← Back to Wiki