{ "info": { "author": "Dmitry Pershin", "author_email": "dapper91@mail.ru", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Intended Audience :: Developers", "License :: Public Domain", "Natural Language :: English", "Programming Language :: Python", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7" ], "description": "====\npaxb\n====\n\n.. image:: https://travis-ci.org/dapper91/paxb.svg?branch=master\n :target: https://travis-ci.org/dapper91/paxb\n :alt: Build status\n.. image:: https://img.shields.io/pypi/l/paxb.svg\n :target: https://pypi.org/project/paxb\n :alt: License\n.. image:: https://img.shields.io/pypi/pyversions/paxb.svg\n :target: https://pypi.org/project/paxb\n :alt: Supported Python versions\n.. image:: https://codecov.io/gh/dapper91/paxb/branch/master/graph/badge.svg\n :target: https://codecov.io/gh/dapper91/paxb\n :alt: Code coverage\n\n\nPython Architecture for XML Binding\n-----------------------------------\n\n``paxb`` is a library that provides an API for mapping between XML documents and Python objects.\n\n``paxb`` library implements the following functionality:\n\n- Deserialize XML documents to Python objects\n- Validate deserialized data\n- Access and update Python object fields\n- Serialize Python objects to XML documents\n\n``paxb`` provides an efficient way of mapping between an XML document and a Python object. Using ``paxb``\ndevelopers can write less boilerplate code emphasizing on application domain logic.\n\nSince ``paxb`` based on `attrs `_ library ``paxb`` and ``attrs``\nAPI can be mixed together.\n\n\nInstallation\n------------\n\nYou can install paxb with pip:\n\n.. code-block:: console\n\n $ pip install paxb\n\n\nRequirements\n------------\n\n- `attrs `_\n\n\nDocumentation\n-------------\n\nDocumentation is available at `Read the Docs `_.\n\n\nQuick start\n===========\n\nSuppose you have an xml document ``user.xml``:\n\n.. code-block:: xml\n\n \n \n \n\n \n\n \n +79204563539\n alex@gmail.com\n alex@mail.ru\n \n\n \n \n \n\n \n \n Moscow\n 8854\n \n \n Yekaterinburg\n 7742\n \n \n\n \n \n\n\nTo deserialize the document you could use `xml `_ library api to parse\nthe document and then access and modify the parsed xml DOM manually. Such an imperative code has a lot of boilerplate\noperations that takes a lot of time and can lead to bugs. Instead you can use ``paxb`` api to write a declarative\nstyle code. All you need to describe field mappings and types, ``paxb`` will serialize and deserialize data for you:\n\n.. code-block:: python\n\n import json\n import re\n from datetime import date\n\n import attr\n import paxb as pb\n\n\n @pb.model(name='occupation', ns='data', ns_map={'data': 'http://www.test2.org'})\n class Occupation:\n title = pb.attr()\n address = pb.field()\n employees = pb.field(converter=int)\n\n\n @pb.model(name='user', ns='doc', ns_map={'doc': 'http://www.test1.org'})\n class User:\n name = pb.attr()\n surname = pb.attr()\n age = pb.attr(converter=int)\n\n birth_year = pb.wrap('birthdate', pb.attr('year', converter=int))\n birth_month = pb.wrap('birthdate', pb.attr('month', converter=int))\n birth_day = pb.wrap('birthdate', pb.attr('day', converter=int))\n\n @property\n def birthdate(self):\n return date(year=self.birth_year, month=self.birth_month, day=self.birth_day)\n\n @birthdate.setter\n def birthdate(self, value):\n self.birth_year = value.year\n self.birth_month = value.month\n self.birth_day = value.day\n\n phone = pb.wrap('contacts', pb.field())\n emails = pb.wrap('contacts', pb.as_list(pb.field(name='email')))\n\n passport_series = pb.wrap('documents/passport', pb.attr('series'))\n passport_number = pb.wrap('documents/passport', pb.attr('number'))\n\n occupations = pb.wrap(\n 'occupations', pb.lst(pb.nested(Occupation)), ns='data', ns_map={'data': 'http://www.test2.org'}\n )\n\n citizenship = pb.field(default='RU')\n\n @phone.validator\n def check(self, attribute, value):\n if not re.match(r'\\+\\d{11,13}', value):\n raise ValueError(\"phone number is incorrect\")\n\n\n with open('user.xml') as file:\n xml = file.read()\n\n\nThen the deserialized object can be modified and serialized back to xml document or converted to json format:\n\n.. code-block:: python\n\n try:\n user = pb.from_xml(User, xml, envelope='doc:envelope', ns_map={'doc': 'http://www.test1.org'})\n user.birthdate = user.birthdate.replace(year=1993)\n\n with open('user.json') as file:\n json.dump(attr.asdict(user), file)\n\n except (pb.exc.DeserializationError, ValueError) as e:\n print(f\"deserialization error: {e}\")\n\n\n``user.json``:\n\n.. code-block:: json\n\n {\n \"age\": 26,\n \"birth_day\": 14,\n \"birth_month\": 6,\n \"birth_year\": 1993,\n \"citizenship\": \"RU\",\n \"emails\": [\"alex@gmail.com\", \"alex@mail.ru\"],\n \"name\": \"Alexey\",\n \"occupations\": [\n {\n \"address\": \"Moscow\",\n \"employees\": 8854,\n \"title\": \"yandex\"\n },\n {\n \"address\": \"Yekaterinburg\",\n \"employees\": 7742,\n \"title\": \"skbkontur\"\n }\n ],\n \"passport_number\": \"836815\",\n \"passport_series\": \"3127\",\n \"phone\": \"+79204563539\",\n \"surname\": \"Ivanov\"\n }", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/dapper91/paxb", "keywords": "xml,binding,mapping,serialization,deserialization", "license": "Public Domain License", "maintainer": "", "maintainer_email": "", "name": "paxb", "package_url": "https://pypi.org/project/paxb/", "platform": "", "project_url": "https://pypi.org/project/paxb/", "project_urls": { "Homepage": "https://github.com/dapper91/paxb" }, "release_url": "https://pypi.org/project/paxb/0.3.0/", "requires_dist": null, "requires_python": ">=3.5", "summary": "Python Architecture for XML Binding", "version": "0.3.0" }, "last_serial": 5919041, "releases": { "0.1.0": [ { "comment_text": "", "digests": { "md5": "7b2ee9652153972d0c0743df04d2d95c", "sha256": "bf218dee6fba2daf65f5c49a440f88ba40dd0f3241be4f426deb9a94f20bba82" }, "downloads": -1, "filename": "paxb-0.1.0-py3.7.egg", "has_sig": false, "md5_digest": "7b2ee9652153972d0c0743df04d2d95c", "packagetype": "bdist_egg", "python_version": "3.7", "requires_python": ">=3.5", "size": 18651, "upload_time": "2019-08-14T14:46:10", "url": "https://files.pythonhosted.org/packages/00/3c/61e8c6595db47b7b30030b2ac4ddde4ff681efa02b9d5f603d03d57e5424/paxb-0.1.0-py3.7.egg" }, { "comment_text": "", "digests": { "md5": "3ccc738b4bae6d2694df7f9c66f3d376", "sha256": "f6dd89db21c24747e3a56b6f2620a46ecfd286637730aa2f42dbe4824016b817" }, "downloads": -1, "filename": "paxb-0.1.0.tar.gz", "has_sig": false, "md5_digest": "3ccc738b4bae6d2694df7f9c66f3d376", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5", "size": 9471, "upload_time": "2019-08-14T14:46:13", "url": "https://files.pythonhosted.org/packages/e7/e2/26f922f1b80dcaf63a32a30deedf6cced718cd03a13ce28e39491fda2036/paxb-0.1.0.tar.gz" } ], "0.2.0": [ { "comment_text": "", "digests": { "md5": "c8b76f3910043dca66f3f9c2d1d3cf2a", "sha256": "88d8fd7181107956e78669561e1a592c88a2b942d6820632e9f9b8ced6213310" }, "downloads": -1, "filename": "paxb-0.2.0.tar.gz", "has_sig": false, "md5_digest": "c8b76f3910043dca66f3f9c2d1d3cf2a", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5", "size": 11020, "upload_time": "2019-08-25T10:36:19", "url": "https://files.pythonhosted.org/packages/08/6b/4ab8615654abc9c1da9746a0cf0fa61cb3445b45eed193a7027ee256dc20/paxb-0.2.0.tar.gz" } ], "0.2.1": [ { "comment_text": "", "digests": { "md5": "faac90830c67eb40d3635b39c6318252", "sha256": "6784b3863187b3f1add6b7f9f3ac6476d0a890e1fb8b53d189a08ec74fc7dfe2" }, "downloads": -1, "filename": "paxb-0.2.1.tar.gz", "has_sig": false, "md5_digest": "faac90830c67eb40d3635b39c6318252", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5", "size": 11109, "upload_time": "2019-08-25T20:03:23", "url": "https://files.pythonhosted.org/packages/7b/13/7e00cbe50b63053e91e944108eab9697538ac0e15e48368c7b2e7f536055/paxb-0.2.1.tar.gz" } ], "0.2.2": [ { "comment_text": "", "digests": { "md5": "c0d51ffb6cca021161e6c0b94d929749", "sha256": "34acf150551443711b6431a856e9b1c938c83ba91e24f0f6ea9f445f92b809a7" }, "downloads": -1, "filename": "paxb-0.2.2.tar.gz", "has_sig": false, "md5_digest": "c0d51ffb6cca021161e6c0b94d929749", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5", "size": 11210, "upload_time": "2019-09-24T18:05:08", "url": "https://files.pythonhosted.org/packages/68/f4/5cdb42cf418beded79e40b6de5251a7cbf150e15dd8fb2bd80d052b03122/paxb-0.2.2.tar.gz" } ], "0.3.0": [ { "comment_text": "", "digests": { "md5": "18e23acb7ba0f1a62be41fb07b3668b0", "sha256": "86c9e124d5c2411d2cf655903821b8e140737ffb67e27f4b62b4661ae75fe796" }, "downloads": -1, "filename": "paxb-0.3.0.tar.gz", "has_sig": false, "md5_digest": "18e23acb7ba0f1a62be41fb07b3668b0", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5", "size": 11215, "upload_time": "2019-10-02T17:04:38", "url": "https://files.pythonhosted.org/packages/2e/c1/0fccf86e1d7d0ba69c325628fdea3ea206539985b255fd9279195968a1c4/paxb-0.3.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "18e23acb7ba0f1a62be41fb07b3668b0", "sha256": "86c9e124d5c2411d2cf655903821b8e140737ffb67e27f4b62b4661ae75fe796" }, "downloads": -1, "filename": "paxb-0.3.0.tar.gz", "has_sig": false, "md5_digest": "18e23acb7ba0f1a62be41fb07b3668b0", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5", "size": 11215, "upload_time": "2019-10-02T17:04:38", "url": "https://files.pythonhosted.org/packages/2e/c1/0fccf86e1d7d0ba69c325628fdea3ea206539985b255fd9279195968a1c4/paxb-0.3.0.tar.gz" } ] }