Skip to main content

Description

Python object configuration library in reflective and distributed concerns.

License Development Status Latest release Supported Python versions Supported Python implementations Download format Build status Code test coverage Downloads Documentation Status Code Health

Installation

pip install b3j0f.conf

Features

This library provides a set of object configuration tools in order to ease development of systems based on configuration resources such as files, DB documents, etc. in a reflexive, functional and distributed context.

Configuration processing is done is in 5 steps with only two mandatories:

  1. optional : configuration model specification. You define which parameters you want to setup (default value, type, etc.).

  2. optional : configuration driver selection. You define the nature of configuration resources (xml, json, ini, etc.).

  3. mandatory : configuration resource edition. You define your configuration resources (files, DB documents, etc.).

  4. optional : bind a configurable to python object(s). You bind a configurable to objects to setup for a reflexive use.

  5. mandatory : apply configuration to a python object. You setup your python objects.

In order to improve reflexive concerns, this library has been developed with very strong flexible features available at runtime.

It is possible to custom every parts directly at runtime with high speed execution concerns.

You can customize:

  • parsing functions.

  • drivers.

  • configuration process.

  • configuration meta-model.

Configuration

The package b3j0f.conf.model provides Configuration class in order to inject configuration resources in a configurable class.

Configuration resources respect two levels of configuration same as the ini configuration model. Both levels are respectively:

  • Category: permits to define a set of parameters unique by name.

  • Parameter: couple of property name and value.

And all categories/parameters are embedded in a Configuration class.

Configuration and Categories are ordered dictionaries where key values are inner element names. Therefore, Parameter names are unique per Categories, and Category/Parameter names are unique per Configuration.

Parameter Overriding

In a dynamic and flexible way, one Configurable class can be bound to several Categories and Parameters. The choice is predetermined by the class itself. That means that one Configurable class can use several configuration resources and all/some/none Categories/Parameters in those resources. In such a way, the order is important because it permits to keep only last parameter values when parameters have the same name.

This overriding is respected by default with Configurable class inheritance. That means a sub class which adds a resource after its parent class resources indicates than all parameters in the final resources will override parameters in the parent class resources where names are the sames.

Name such as a regular expression

Even if a parameter uses a name, it is possible to use this name such as a regular expression name.

In this case, while reading a configuration from a resource, all configuration parameters which match the regular expression will use the same attributes as defined in the parameter with the regular expression. And a name which is the name from the configuration resource.

Parser

The package b3j0f.conf.parser provides parsers used to deserialize parameter values.

All parsers use special entries such as:

  • %(lang:)expr%: string value of a programming language expression. lang is the target language (default is python) and expr is the expression to evaluate. For example, %"testy"[:-1]% equals test.

  • @((rpath/)cname.)[history]pname: reference to another parameter value (thanks to the idea from the pypi config project) where:

    • rpath: optional resource path.

    • cname: optional category name.

    • history: optional parameter history in the arborescence from the (current) category. If not given, last parameter value is given.

    • pname: parameter name.

    For example: @test designates the final value of the parameter test. @myconf.json/test is the parameter test from the resource myconf.json. @mycat...test is the parameter test defined two categories before the category mycat.

If the parameter configuration value is of the format =(lang:)expr, the result is an evaluation of expr in the given language lang. For example, =2 equals the integer 2. =sys.maxsize is the maxsize value from the sys module (thanks to the best effort property).

Finally, here are reserved keywords in an evaluated expression:

  • conf: current configuration.

  • configurable: current configurable.

Configurable

A Configurable class is provided in the b3j0f.conf.configurable.core module. It permits to get parameters from configuration resources and setup them to a python object or in a method/function parameters.

It inherits from the b3j0f.annotation.Annotation class (annotation). That means it can be used such as an annotation (decorator with annotation functions). For example, bound Configurables to an object o are retrieved like this: Configurable.get_annotations(o).

In order to perform a configuration setup, it uses:

  • conf: configuration model.

  • drivers: configuration resource drivers.

  • scope: parsing execution scope.

  • besteffort: boolean flag which aims to resolve automatically absolute object path. True by default.

  • safe: boolean flag which aims to cancel calls to I/O functions. True by default.

  • logger: logger which will handle all warning/error messages. None by default.

Annotated elements are bound and can all be (re)configured once in using the method applyconfiguration.

Driver

Drivers are the mean to parse configuration resources, such as files, DB documents, etc. from a configuration model provided by a Configurable object.

By default, conf drivers are able to parse json/ini/xml files. Those last use a relative path given by the environment variable B3J0F_CONF_DIR or from directories (in this order) /etc, /usr/local/etc, ~/etc, ~/.config, ~/config, current execution directory or absolute path.

Example

Bind configuration files to an object

Bind the configuration file ~/etc/myobject.conf and ~/.config/myobject.conf to a business class MyObject (the relative path ~/etc can be changed thanks to the environment variable B3J0F_CONF_DIR).

The configuration file contains a category named MYOBJECT containing the parameters:

  • myattr equals 'myvalue'.

  • six equals 6.

  • twelve equals six * 2.0.

Let the following configuration file ~/etc/myobject.conf in ini format:

[MYOBJECT]
myattr = myvalue
twelve = =@six * 2.0

Let the following configuration file ~/.config/myobject.conf in json format:

{
  "MYOBJECT": {
    "six": 6
  }
}

The following code permits to load upper configuration to a python object.

from b3j0f.conf import Configurable

# instantiate a business class
@Configurable(paths='myobject.conf')
class MyObject(object):
    pass

myobject = MyObject()

# assert attributes
assert myobject.myattr == 'myvalue'
assert myobject.six == 6
assert isinstance(myobject.six, int)
assert myobject.twelve == 12
assert isinstance(myobject.twelve, float)

The following code permits to load upper configuration to a python function.

from b3j0f.conf import Parameter, Array

# instantiate a business class and ensure twelve is converted into an integer and a string with commas is converted into an array of integers.
@Configurable(
  paths='myobject.conf',
  conf=[
    Parameter('default', value=len('default')),  # default value for the parameter default
    Parameter('twelve', ptype=int),
    Parameter('integers', svalue='1,2,3', ptype=Array(int))
)
def myfunc(myattr=None, six=None, twelve=None, default=None):  # Only None values will be setted by the configuration
    return myattr, six, twelve, default

myattr, six, twelve, default = myfunc(twelve=46)

# assert attributes
assert myobject.default == 7
assert myobject.myattr == 'myvalue'
assert myobject.six == 6
assert myobject.twelve == 46
assert isinstance(myobject.twelve, int)
assert myobject.integers == [1, 2, 3]

Class configuration

from b3j0f.conf import category
from b3j0f.conf import Configurable

# class configuration
@Configurable(conf=category('land', Parameter('country', value='fr')))
class World(object):
    pass

world = World()
assert world.country == 'fr'

One configuration with several objects

land = Configurable.get_annotations(world)[0]  # class method for retrieving Configurables

@land  # bind land to World2
class World2(object):
    pass

world2 = World2()

assert World2().country == 'fr'

class World3(object):
    pass

world3 = World3()
land.applyconfiguration([world3])  # apply land on world3 without annotated it

assert world3.country == 'fr'

world3s = (land(World3()) for _ in range(5))  # annotate a set of worlds

land.conf['land']['country'] = 'en'  # change default country code

land.applyconfiguration()  # update all annotated objects

for _world3 in world3s:
    assert _world3.country == 'en'

assert world2.country == 'en'

assert world3.country == 'fr'  # check not annotated element has not changed

Configure object constructor

land.autoconf = False  # disable autoconf

@land
class World4(object):
    def __init__(self, country=None):
        self.safecountry = country

world4 = World4()

assert not hasattr(world4, 'country')  # disabled auto conf side effect
assert world4.safecountry = 'en'

land.applyconfiguration()  # configure all land targets

assert world4.country == 'en'

Configure function parameters

@land
def getcountry(country=None):
    print(country)
    return country

assert getcountry() == 'en'

land['land']['country'] = 'fr'

assert getcountry() == 'fr'

Configure embedded objects

from b3j0f.conf import configuration, category, Parameter

class SubTest(object):
    pass

@Configurable(
    conf=(
        configuration(
            category('', Parameter('subtest', value=SubTest)),
# the prefix ':' refers (recursively) to a sub configuration for the parameter named with the suffix after ':'
            category(':subtest', Parameter('subsubtest', value=SubTest)),
            category(':subtset:subsubtest', Parameter('test', value=True))
        )
    )
)
class Test(object):
    pass

test = Test()

assert isinstance(test.subtest, SubTest)
assert isinstance(test.subtest.subsubtest)
assert not hasattr(test.subtest, 'test')
assert test.subtest.subsubtest.test is True

# and you can still apply configuration
Configurable.get_annotations(test)[0].conf[':subtset:subsubtest']['test'] = False
applyconfiguration(targets=[test])

assert test.subtest.subsubtest.test is False

Configure metaclasses

from six import add_metaclass

@Configurable(conf=Parameter('test', value=True))
class MetaTest(type):
    pass

@add_metaclass(MetaTest)
class Test(object):
    pass

test = Test()

assert test.test is True

Perspectives

  • wait feedbacks during 6 months before passing it to a stable version.

  • Cython implementation.

  • add GUI in order to ease management of multi resources and categorized parameters.

Donation

I'm grateful for gifts, but don't have a specific funding goal.

Metadata

Release files for b3j0f.conf 0.3.22

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distributions (sdists)

Source distribution for b3j0f.conf 0.3.22
File Size Uploaded Provenance
b3j0f.conf-0.3.22.zip 101.2 kB Without provenance Details
b3j0f.conf-0.3.22.tar.gz 47.1 kB Without provenance Details
b3j0f.conf-0.3.22.tar.bz2 38.8 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for b3j0f.conf 0.3.22
File Interpreter ABI Platform
b3j0f.conf-0.3.22-py2.py3-none-any.whl Python 3, Python 2 none any Details

Total release size: 278.8 kB

Release files / b3j0f.conf-0.3.22.zip

Download URL b3j0f.conf-0.3.22.zip
Size 101.2 kB
Tags Source
SHA-256 checksum
How to use checksums
40c9a36f3e440af3cd160ade014f3a3273705c56ad15f081cc5444aa5183ecd8
BLAKE2b-256 checksum
How to use checksums
d3807f370961e383ba613cc88e567737ef36fece3f5f25d0011d16110af5ed5f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No

Release files / b3j0f.conf-0.3.22.tar.gz

Download URL b3j0f.conf-0.3.22.tar.gz
Size 47.1 kB
Tags Source
SHA-256 checksum
How to use checksums
884353e074252de28641125ecceb1ca472cdc6a6790282f3456cbb398d1012e4
BLAKE2b-256 checksum
How to use checksums
d4c9dc30e7ff7359b394fdda9c397961e8994cbe4a11596cc567316a85747e6e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No

Release files / b3j0f.conf-0.3.22.tar.bz2

Download URL b3j0f.conf-0.3.22.tar.bz2
Size 38.8 kB
Tags Source
SHA-256 checksum
How to use checksums
bfa66faef29eb25de6bf335d36cb22ef5963151823f19921e2c399734e615f8b
BLAKE2b-256 checksum
How to use checksums
10584e04a5adce695b96b67c96a53dcf8946250942800bb8cc6edb2f6266a28f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No

Release files / b3j0f.conf-0.3.22-py2.py3-none-any.whl

Download URL b3j0f.conf-0.3.22-py2.py3-none-any.whl
Size 91.7 kB
Tags Python 2 Python 3
SHA-256 checksum
How to use checksums
db792e5f65439bb7545a2c94d4acb88bd9e45518f2c9e4c10c82f144fd24ce80
BLAKE2b-256 checksum
How to use checksums
7159a06e57afa8108e5a4f14b05cf2b725358d98f0b4f905a96dc0a8cb6cf013
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No

Security for b3j0f.conf 0.3.22

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Release history Release notifications | RSS feed

This release

0.3.22 This release

4 release files No provenance

0.1

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page