jetblack-serialization


Namejetblack-serialization JSON
Version 3.1.1 PyPI version JSON
download
home_pagehttps://github.com/rob-blackbourn/jetblack-serialization
SummarySerialization for JSON and XML using typing
upload_time2024-06-19 13:26:44
maintainerNone
docs_urlNone
authorRob Blackbourn
requires_python<4.0,>=3.7
licenseApache-2.0
keywords serialization jetblack json xml typing
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # jetblack-serialization

Serialization for JSON and XML in Python using typing annotations
(read the [docs](https://rob-blackbourn.github.io/jetblack-serialization/)).

## 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.

```bash
pip install jetblack-serialization
```

## Overview

The package adds support for type annotations when serializing or deserializing
JSON or XML.


### JSON

Given a typed dictionary:

```python
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:

```python
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:

```json
{
    "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:

```python
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:

```python
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`:

```python
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:

```xml
<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:

```python
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.
            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/rob-blackbourn/jetblack-serialization",
    "name": "jetblack-serialization",
    "maintainer": null,
    "docs_url": null,
    "requires_python": "<4.0,>=3.7",
    "maintainer_email": null,
    "keywords": "serialization, jetblack, json, xml, typing",
    "author": "Rob Blackbourn",
    "author_email": "rob.blackbourn@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/ef/c5/73c652615bcc23c136aed53b11cb000b2d535ebd431a5ed0427f2c982868/jetblack-serialization-3.1.1.tar.gz",
    "platform": null,
    "description": "# jetblack-serialization\n\nSerialization for JSON and XML in Python using typing annotations\n(read the [docs](https://rob-blackbourn.github.io/jetblack-serialization/)).\n\n## Status\n\nIt has been tested with Python 3.7 used the `typing_extensions`\npackage for `TypedDict` and `Annotated`. In Python 3.8 the `TypedDict`\nclass is available in the standard `typing` package.\n\n## Installation\n\nThe package can be installed with pip.\n\n```bash\npip install jetblack-serialization\n```\n\n## Overview\n\nThe package adds support for type annotations when serializing or deserializing\nJSON or XML.\n\n\n### JSON\n\nGiven a typed dictionary:\n\n```python\nfrom datetime import datetime\nfrom typing import List, Optional, TypedDict, Union\n\nclass Book(TypedDict, total=False):\n    book_id: int\n    title: str\n    author: str\n    publication_date: datetime\n    keywords: List[str]\n    phrases: List[str]\n    age: Optional[Union[datetime, int]]\n    pages: Optional[int]\n```\n\n#### Serializing\n\nThis could be serialized to JSON as:\n\n```python\nfrom stringcase import camelcase, snakecase\nfrom jetblack_serialization import SerializerConfig\nfrom jetblack_serialization.json import serialize\n\nobj: Book = {\n    'author': 'Chairman Mao',\n    'book_id': 42,\n    'title': 'Little Red Book',\n    'publication_date': datetime(1973, 1, 1, 21, 52, 13),\n    'keywords': ['Revolution', 'Communism'],\n    'phrases': [\n        'Revolutionary wars are inevitable in class society',\n        'War is the continuation of politics'\n    ],\n    'age': 24,\n}\ntext = serialize(\n    obj,\n    Book,\n    SerializerConfig(camelcase, snakecase, pretty_print=True)\n)\nprint(text)\n```\n\ngiving:\n\n```json\n{\n    \"bookId\": 42,\n    \"title\": \"Little Red Book\",\n    \"author\": \"Chairman Mao\",\n    \"publicationDate\": \"1973-01-01T21:52:13.00Z\",\n    \"keywords\": [\"Revolution\", \"Communism\"],\n    \"phrases\": [\"Revolutionary wars are inevitable in class society\", \"War is the continuation of politics\"],\n    \"age\": 24,\n    \"pages\": null\n}\n```\n\nNote the fields have been camel cased, and the publication date has been turned\ninto an ISO 8601 date.\n\n#### Deserializing\n\nWe can deserialize the data as follows:\n\n```python\nfrom stringcase import camelcase, snakecase\nfrom jetblack_serialization import SerializerConfig\nfrom jetblack_serialization.json import deserialize\n\ndct = deserialize(\n    text,\n    Annotated[Book, JSONValue()],\n    SerializerConfig(camelcase, snakecase)\n)\n```\n\n### XML\n\nThe XML version of the typed dictionary might look like this:\n\n```python\nfrom datetime import datetime\nfrom typing import List, Optional, TypedDict, Union\nfrom typing_extensions import Annotated\nfrom jetblack_serialization.xml import XMLEntity, XMLAttribute\n\nclass Book(TypedDict, total=False):\n    book_id: Annotated[int, XMLAttribute(\"bookId\")]\n    title: str\n    author: str\n    publication_date: datetime\n    keywords: Annotated[List[Annotated[str, XMLEntity(\"Keyword\")]], XMLEntity(\"Keywords\")]\n    phrases: List[str]\n    age: Optional[Union[datetime, int]]\n    pages: Optional[int]\n```\n\nNote we have introduced some annotations to control the serialization.\nFor XML we have used pascal-case to serialized the keys and snake-case\nfor deserialization.\n\n#### Serializing\n\nTo serialize we need to provide the containing tag `Book`:\n\n```python\nfrom stringcase import pascalcase, snakecase\nfrom jetblack_serialization import SerializerConfig\nfrom jetblack_serialization.xml import serialize\n\nbook: Book = {\n    'author': 'Chairman Mao',\n    'book_id': 42,\n    'title': 'Little Red Book',\n    'publication_date': datetime(1973, 1, 1, 21, 52, 13),\n    'keywords': ['Revolution', 'Communism'],\n    'phrases': [\n        'Revolutionary wars are inevitable in class society',\n        'War is the continuation of politics'\n    ],\n    'age': 24,\n    'pages': None\n}\ntext = serialize(\n    book,\n    Annotated[Book, XMLEntity(\"Book\")],\n    SerializerConfig(pascalcase, snakecase)\n)\nprint(text)\n```\n\nProducing:\n\n```xml\n<Book bookId=\"42\">\n    <Title>Little Red Book</Title>\n    <Author>Chairman Mao</Author>\n    <PublicationDate>1973-01-01T21:52:13.00Z</PublicationDate>\n    <Keywords>\n        <Keyword>Revolution</Keyword>\n        <Keyword>Communism</Keyword>\n    </Keywords>\n    <Phrase>Revolutionary wars are inevitable in class society</Phrase>\n    <Phrase>War is the continuation of politics</Phrase>\n    <Age>24</Age>\n</Book>'\n```\n\nThe annotations are more elaborate here. However, much of the typed dictionary\nrequires no annotation.\n\nFirst we needed the outer document wrapper `XMLEntity(\"Book\")`.\n\nNext we annotated the `book_id` to be an `XMLAttribute`.\n\nFinally we annotated the two lists differently. The `keywords` list used\na nested structure, which we indicated by giving the list a different\n`XMLEntity` tag to the list items. For the phrases we used the default\nin-line behaviour.\n\n#### Deserializing\n\nWe can deserialize the XML as follows:\n\n```python\nfrom stringcase import pascalcase, snakecase\nfrom jetblack_serialization import SerializerConfig\nfrom jetblack_serialization.xml import deserialize\n\ndct = deserialize(\n    text,\n    Annotated[Book, XMLEntity(\"Book\")],\n    SerializerConfig(pascalcase, snakecase)\n)\n```\n\n## Attributes\n\nFor JSON, attributes are typically not required. However\n`JSONProperty(tag: str)` and `JSONValue()` are provided for\ncompleteness.",
    "bugtrack_url": null,
    "license": "Apache-2.0",
    "summary": "Serialization for JSON and XML using typing",
    "version": "3.1.1",
    "project_urls": {
        "Homepage": "https://github.com/rob-blackbourn/jetblack-serialization",
        "Repository": "https://github.com/rob-blackbourn/jetblack-serialization"
    },
    "split_keywords": [
        "serialization",
        " jetblack",
        " json",
        " xml",
        " typing"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "e58336ef715c0dfa96d8ca0cca6c7a16c1276bde5ae47d5c473016dbc7688b64",
                "md5": "c9ad4c56e55093ce4b473b4e48d8297c",
                "sha256": "334b049a3eb916a425dec95a079372d1f8f9adc466c7177000bf8dd517996e05"
            },
            "downloads": -1,
            "filename": "jetblack_serialization-3.1.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "c9ad4c56e55093ce4b473b4e48d8297c",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": "<4.0,>=3.7",
            "size": 25768,
            "upload_time": "2024-06-19T13:26:46",
            "upload_time_iso_8601": "2024-06-19T13:26:46.320765Z",
            "url": "https://files.pythonhosted.org/packages/e5/83/36ef715c0dfa96d8ca0cca6c7a16c1276bde5ae47d5c473016dbc7688b64/jetblack_serialization-3.1.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "efc573c652615bcc23c136aed53b11cb000b2d535ebd431a5ed0427f2c982868",
                "md5": "701f49588c218cb568cbde288d587088",
                "sha256": "ee06e5856953f8641fba46a850231da1c96892f91053fdd86b25792c6925db1c"
            },
            "downloads": -1,
            "filename": "jetblack-serialization-3.1.1.tar.gz",
            "has_sig": false,
            "md5_digest": "701f49588c218cb568cbde288d587088",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": "<4.0,>=3.7",
            "size": 19012,
            "upload_time": "2024-06-19T13:26:44",
            "upload_time_iso_8601": "2024-06-19T13:26:44.238888Z",
            "url": "https://files.pythonhosted.org/packages/ef/c5/73c652615bcc23c136aed53b11cb000b2d535ebd431a5ed0427f2c982868/jetblack-serialization-3.1.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-06-19 13:26:44",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "rob-blackbourn",
    "github_project": "jetblack-serialization",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "jetblack-serialization"
}
        
Elapsed time: 4.10027s