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.