svarog


Namesvarog JSON
Version 0.3.1 PyPI version JSON
download
home_pagehttps://gitlab.com/dswistowski/svarog/
SummarySvarog allow to create object from non typed data
upload_time2023-02-02 14:52:58
maintainer
docs_urlNone
authorDamian Świstowski
requires_python>=3.8,<4.0
licenseMIT
keywords svarog json structure typing
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            ======
Svarog
======


.. image:: https://img.shields.io/pypi/v/svarog.svg
        :target: https://pypi.python.org/pypi/svarog

.. image:: https://github.com/dswistowski/svarog/actions/workflows/tests.yml/badge.svg
        :target: https://github.com/dswistowski/svarog/actions/workflows/tests.yml

.. image:: https://readthedocs.org/projects/svarog/badge/?version=latest
        :target: https://svarog.readthedocs.io/en/latest/?badge=latest
        :alt: Documentation Status




Svarog allow to create object from non typed data. All it need is annotated `__init__` method:


>>> from svarog import forge
... class A:
...     def __init__(self, a: int, b: str):
...       self._a = a
...       self._b = b
...    def __repr__(self):
...        return f'A(a={self._a}, b="{self._b}")'
>>> forge(A, {"a": 1, "b": "3"})
A(a=1, b="3")


More complicated types as `Sequence`, `Mapping`, `Optional` are possible

>>> class A:
...     def __init__(self, b: Sequence[int]):
...         self._b = b
...     def __repr__(self):
...         return f'A(b={self._b})'
>>> forge(A, {"b": "3213"})
A(b=[3, 2, 1, 3])

You can use forward refs:

>>> class WithRef:
...    def __init__(self, child: Optional['WithRef']):
...        self._child = child
...    def __repr__(self):
...        return f"WithRef({self._child!r})"
>>> forge(WithRef(WithRef(WithRef())))
WithRef(WithRef(WithRef(None)))


Objects are forged recursively:


>>> @dataclass
... class A:
...     b: 'B'
...     c: 'C'
... @dataclass
... class B:
...     number: int
... @dataclass
... class C:
...     string: str
>>> forge(A, {'b': {'number': 42}, 'c': {'string': 'the-string'}})
A(b=B(number=42), c=C(string='the-string'))


You can register own forge for your classes:

>>> class FooType(Enum):
...     LOREM = "lorem"
...     IPSUM = "ipsum"
...
... class FooParams:
...     types: ClassVar[Mapping[FooType, "FooParams"]] = {}
...     def __init_subclass__(cls, type: FooType):
...        cls.types[type] = cls
...
...    @classmethod
...    def for_type(cls, type):
...        return cls.types[type]
...
... @dataclass
... class LoremFooParams(FooParams, type=FooType.LOREM):
...     lorem: str
...
... @dataclass
... class IpsumFooParams(FooParams, type=FooType.IPSUM):
...     ipsum: int
...
... @dataclass
... class Foo:
...     type: FooType
...     params: FooParams
...
...     @classmethod
...     def forge(cls, _, data, forge):
...         foo_type = forge(FooType, data["type"])
...         return Foo(
...             type=forge(FooType, foo_type),
...             params=forge(FooParams.for_type(foo_type), data["params"])
...         )
...
>>> register_forge(Foo, Foo.forge)
>>> forge(Foo, {"type": "lorem", "params": {"lorem": "foo-bar"}})
Foo(type=<FooType.LOREM: 'lorem'>, params=LoremFooParams(lorem='foo-bar'))

>>> forge(Foo, {"type": "ipsum", "params": {"ipsum": 42}})
Foo(type=<FooType.IPSUM: 'ipsum'>, params=IpsumFooParams(ipsum=42))


Support for CamelCase to snake_case convertion:

>>> class Snake:
...     lorem_ipsum: int
>>> forge = Svarog(snake_case=True).forge
>>> forge(Snake, {"LoremIpsum": 42})
Snake(lorem_ipsum=42)

* Free software: MIT license
* Documentation: https://svarog.readthedocs.io.


Features
--------

* Converts unstructured data into structured recursively

  * Works with `dataclasses`
  * Works with `Sequence`, `Mapping`, `Optional`
  * Special conventers for types can be registered with

Credits
-------

Some parts of this code, and concept borrowed from cattrs_ project

.. _Cattrs: https://github.com/Tinche/cattrs

This package was created with Cookiecutter_ and the `audreyr/cookiecutter-pypackage`_ project template.

.. _Cookiecutter: https://github.com/audreyr/cookiecutter
.. _`audreyr/cookiecutter-pypackage`: https://github.com/audreyr/cookiecutter-pypackage

            

Raw data

            {
    "_id": null,
    "home_page": "https://gitlab.com/dswistowski/svarog/",
    "name": "svarog",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.8,<4.0",
    "maintainer_email": "",
    "keywords": "svarog,json,structure,typing",
    "author": "Damian \u015awistowski",
    "author_email": "damian@swistowski.org",
    "download_url": "https://files.pythonhosted.org/packages/be/6a/accd525bec44a94b1ecb548e9895781b84a77b94b144fe9b65351f51380e/svarog-0.3.1.tar.gz",
    "platform": null,
    "description": "======\nSvarog\n======\n\n\n.. image:: https://img.shields.io/pypi/v/svarog.svg\n        :target: https://pypi.python.org/pypi/svarog\n\n.. image:: https://github.com/dswistowski/svarog/actions/workflows/tests.yml/badge.svg\n        :target: https://github.com/dswistowski/svarog/actions/workflows/tests.yml\n\n.. image:: https://readthedocs.org/projects/svarog/badge/?version=latest\n        :target: https://svarog.readthedocs.io/en/latest/?badge=latest\n        :alt: Documentation Status\n\n\n\n\nSvarog allow to create object from non typed data. All it need is annotated `__init__` method:\n\n\n>>> from svarog import forge\n... class A:\n...     def __init__(self, a: int, b: str):\n...       self._a = a\n...       self._b = b\n...    def __repr__(self):\n...        return f'A(a={self._a}, b=\"{self._b}\")'\n>>> forge(A, {\"a\": 1, \"b\": \"3\"})\nA(a=1, b=\"3\")\n\n\nMore complicated types as `Sequence`, `Mapping`, `Optional` are possible\n\n>>> class A:\n...     def __init__(self, b: Sequence[int]):\n...         self._b = b\n...     def __repr__(self):\n...         return f'A(b={self._b})'\n>>> forge(A, {\"b\": \"3213\"})\nA(b=[3, 2, 1, 3])\n\nYou can use forward refs:\n\n>>> class WithRef:\n...    def __init__(self, child: Optional['WithRef']):\n...        self._child = child\n...    def __repr__(self):\n...        return f\"WithRef({self._child!r})\"\n>>> forge(WithRef(WithRef(WithRef())))\nWithRef(WithRef(WithRef(None)))\n\n\nObjects are forged recursively:\n\n\n>>> @dataclass\n... class A:\n...     b: 'B'\n...     c: 'C'\n... @dataclass\n... class B:\n...     number: int\n... @dataclass\n... class C:\n...     string: str\n>>> forge(A, {'b': {'number': 42}, 'c': {'string': 'the-string'}})\nA(b=B(number=42), c=C(string='the-string'))\n\n\nYou can register own forge for your classes:\n\n>>> class FooType(Enum):\n...     LOREM = \"lorem\"\n...     IPSUM = \"ipsum\"\n...\n... class FooParams:\n...     types: ClassVar[Mapping[FooType, \"FooParams\"]] = {}\n...     def __init_subclass__(cls, type: FooType):\n...        cls.types[type] = cls\n...\n...    @classmethod\n...    def for_type(cls, type):\n...        return cls.types[type]\n...\n... @dataclass\n... class LoremFooParams(FooParams, type=FooType.LOREM):\n...     lorem: str\n...\n... @dataclass\n... class IpsumFooParams(FooParams, type=FooType.IPSUM):\n...     ipsum: int\n...\n... @dataclass\n... class Foo:\n...     type: FooType\n...     params: FooParams\n...\n...     @classmethod\n...     def forge(cls, _, data, forge):\n...         foo_type = forge(FooType, data[\"type\"])\n...         return Foo(\n...             type=forge(FooType, foo_type),\n...             params=forge(FooParams.for_type(foo_type), data[\"params\"])\n...         )\n...\n>>> register_forge(Foo, Foo.forge)\n>>> forge(Foo, {\"type\": \"lorem\", \"params\": {\"lorem\": \"foo-bar\"}})\nFoo(type=<FooType.LOREM: 'lorem'>, params=LoremFooParams(lorem='foo-bar'))\n\n>>> forge(Foo, {\"type\": \"ipsum\", \"params\": {\"ipsum\": 42}})\nFoo(type=<FooType.IPSUM: 'ipsum'>, params=IpsumFooParams(ipsum=42))\n\n\nSupport for CamelCase to snake_case convertion:\n\n>>> class Snake:\n...     lorem_ipsum: int\n>>> forge = Svarog(snake_case=True).forge\n>>> forge(Snake, {\"LoremIpsum\": 42})\nSnake(lorem_ipsum=42)\n\n* Free software: MIT license\n* Documentation: https://svarog.readthedocs.io.\n\n\nFeatures\n--------\n\n* Converts unstructured data into structured recursively\n\n  * Works with `dataclasses`\n  * Works with `Sequence`, `Mapping`, `Optional`\n  * Special conventers for types can be registered with\n\nCredits\n-------\n\nSome parts of this code, and concept borrowed from cattrs_ project\n\n.. _Cattrs: https://github.com/Tinche/cattrs\n\nThis package was created with Cookiecutter_ and the `audreyr/cookiecutter-pypackage`_ project template.\n\n.. _Cookiecutter: https://github.com/audreyr/cookiecutter\n.. _`audreyr/cookiecutter-pypackage`: https://github.com/audreyr/cookiecutter-pypackage\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Svarog allow to create object from non typed data",
    "version": "0.3.1",
    "split_keywords": [
        "svarog",
        "json",
        "structure",
        "typing"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "d7f4ac89eb7350ace43a564143f14aed8fdafa526831be80b9a8b51193647727",
                "md5": "ffd65cf64f3cf821389874c18684a4b3",
                "sha256": "c67598593b3bf91f1ae1a8e0120b66ca0114c46c53e3c1d86d0f83ea71ccfd45"
            },
            "downloads": -1,
            "filename": "svarog-0.3.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "ffd65cf64f3cf821389874c18684a4b3",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8,<4.0",
            "size": 9185,
            "upload_time": "2023-02-02T14:52:57",
            "upload_time_iso_8601": "2023-02-02T14:52:57.039287Z",
            "url": "https://files.pythonhosted.org/packages/d7/f4/ac89eb7350ace43a564143f14aed8fdafa526831be80b9a8b51193647727/svarog-0.3.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "be6aaccd525bec44a94b1ecb548e9895781b84a77b94b144fe9b65351f51380e",
                "md5": "f3aa22a551c2f998669318f6d6b3bb26",
                "sha256": "81de509f0c4994546b42a4bbf0ac49440ed81914f2fa2257e71b8fb3c7d09576"
            },
            "downloads": -1,
            "filename": "svarog-0.3.1.tar.gz",
            "has_sig": false,
            "md5_digest": "f3aa22a551c2f998669318f6d6b3bb26",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8,<4.0",
            "size": 8795,
            "upload_time": "2023-02-02T14:52:58",
            "upload_time_iso_8601": "2023-02-02T14:52:58.575892Z",
            "url": "https://files.pythonhosted.org/packages/be/6a/accd525bec44a94b1ecb548e9895781b84a77b94b144fe9b65351f51380e/svarog-0.3.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-02-02 14:52:58",
    "github": false,
    "gitlab": true,
    "bitbucket": false,
    "gitlab_user": "dswistowski",
    "gitlab_project": "svarog",
    "lcname": "svarog"
}
        
Elapsed time: 0.11575s