confcls


Nameconfcls JSON
Version 1.0.0 PyPI version JSON
download
home_pageNone
SummaryClass instance configurator
upload_time2024-05-14 18:01:15
maintainerNone
docs_urlNone
authorVáclav Krpec
requires_python<4.0,>=3.9
licenseNone
keywords config configuration
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Class Instance Configurator

A simple configuration library allowing instantiation of classes from config. files.

Configuration files are in JSON format and simply specify the type of the created object
and keyword arguments for its construction.
The library also supports free-form config. objects for which respective dataclass-like
types are automatically created from a meta-class (so that the programmer doesn’t even
have to declare them).

Support for remote config. is provided by (optional) use of `smart-open`.

## Examples

### Instantiation of a class from config. file

Assuming you have the following general class:

**my\_module.py**

    from confcls import Configurable

    class MyClass(Configurable):
        def __init__(self, arg1: str, arg2: int, arg3: list[str], arg4: dict[str, float]):
            self.foo = arg1
            self.bar = arg2
            self.baz = [arg4[name] for name in arg3 if name in arg4]

You can now store its instance configuration in a JSON file:

**my\_obj.json**

    {
        "__type__" : "my_module.MyClass",
        "arg1" : "Hello world!",
        "arg2" : 123,
        "arg3" : ["abc", "ghi"],
        "arg4" : {
            "abc" : 0.123,
            "def" : 0.987
        }
    }

And instantiate the configured instance, thus:

    from my_module import MyClass

    my_obj = MyClass.from_config("my_obj.json")

(You may also call `confcls.Configurable.from_config` directly if you don’t wish
to specify and/or import the type.)

The instantiation does support nesting; your constructor arguments may indeed be other
class instances:

**my\_obj.json**

    {
        "__type__" : "my_module.Class1",
        "foo" : 123,
        "bar" : {
            "__type__" : "my_module.Class2",
            "arg1" : 345,
            "arg2" : "whatever"
        },
        "baz" : {
            "__type__" : "my_module.Class3",
            "arg" : {
                "__type__" : "my_module.Class2",
                "arg1" : 567,
                "arg2" : "something else"
            }
        }
    }

The above configuration instantiates the same object as the following code:

    my_obj = Class1(
        foo=123,
        bar=Class2(arg1=345, arg2="whatever"),
        baz=Class3(arg=Class2(arg1=567, arg2="something else)),
    )

### Dataclass config

You may want to create a (nested) dataclass configuration.
The principle is exactly the same as above; you simply define your configuration
data classes and instantiate them from configuration:

**my\_config.py**

    from dataclasses import dataclass
    from confcls import Configurable

    @dataclass
    class Configuration(Configurable):
        number: int
        fpnum: float = 0.0  # number with default
        item1: Item1
        opt_item2: Item2 = None  # optional instance

    @dataclass
    class Item1:  # note that nested dataclasses don't even need to be Configurable
        foo: int
        bar: float = 1.0

    @dataclass Item2:
        baz: str

Now, your configuration may look like this:

    {
        "__type__" : "my_config.Configuration",
        "number" : 123,
        "item1" : {
            "__type__" : "my_config.Item1",
            "foo" : 345,
            "bar" : 0.5
        }
    }

### Automatic dataclass-like instances

If you’re very lazy, you don’t even have to declare your config. dataclasses.
Just let `confcls` create the types for you, on demand:

**my\_config.json**

    {
        "__type__" : "confcls.Configuration",
        "myarg1" : "whatever you like",
        "myarg2" : {
            "__type__" : "confcls.Object",
            "absolutely" : "anything",
            "really" : 123
        }
    }

`confcls.Object` is a free-form class which can be instantiated with any keyword
arguments (and the instance contains them as members).
So now, you can access your configuration e.g. like this:

    from confcls import Configuration  # Configurable extension of confcls.Object

    config = Configuration.from_config("my_config.json")
    assert config.myarg2.absolutely == "anything"

Note that this sort of configuration doesn’t support defaults as there’s nowhere
to define them (if you want defaults, just declare your (data)classes with them).
Also note that you may combine the declared/free-form approaches (if it makes sense).

Finally, observe that the `Configurable.from_config` member function has `auto_obj`
parameter (with `False` default).
Setting that parameter to `True` allows you to omit the `type` specification
in your configuration.
In that case, the library will automatically treat all JSON objects in the config.
file as if the `confcls.Object` type was specified.

## Development

To develop `confcls`, you shall need make, pyenv and poetry installed.
Then, setup and initialise your development environment:

    $ make setup
    $ make init

To run mypy type checks, unit tests, and the linter use the `mypy`, `test` and `lint`
make targets, respectively.
Alternatively, use the `check` target to do all that.

    $ make check

The Python package is built by the `build` target.
The package may be published using the `publish` target.

    $ make build
    $ make publish

## Author

Václav Krpec &lt;<vencik@razdva.cz>&gt;


            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "confcls",
    "maintainer": null,
    "docs_url": null,
    "requires_python": "<4.0,>=3.9",
    "maintainer_email": null,
    "keywords": "config, configuration",
    "author": "V\u00e1clav Krpec",
    "author_email": "vencik@razdva.cz",
    "download_url": "https://files.pythonhosted.org/packages/ac/19/f15542355dd6f9fb962cd1d151dcb71d1876de1618260736f8e8edd3a9be/confcls-1.0.0.tar.gz",
    "platform": null,
    "description": "# Class Instance Configurator\n\nA simple configuration library allowing instantiation of classes from config. files.\n\nConfiguration files are in JSON format and simply specify the type of the created object\nand keyword arguments for its construction.\nThe library also supports free-form config. objects for which respective dataclass-like\ntypes are automatically created from a meta-class (so that the programmer doesn\u2019t even\nhave to declare them).\n\nSupport for remote config. is provided by (optional) use of `smart-open`.\n\n## Examples\n\n### Instantiation of a class from config. file\n\nAssuming you have the following general class:\n\n**my\\_module.py**\n\n    from confcls import Configurable\n\n    class MyClass(Configurable):\n        def __init__(self, arg1: str, arg2: int, arg3: list[str], arg4: dict[str, float]):\n            self.foo = arg1\n            self.bar = arg2\n            self.baz = [arg4[name] for name in arg3 if name in arg4]\n\nYou can now store its instance configuration in a JSON file:\n\n**my\\_obj.json**\n\n    {\n        \"__type__\" : \"my_module.MyClass\",\n        \"arg1\" : \"Hello world!\",\n        \"arg2\" : 123,\n        \"arg3\" : [\"abc\", \"ghi\"],\n        \"arg4\" : {\n            \"abc\" : 0.123,\n            \"def\" : 0.987\n        }\n    }\n\nAnd instantiate the configured instance, thus:\n\n    from my_module import MyClass\n\n    my_obj = MyClass.from_config(\"my_obj.json\")\n\n(You may also call `confcls.Configurable.from_config` directly if you don\u2019t wish\nto specify and/or import the type.)\n\nThe instantiation does support nesting; your constructor arguments may indeed be other\nclass instances:\n\n**my\\_obj.json**\n\n    {\n        \"__type__\" : \"my_module.Class1\",\n        \"foo\" : 123,\n        \"bar\" : {\n            \"__type__\" : \"my_module.Class2\",\n            \"arg1\" : 345,\n            \"arg2\" : \"whatever\"\n        },\n        \"baz\" : {\n            \"__type__\" : \"my_module.Class3\",\n            \"arg\" : {\n                \"__type__\" : \"my_module.Class2\",\n                \"arg1\" : 567,\n                \"arg2\" : \"something else\"\n            }\n        }\n    }\n\nThe above configuration instantiates the same object as the following code:\n\n    my_obj = Class1(\n        foo=123,\n        bar=Class2(arg1=345, arg2=\"whatever\"),\n        baz=Class3(arg=Class2(arg1=567, arg2=\"something else)),\n    )\n\n### Dataclass config\n\nYou may want to create a (nested) dataclass configuration.\nThe principle is exactly the same as above; you simply define your configuration\ndata classes and instantiate them from configuration:\n\n**my\\_config.py**\n\n    from dataclasses import dataclass\n    from confcls import Configurable\n\n    @dataclass\n    class Configuration(Configurable):\n        number: int\n        fpnum: float = 0.0  # number with default\n        item1: Item1\n        opt_item2: Item2 = None  # optional instance\n\n    @dataclass\n    class Item1:  # note that nested dataclasses don't even need to be Configurable\n        foo: int\n        bar: float = 1.0\n\n    @dataclass Item2:\n        baz: str\n\nNow, your configuration may look like this:\n\n    {\n        \"__type__\" : \"my_config.Configuration\",\n        \"number\" : 123,\n        \"item1\" : {\n            \"__type__\" : \"my_config.Item1\",\n            \"foo\" : 345,\n            \"bar\" : 0.5\n        }\n    }\n\n### Automatic dataclass-like instances\n\nIf you\u2019re very lazy, you don\u2019t even have to declare your config. dataclasses.\nJust let `confcls` create the types for you, on demand:\n\n**my\\_config.json**\n\n    {\n        \"__type__\" : \"confcls.Configuration\",\n        \"myarg1\" : \"whatever you like\",\n        \"myarg2\" : {\n            \"__type__\" : \"confcls.Object\",\n            \"absolutely\" : \"anything\",\n            \"really\" : 123\n        }\n    }\n\n`confcls.Object` is a free-form class which can be instantiated with any keyword\narguments (and the instance contains them as members).\nSo now, you can access your configuration e.g. like this:\n\n    from confcls import Configuration  # Configurable extension of confcls.Object\n\n    config = Configuration.from_config(\"my_config.json\")\n    assert config.myarg2.absolutely == \"anything\"\n\nNote that this sort of configuration doesn\u2019t support defaults as there\u2019s nowhere\nto define them (if you want defaults, just declare your (data)classes with them).\nAlso note that you may combine the declared/free-form approaches (if it makes sense).\n\nFinally, observe that the `Configurable.from_config` member function has `auto_obj`\nparameter (with `False` default).\nSetting that parameter to `True` allows you to omit the `type` specification\nin your configuration.\nIn that case, the library will automatically treat all JSON objects in the config.\nfile as if the `confcls.Object` type was specified.\n\n## Development\n\nTo develop `confcls`, you shall need make, pyenv and poetry installed.\nThen, setup and initialise your development environment:\n\n    $ make setup\n    $ make init\n\nTo run mypy type checks, unit tests, and the linter use the `mypy`, `test` and `lint`\nmake targets, respectively.\nAlternatively, use the `check` target to do all that.\n\n    $ make check\n\nThe Python package is built by the `build` target.\nThe package may be published using the `publish` target.\n\n    $ make build\n    $ make publish\n\n## Author\n\nV\u00e1clav Krpec &lt;<vencik@razdva.cz>&gt;\n\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "Class instance configurator",
    "version": "1.0.0",
    "project_urls": {
        "Homepage": "https://github.com/vencik/confcls",
        "Repository": "https://github.com/vencik/confcls"
    },
    "split_keywords": [
        "config",
        " configuration"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "f75b8fd4bdd59698dc1f1949147c6cb51bba2b24a4bb703fa5f7d67e4639e3ea",
                "md5": "2c84c4275858603f4f3dd75cea14be4c",
                "sha256": "11bebd45c67c81f2b1ca905b1ae5df99bdbf75a2ba80d6f21fdaa520a3cd78a9"
            },
            "downloads": -1,
            "filename": "confcls-1.0.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "2c84c4275858603f4f3dd75cea14be4c",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": "<4.0,>=3.9",
            "size": 5792,
            "upload_time": "2024-05-14T18:01:13",
            "upload_time_iso_8601": "2024-05-14T18:01:13.212080Z",
            "url": "https://files.pythonhosted.org/packages/f7/5b/8fd4bdd59698dc1f1949147c6cb51bba2b24a4bb703fa5f7d67e4639e3ea/confcls-1.0.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "ac19f15542355dd6f9fb962cd1d151dcb71d1876de1618260736f8e8edd3a9be",
                "md5": "f1127553f06d901d924a7cbb44a0abe3",
                "sha256": "7fa8b83b26eb38403cf60257d1d8468534bee4d974cc3e8384f9aee72c70a3f1"
            },
            "downloads": -1,
            "filename": "confcls-1.0.0.tar.gz",
            "has_sig": false,
            "md5_digest": "f1127553f06d901d924a7cbb44a0abe3",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": "<4.0,>=3.9",
            "size": 5939,
            "upload_time": "2024-05-14T18:01:15",
            "upload_time_iso_8601": "2024-05-14T18:01:15.260231Z",
            "url": "https://files.pythonhosted.org/packages/ac/19/f15542355dd6f9fb962cd1d151dcb71d1876de1618260736f8e8edd3a9be/confcls-1.0.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-05-14 18:01:15",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "vencik",
    "github_project": "confcls",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "confcls"
}
        
Elapsed time: 0.30012s