Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/dapper91/paxb
Python Architecture for XML Binding
https://github.com/dapper91/paxb
binding deserialization json mapping marshalling python serialization unmarshalling xml
Last synced: 4 months ago
JSON representation
Python Architecture for XML Binding
- Host: GitHub
- URL: https://github.com/dapper91/paxb
- Owner: dapper91
- License: unlicense
- Created: 2019-08-01T19:26:03.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2019-10-10T16:24:55.000Z (over 5 years ago)
- Last Synced: 2024-10-09T19:50:09.107Z (4 months ago)
- Topics: binding, deserialization, json, mapping, marshalling, python, serialization, unmarshalling, xml
- Language: Python
- Size: 67.4 KB
- Stars: 3
- Watchers: 3
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.rst
- Changelog: CHANGELOG.rst
- License: LICENSE
Awesome Lists containing this project
README
====
paxb
====.. image:: https://travis-ci.org/dapper91/paxb.svg?branch=master
:target: https://travis-ci.org/dapper91/paxb
:alt: Build status
.. image:: https://img.shields.io/pypi/l/paxb.svg
:target: https://pypi.org/project/paxb
:alt: License
.. image:: https://img.shields.io/pypi/pyversions/paxb.svg
:target: https://pypi.org/project/paxb
:alt: Supported Python versions
.. image:: https://codecov.io/gh/dapper91/paxb/branch/master/graph/badge.svg
:target: https://codecov.io/gh/dapper91/paxb
:alt: Code coveragePython Architecture for XML Binding
-----------------------------------``paxb`` is a library that provides an API for mapping between XML documents and Python objects.
``paxb`` library implements the following functionality:
- Deserialize XML documents to Python objects
- Validate deserialized data
- Access and update Python object fields
- Serialize Python objects to XML documents``paxb`` provides an efficient way of mapping between an XML document and a Python object. Using ``paxb``
developers can write less boilerplate code emphasizing on application domain logic.Since ``paxb`` based on `attrs `_ library ``paxb`` and ``attrs``
API can be mixed together.Installation
------------You can install paxb with pip:
.. code-block:: console
$ pip install paxb
Requirements
------------- `attrs `_
Documentation
-------------Documentation is available at `Read the Docs `_.
Quick start
===========Suppose you have an xml document ``user.xml``:
.. code-block:: xml
+79204563539
[email protected]
[email protected]
Moscow
8854
Yekaterinburg
7742
To deserialize the document you could use `xml `_ library api to parse
the document and then access and modify the parsed xml DOM manually. Such an imperative code has a lot of boilerplate
operations that takes a lot of time and can lead to bugs. Instead you can use ``paxb`` api to write a declarative
style code. All you need to describe field mappings and types, ``paxb`` will serialize and deserialize data for you:.. code-block:: python
import json
import re
from datetime import dateimport attr
import paxb as pb@pb.model(name='occupation', ns='data', ns_map={'data': 'http://www.test2.org'})
class Occupation:
title = pb.attr()
address = pb.field()
employees = pb.field(converter=int)@pb.model(name='user', ns='doc', ns_map={'doc': 'http://www.test1.org'})
class User:
name = pb.attr()
surname = pb.attr()
age = pb.attr(converter=int)birth_year = pb.wrap('birthdate', pb.attr('year', converter=int))
birth_month = pb.wrap('birthdate', pb.attr('month', converter=int))
birth_day = pb.wrap('birthdate', pb.attr('day', converter=int))@property
def birthdate(self):
return date(year=self.birth_year, month=self.birth_month, day=self.birth_day)@birthdate.setter
def birthdate(self, value):
self.birth_year = value.year
self.birth_month = value.month
self.birth_day = value.dayphone = pb.wrap('contacts', pb.field())
emails = pb.wrap('contacts', pb.as_list(pb.field(name='email')))passport_series = pb.wrap('documents/passport', pb.attr('series'))
passport_number = pb.wrap('documents/passport', pb.attr('number'))occupations = pb.wrap(
'occupations', pb.lst(pb.nested(Occupation)), ns='data', ns_map={'data': 'http://www.test2.org'}
)citizenship = pb.field(default='RU')
@phone.validator
def check(self, attribute, value):
if not re.match(r'\+\d{11,13}', value):
raise ValueError("phone number is incorrect")with open('user.xml') as file:
xml = file.read()Then the deserialized object can be modified and serialized back to xml document or converted to json format:
.. code-block:: python
try:
user = pb.from_xml(User, xml, envelope='doc:envelope', ns_map={'doc': 'http://www.test1.org'})
user.birthdate = user.birthdate.replace(year=1993)with open('user.json') as file:
json.dump(attr.asdict(user), file)except (pb.exc.DeserializationError, ValueError) as e:
print(f"deserialization error: {e}")``user.json``:
.. code-block:: json
{
"age": 26,
"birth_day": 14,
"birth_month": 6,
"birth_year": 1993,
"citizenship": "RU",
"emails": ["[email protected]", "[email protected]"],
"name": "Alexey",
"occupations": [
{
"address": "Moscow",
"employees": 8854,
"title": "yandex"
},
{
"address": "Yekaterinburg",
"employees": 7742,
"title": "skbkontur"
}
],
"passport_number": "836815",
"passport_series": "3127",
"phone": "+79204563539",
"surname": "Ivanov"
}