Glorpen Config¶
Config framework for Your projects - with validation, interpolation and value normalization. It can even generate default config with help texts!
Official repositories¶
GitHub: https://github.com/glorpen/glorpen-config
BitBucket: https://bitbucket.org/glorpen/glorpen-config
Features¶
You can:
- define configuration schema inside Python app
- convert configuration values to Python objects
- validate user provided data
- use interpolation to fill config values
- generate example configuration with help text
How to load data¶
You can use Reader
to read values from arbitrary source and then pass it to glorpen.config.Config
:
from glorpen.config.translators.yaml import YamlReader
from glorpen.config import Config
config = Config(String())
config.get(YamlReader("example.yaml").read())
or with use of glorpen.config.Translator
:
from glorpen.config.translators.yaml import YamlReader
from glorpen.config import Config, Translator
translator = Translator(Config(String()))
translator.read(YamlReader("example.yaml"))
glorpen.config.Config.get()
accepts anything that is supported by underlying config schema so you can pass dict
or custom objects.
Interpolation¶
You can reuse values from config with dotted notation, eg: {{ path.to.value }}
.
project:
path: "/tmp"
cache_path: "{{ project.path }}/cache"
See field documentation to find where interpolation is supported.
Normalization and validation¶
Each field type has own normalization rules, eg. for glorpen.config.fields.log.LogLevel
:
logging: DEBUG
config.get(data)
would yield value 10
as in logging.DEBUG
.
Additionally it will raise exception if invalid value is provided.
Optional and default values¶
Each field can have default value. If no value is given in config but default one is set, it will be used instead.
Default values should be already Python values, eg. int
, str
, objects.
Contents¶
Example usage¶
Using fields¶
Your first step should be defining configuration schema:
import logging
import glorpen.config.fields.simple as f
from glorpen.config.fields.log import LogLevel
project_path = "/tmp/project"
spec = f.Dict({
"project_path": f.Path(default=project_path),
"project_cache_path": f.Path(default="{{ project_path }}/cache"),
"logging": fl.LogLevel(default=logging.INFO),
"database": f.String(),
"sources": f.Dict({
"some_param": f.String(),
"some_path": f.Path(),
}),
"maybe_string": f.Variant([
f.String(),
f.Number()
])
})
Example yaml config:
logging: "DEBUG"
database: "mysql://...."
sources:
some_param: "some param"
some_path: "/tmp"
maybe_string: 12
Then you can create glorpen.config.Config
instance:
from glorpen.config import Config
import glorpen.config.loaders as loaders
loader = loaders.YamlLoader(filepath=config_path)
cfg = Config(loader=loader, spec=spec).finalize()
cfg.get("sources.some_param") #=> 'some param'
cfg.get("project_path") #=> '/tmp/project'
cfg.get("project_cache_path") #=> '/tmp/project/cache'
cfg.get("logging") #=> 10
cfg.get("maybe_string") #=> 12
Creating custom fields¶
Custom field class should extend glorpen.config.fields.base.Field
or glorpen.config.fields.base.FieldWithDefault
.
glorpen.config.fields.base.Field.make_resolvable()
method should register normalizer functions which later will be called in registration order.
Each value returned by normalizer is passed to next one. After chain end value is returned as config value.
Returned glorpen.config.fields.base.ResolvableObject
instance is resolved before passing it to next normalizer.
If value passed to normalizator is invalid it should raise glorpen.config.exceptions.ValidationError
.
Sometimes value can be lazy loaded - it is represented as glorpen.config.fields.base.ResolvableObject
.
You can get real value by using glorpen.config.fields.base.resolve()
.
class MyValue(object):
def __init__(self, value):
super(MyValue, self).__init__()
self.value = value
class MyField(Field):
def to_my_value(self, value, config):
return MyValue(value)
def is_value_supported(self, value):
return True
def make_resolvable(self, r):
r.on_resolve(self.to_my_value)
The last thing is to use prepared custom field in configuration spec.
glorpen.config
API Documentation¶
glorpen.config
¶
-
glorpen.config.
__version__
¶ Current package version.
glorpen.config.fields.base
¶
-
class
glorpen.config.fields.base.
Field
(validators=None)[source]¶ Single field in configuration file.
Custom fields should implement own normalizer/interpolation by overriding corresponding methods.
To add custom validation based on whole config object use
validator()
.
glorpen.config.fields.simple
¶
-
class
glorpen.config.fields.simple.
Dict
(schema=None, keys=None, values=None, check_keys=False, **kwargs)[source]¶ Converts values to
collections.OrderedDict
Supports setting whole schema (specific keys and specific values) or just keys type and values type.
Keys can be interpolated if
keys
param supports it.
-
class
glorpen.config.fields.simple.
List
(schema, check_values=False, **kwargs)[source]¶ Converts value to list.
-
class
glorpen.config.fields.simple.
Path
(*args, split_by='.', left_char='{', right_char='}', **kwargs)[source]¶ Converts given value to disk path.
-
class
glorpen.config.fields.simple.
PathObj
(*args, split_by='.', left_char='{', right_char='}', **kwargs)[source]¶ Converts value to
pathlib.Path
object.
-
class
glorpen.config.fields.simple.
String
(*args, split_by='.', left_char='{', right_char='}', **kwargs)[source]¶ Converts value to string.
-
class
glorpen.config.fields.simple.
Variant
(schema, *args, **kwargs)[source]¶ Converts value to normalized state using one
Field
chosen from multiple provided.To allow blank values you have to pass child field with enabled blank values. First field which supports value (
Field.is_value_supported()
) will be used to convert it.