InfoScout GarlicConfig
Project description
GarlicConfig
GarlicConfig is a framework that makes it easy to deal with configurations in an easy yet flexible way. The core of this package is written in C++ and this Python package wraps the native code to provide an easy access to the configuration and some extra feature on top of it. The native library allows for quick retrieval of the configurations which can be used on any platform, this wrapper, however allows for defining advanced validation and config retrieval logic. For example, you could define your own conventions for getting localized version of configs.
The whole thing starts by defining the structure of your configs using models.
You can define models by inheriting from ConfigModel
:
from garlicconfig import models
class DatabaseConfig(models.ConfigModel):
pass
By adding attributes (or properties), you can define what this model recognizes and what format should each one of these attributes have.
For properties, you can use ConfigField
. There are a set of built-in fields:
- StringField
- IntegerField
- ArrayField
- ModelField
- BooleanField
You can also make your own custom ConfigModel
and/or ConfigField
.
for example:
from garlicconfig import fields
from garlicconfig.exceptions import ValidationError
class EvenIntegerField(IntegerField):
def validate(self, value):
if value % 2 != 0:
raise ValidationError('bad integer')
def to_model_value(self, value):
return int(value)
def to_garlic_value(self, value):
return str(value)
The field class above stores str
in the python dictionary representation. However, for the materialized config model, int
is used. It also invalidates unaccepted values by raising ValidationError
, in this case odd values.
Note that to_model_value
is responsible for converting a basic type to a more complicated python type, perhaps constructing a Python-defined class.
to_garlic_value
does the exact opposite, it should convert the value to a basic value. Basic value is defined to be one of the following types:
- str
- int
- float
- dict
- set & list
This is primarily used for ease of encoding/decoding. By default, both of these methods return the given value
without making any changes and I'd recommend not creating very complicated objects since it'll limit the accessibility of them in different platforms should you need to support them.
Next, you can define your own config model and use the custom ConfigField
we just created.
for example:
class SomeRandomConfig(ConfigModel):
value = EvenIntegerField(nullable=False, default=2)
You can use py_value
method on config models to get a python dictionary with basic value types in it. This is handy to cache it in memory, or to use it for serialization.
from_dict
will create a new config model from a python dictionary.
Furthermore, you can use garlic_value
to construct a GarlicValue
from the current config model and use from_garlic
to construct a model from a GarlicValue
.
GarlicValue
is a type that keeps configuration objects in the native code and loads them in Python lazily. This allows you to lower memory usage while speeding up all operations. It also comes with a set of handy methods:
resolve
Allows for requested a specific value by providing a dot separated path.
for example:
class ParentConfig(models.ConfigModel):
random_config_field = models.ModelField(SomeRandomConfig)
foo = ParentConfig()
foo.random_config_field.value = 8
garlic_value = foo.garlic_value()
print(garlic_value.resolve('random_config_field.value'))
In the above code, if value to the given path exists, the python representation of the value gets returned. Otherwise, None
gets returned. This is helpful because you can simply give the path to the final value and get the requested value. Since all of this is happening in the native code, it's significantly faster to use GarlicValue
over python dictionary or regular models.
Your goal should be to validate models using ConfigModel
and store/read configurations using GarlicValue
.
clone
Copy operations, specially deep copies in Python are very expensive. You can, however, clone GarlicValue
instances much faster by using the native clone which copies the object without the need to use deep copy yet accomplish the same result.
for example:
garlic_value_1 = foo.garlic_value()
garlic_value_2 = foo.clone()
Serialization
You can use the following code to encode/decode configs. The default encoder is Json. However, you can write your own encoder and support other formats as needed.
from garlicconfig import encoding
config = DatabaseConfig()
serialized_string = encoding.encode(config, pretty=True)
Merging layers
You merge two configuration layers in order to support inheritance. Something that will come very handy if you plan to use localization or multi-layered configurations.
Any GarlicValue
instance will have a apply
method that will basically applies a second GarlicValue
on top of itself.
for example:
from garlicconfig import models
from garlicconfig import fields
class ExtraConfig(models.ConfigModel):
has_id = fields.BooleanField(default=False)
has_degree = fields.BooleanField(default=False)
class DumbConfig(models.ConfigModel):
name = fields.StringField(nullable=False)
numbers = fields.ArrayField(IntegerField())
extra = models.ModelField(ExtraConfig)
def validate(self):
super(DumbConfig, self).validate()
if not self.name and not self.numbers:
raise garlicconfig.exceptions.ValidationError('invalid config for some reason!')
config_1 = DumbConfig.from_dict({
'name': 'Peyman',
'numbers': [1, 2, 3]
'extra': {
'has_id': True
}
}).garlic_value()
config_2 = DumbConfig.from_dict({
'name': 'Patrick',
'numbers': [4, 5, 6]
'extra': {
'has_degree': True
}
}).garlic_value()
config_1.apply(config_2)
config_1.resolve('numbers') # returns [4, 5, 6]
config_1.resolve('name') # returns 'Patrick'
config_1.resolve('extra.has_id') # returns True (from config_1)
config_1.resolve('extra.has_degree') # returns True (from config_2)
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distributions
File details
Details for the file garlicconfig-1.2.6-cp39-cp39-macosx_12_0_x86_64.whl
.
File metadata
- Download URL: garlicconfig-1.2.6-cp39-cp39-macosx_12_0_x86_64.whl
- Upload date:
- Size: 452.4 kB
- Tags: CPython 3.9, macOS 12.0+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.9.13
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | cc96f3e516153b4d512e7920676c61f4e2e050efa2cd9bd831e146c9d84bd70e |
|
MD5 | 13d29c670711e4589cfe62f82d955f5c |
|
BLAKE2b-256 | e5c485c3c8f35a6dc4f3d794466f23b1c144cccf1e0340788c77059c83e99c78 |
File details
Details for the file garlicconfig-1.2.6-cp37-cp37m-win_amd64.whl
.
File metadata
- Download URL: garlicconfig-1.2.6-cp37-cp37m-win_amd64.whl
- Upload date:
- Size: 430.8 kB
- Tags: CPython 3.7m, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.7.5
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 994e52b113c5286f57ed71e187ec784159c3f5f3db159cf84d2f2cef6690c569 |
|
MD5 | e20e41142bdefc1ce9406e020a408c72 |
|
BLAKE2b-256 | 277069713326377045f5bcb54f976f1ac5d0672fa86e293c4884f72c36f41995 |
File details
Details for the file garlicconfig-1.2.6-cp36-cp36m-win_amd64.whl
.
File metadata
- Download URL: garlicconfig-1.2.6-cp36-cp36m-win_amd64.whl
- Upload date:
- Size: 453.4 kB
- Tags: CPython 3.6m, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.8.0 pkginfo/1.9.6 readme-renderer/34.0 requests/2.27.1 requests-toolbelt/0.10.1 urllib3/1.26.14 tqdm/4.64.1 importlib-metadata/4.8.3 keyring/23.4.1 rfc3986/1.5.0 colorama/0.4.5 CPython/3.6.8
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | e7a78f2d742417b7285d6877ccca06641d803ab7f5fc9b333dc5122d6adba34b |
|
MD5 | 517b4610dffb65aa6b5f84cfc44cce3f |
|
BLAKE2b-256 | b37205184b84aca181429eaa8b9cf6bad263df2c959edcbda792bff4dddeff49 |
File details
Details for the file garlicconfig-1.2.6-cp36-cp36m-manylinux_2_24_x86_64.whl
.
File metadata
- Download URL: garlicconfig-1.2.6-cp36-cp36m-manylinux_2_24_x86_64.whl
- Upload date:
- Size: 1.4 MB
- Tags: CPython 3.6m, manylinux: glibc 2.24+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.8.0 pkginfo/1.9.6 readme-renderer/34.0 requests/2.27.1 requests-toolbelt/0.10.1 urllib3/1.26.14 tqdm/4.64.1 importlib-metadata/4.8.3 keyring/23.4.1 rfc3986/1.5.0 colorama/0.4.5 CPython/3.6.8
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 5ab6231143ab4652acd1ccfa510739a3ece0fb3ed29a941476e071f55b3dd535 |
|
MD5 | 2cbeb9510fe2163f2f693041f27a76d1 |
|
BLAKE2b-256 | d5de57a99a0dd7e5d37405fe7c3c2c2ef6094b652c5d3d6cfe3fea26867a8886 |