Serialization for JSON and XML using typing
Project description
jetblack-serialization
Serialization for JSON and XML in Python using typing annotations (read the docs).
Status
It has been tested with Python 3.7 used the typing_extensions
package for TypedDict
and Annotated
. In Python 3.8 the TypedDict
class is available in the standard typing
package.
Installation
The package can be installed with pip.
pip install jetblack-serialization
Overview
The package adds support for type annotations when serializing or deserializing JSON or XML.
JSON
Given a typed dictionary:
from datetime import datetime from typing import List, Optional, TypedDict, Union class Book(TypedDict, total=False): book_id: int title: str author: str publication_date: datetime keywords: List[str] phrases: List[str] age: Optional[Union[datetime, int]] pages: Optional[int]
Serializing
This could be serialized to JSON as:
from stringcase import camelcase, snakecase from jetblack_serialization import SerializerConfig from jetblack_serialization.json import serialize obj: Book = { 'author': 'Chairman Mao', 'book_id': 42, 'title': 'Little Red Book', 'publication_date': datetime(1973, 1, 1, 21, 52, 13), 'keywords': ['Revolution', 'Communism'], 'phrases': [ 'Revolutionary wars are inevitable in class society', 'War is the continuation of politics' ], 'age': 24, } text = serialize( obj, Book, SerializerConfig(camelcase, snakecase, pretty_print=True) ) print(text)
giving:
{ "bookId": 42, "title": "Little Red Book", "author": "Chairman Mao", "publicationDate": "1973-01-01T21:52:13.00Z", "keywords": ["Revolution", "Communism"], "phrases": ["Revolutionary wars are inevitable in class society", "War is the continuation of politics"], "age": 24, "pages": null }
Note the fields have been camel cased, and the publication date has been turned into an ISO 8601 date.
Deserializing
We can deserialize the data as follows:
from stringcase import camelcase, snakecase from jetblack_serialization import SerializerConfig from jetblack_serialization.json import deserialize dct = deserialize( text, Annotated[Book, JSONValue()], SerializerConfig(camelcase, snakecase) )
XML
The XML version of the typed dictionary might look like this:
from datetime import datetime from typing import List, Optional, TypedDict, Union from typing_extensions import Annotated from jetblack_serialization.xml import XMLEntity, XMLAttribute class Book(TypedDict, total=False): book_id: Annotated[int, XMLAttribute("bookId")] title: str author: str publication_date: datetime keywords: Annotated[List[Annotated[str, XMLEntity("Keyword")]], XMLEntity("Keywords")] phrases: List[str] age: Optional[Union[datetime, int]] pages: Optional[int]
Note we have introduced some annotations to control the serialization. For XML we have used pascal-case to serialized the keys and snake-case for deserialization.
Serializing
To serialize we need to provide the containing tag Book
:
from stringcase import pascalcase, snakecase from jetblack_serialization import SerializerConfig from jetblack_serialization.xml import serialize book: Book = { 'author': 'Chairman Mao', 'book_id': 42, 'title': 'Little Red Book', 'publication_date': datetime(1973, 1, 1, 21, 52, 13), 'keywords': ['Revolution', 'Communism'], 'phrases': [ 'Revolutionary wars are inevitable in class society', 'War is the continuation of politics' ], 'age': 24, 'pages': None } text = serialize( book, Annotated[Book, XMLEntity("Book")], SerializerConfig(pascalcase, snakecase) ) print(text)
Producing:
<Book bookId="42"> <Title>Little Red Book</Title> <Author>Chairman Mao</Author> <PublicationDate>1973-01-01T21:52:13.00Z</PublicationDate> <Keywords> <Keyword>Revolution</Keyword> <Keyword>Communism</Keyword> </Keywords> <Phrase>Revolutionary wars are inevitable in class society</Phrase> <Phrase>War is the continuation of politics</Phrase> <Age>24</Age> </Book>'
The annotations are more elaborate here. However, much of the typed dictionary requires no annotation.
First we needed the outer document wrapper XMLEntity("Book")
.
Next we annotated the book_id
to be an XMLAttribute
.
Finally we annotated the two lists differently. The keywords
list used
a nested structure, which we indicated by giving the list a different
XMLEntity
tag to the list items. For the phrases we used the default
in-line behaviour.
Deserializing
We can deserialize the XML as follows:
from stringcase import pascalcase, snakecase from jetblack_serialization import SerializerConfig from jetblack_serialization.xml import deserialize dct = deserialize( text, Annotated[Book, XMLEntity("Book")], SerializerConfig(pascalcase, snakecase) )
Attributes
For JSON, attributes are typically not required. However
JSONProperty(tag: str)
and JSONValue()
are provided for
completeness.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Hashes for jetblack-serialization-2.1.1.tar.gz
Algorithm | Hash digest | |
---|---|---|
SHA256 | efe513b2d3778e78f73d7ca9796595181c61f65d3b2ba39eb68a9e58a5f372a1 |
|
MD5 | c8353fc7ab958962ff101a81a76d1678 |
|
BLAKE2-256 | e0a83e1f5744f450a2a131961e96aeb5e174bfaab9f12b139a4298ef011b159a |
Hashes for jetblack_serialization-2.1.1-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | aaef3bcc637902638a744981f7ac11f46b2821f88235ad74d794da251305bbf0 |
|
MD5 | 17c337a9a092677f5f5c1ac45518a5cd |
|
BLAKE2-256 | 450aa56df2bfde0b0c1d5257ae10f3fc903eb79aa625efa563582e4b75caf24d |