Easy access to ~/.config
.
Simply run pip3 install --upgrade xdgconfig
.
By default, xdgconfig
only supports JSON as its serializer, but you can install support for
other serializers by specifiying the format in square brackets, i.e. pip3 install xdgconfig[xml]
.
The following are available:
jsonc
: JSON, with commentsini
: INI filesxml
: eXtensible Markup Language filestoml
: Tom's Markup language filesyaml
: YAML Ain't Markup Language filesFurthermore there is an all
recipe to install support for every markup supported,
and you can combine them by using a +
between 2 targets, i.e. pip3 install xdgconfig[xml+toml]
Simply clone this repo and run python3 setup.py install
.
Config
objects use a shared single reference.dict
-like interfaceConfig
object./etc/prog/config
, then in ~/.config/prog/config
PROG_CONFIG_PATH
config.key
for instance). See limitations for guidance.from xdgconfig import JsonConfig
# Instanciate the JsonConfig object
# If you'd rather use a different format, there also are config classes
# for TOML, YAML, INI (configparser), and XML.
# This will save your configuration under `~/.config/PROG/config
config = JsonConfig('PROG', autosave=True)
config['foo'] = 'bar' # Save a value to the config
# Access the value later on
print(config['foo'])
# It behaves like a collections.defaultdict as well
config['oof']['bar'] = 'baz'
# Prints {'oof': {'bar': 'baz'}, 'foo': 'bar'}
print(config)
You can add custom serializers support by using a Mixin class, as well as
a serializer class which must have a dumps
and a loads
method, which will
be used to store and load data from the config file. The data is always
represented as a python dict
object, but you can serialize any data you want
inside of it.
Look at the following example for an implementation guide.
from typing import Any, Dict
from xdgconfig import Config
class MySerializer:
def dumps(data: Dict[str, Any]) -> str:
return '\n'.join(f'{k}:{v}' for k, v in data.items())
def loads(contents: str) -> Dict[str, Any]:
return dict(s.split(':') for s in contents.split('\n'))
class MySerializerMixin:
_SERIALIZER = MySerializer
class MyConfig(MySerializerMixin, Config):
...
You can set default values by creating a Mixin
class with a _DEFAULTS
class attribute, such as :
from pathlib import Path
from pprint import pprint
from xdgconfig import JsonConfig
class DefaultConfig:
_DEFAULTS = {
'logger.level': 'info',
'logger.verbosity': 3,
'app.path': str(Path.cwd()),
'app.credentials.username': 'user',
'app.credentials.password': 'password',
}
class Config(DefaultConfig, JsonConfig):
...
config = Config('PROG', 'config.json')
pprint(config)
# Prints the following dict :
# {
# 'logger': {
# 'level': 'info',
# 'verbosity': 3
# },
# 'app': {
# 'path': '$CWD',
# 'credentials': {
# 'username': 'user',
# 'password': 'password'
# }
# }
# }
IniConfig
object prevents you from using periods (.
) in key names, as they are separators for subdicts.Config
object all start with a leading underscore (_
), hence, using key names with the same convention is discouraged, as it could break the object due to the way dot (.
) accessing works. The only exception is the save
method, which doesn't start with a leading underscore.