jetblack-serialization


Namejetblack-serialization JSON
Version 4.0.10 PyPI version JSON
download
home_pageNone
SummarySerialization for JSON and XML using typing
upload_time2025-09-09 06:37:38
maintainerNone
docs_urlNone
authorNone
requires_python>=3.12
licenseApache-2.0
keywords serialization json xml yaml
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # jetblack-serialization

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

## Installation

This is a Python 3.12+ package.

The package can be installed with pip.

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

By default, the dependencies for YAML and XML are not installed.

To install the dependencies for XML
([`lxml`](https://lxml.de/)).

```bash
pip install jetblack-serialization[xml]
```

To install the dependencies for YAML ([`PyYAML`](https://github.com/yaml/pyyaml)).

```bash
pip install jetblack-serialization[yaml]
```

To install the dependencies for all.

```bash
pip install jetblack-serialization[xml,yaml]
```

## Overview

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

### JSON

Given a typed dictionary:

```python
from datetime import datetime
from typing import 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 JSON

This could be serialized to JSON as:

```python
from stringcase import camelcase
from jetblack_serialization.json import serialize, SerializerConfig

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(key_serializer=camelcase, 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 JSON

We can deserialize the data as follows:

```python
from stringcase import snakecase
from jetblack_serialization.json import deserialize, SerializerConfig

dct = deserialize(
    text,
    Annotated[Book, JSONValue()],
    SerializerConfig(key_deserializer=snakecase)
)
```

### YAML

YAML is a superset of JSON, so for serialization things are very similar.

Given a typed dictionary:

```python
from datetime import datetime
from typing import 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 YAML

This could be serialized to YAML as:

```python
from stringcase import camelcase
from jetblack_serialization.yaml import serialize, SerializerConfig

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(key_serializer=camelcase, pretty_print=True)
)
print(text)
```

giving:

```yaml
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 YAML

We can deserialize the data as follows:

```python
from stringcase import snakecase
from jetblack_serialization.yaml import deserialize, SerializerConfig

dct = deserialize(
    text,
    Annotated[Book, JSONValue()],
    SerializerConfig(key_deserializer=snakecase)
)
```

### XML

The XML version of the typed dictionary might look like this:

```python
from datetime import datetime
from typing import 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 XML

To serialize we need to provide the containing tag `Book`:

```python
from stringcase import pascalcase
from jetblack_serialization.xml import serialize, SerializerConfig

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(key_serializer=pascalcase)
)
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 XML

We can deserialize the XML as follows:

```python
from stringcase import snakecase
from jetblack_serialization.xml import deserialize, SerializerConfig

dct = deserialize(
    text,
    Annotated[Book, XMLEntity("Book")],
    SerializerConfig(key_deserializer=snakecase)
)
```

## Attributes

For JSON, attributes are typically not required. However
`JSONProperty(tag: str)` and `JSONValue()` are provided for
completeness.

## Contributing

To run the tests with tox and pyenv:

```bash
VIRTUALENV_DISCOVERY=pyenv tox
```

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "jetblack-serialization",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.12",
    "maintainer_email": null,
    "keywords": "serialization, JSON, XML, YAML",
    "author": null,
    "author_email": "Rob Blackbourn <rob.blackbourn@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/ae/f3/23cc256901d26cbd00421285cb6f15ab5b6313c59e3200e3c57a70b541b6/jetblack_serialization-4.0.10.tar.gz",
    "platform": null,
    "description": "# jetblack-serialization\n\nSerialization for JSON, YAML and XML in Python using type annotations\n(read the [docs](https://rob-blackbourn.github.io/jetblack-serialization/)).\n\n## Installation\n\nThis is a Python 3.12+ package.\n\nThe package can be installed with pip.\n\n```bash\npip install jetblack-serialization\n```\n\nBy default, the dependencies for YAML and XML are not installed.\n\nTo install the dependencies for XML\n([`lxml`](https://lxml.de/)).\n\n```bash\npip install jetblack-serialization[xml]\n```\n\nTo install the dependencies for YAML ([`PyYAML`](https://github.com/yaml/pyyaml)).\n\n```bash\npip install jetblack-serialization[yaml]\n```\n\nTo install the dependencies for all.\n\n```bash\npip install jetblack-serialization[xml,yaml]\n```\n\n## Overview\n\nThe package adds support for type annotations when serializing or deserializing\nJSON, YAML or XML.\n\n### JSON\n\nGiven a typed dictionary:\n\n```python\nfrom datetime import datetime\nfrom typing import 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 JSON\n\nThis could be serialized to JSON as:\n\n```python\nfrom stringcase import camelcase\nfrom jetblack_serialization.json import serialize, SerializerConfig\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(key_serializer=camelcase, 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 JSON\n\nWe can deserialize the data as follows:\n\n```python\nfrom stringcase import snakecase\nfrom jetblack_serialization.json import deserialize, SerializerConfig\n\ndct = deserialize(\n    text,\n    Annotated[Book, JSONValue()],\n    SerializerConfig(key_deserializer=snakecase)\n)\n```\n\n### YAML\n\nYAML is a superset of JSON, so for serialization things are very similar.\n\nGiven a typed dictionary:\n\n```python\nfrom datetime import datetime\nfrom typing import 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 YAML\n\nThis could be serialized to YAML as:\n\n```python\nfrom stringcase import camelcase\nfrom jetblack_serialization.yaml import serialize, SerializerConfig\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(key_serializer=camelcase, pretty_print=True)\n)\nprint(text)\n```\n\ngiving:\n\n```yaml\nbookId: 42\ntitle: Little Red Book\nauthor: Chairman Mao\npublicationDate: '1973-01-01T21:52:13.00Z'\nkeywords:\n- Revolution\n- Communism\nphrases:\n- Revolutionary wars are inevitable in class society\n- War is the continuation of politics\nage: 24\npages: null\n```\n\nNote the fields have been camel cased, and the publication date has been turned\ninto an ISO 8601 date.\n\n#### Deserializing YAML\n\nWe can deserialize the data as follows:\n\n```python\nfrom stringcase import snakecase\nfrom jetblack_serialization.yaml import deserialize, SerializerConfig\n\ndct = deserialize(\n    text,\n    Annotated[Book, JSONValue()],\n    SerializerConfig(key_deserializer=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 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 XML\n\nTo serialize we need to provide the containing tag `Book`:\n\n```python\nfrom stringcase import pascalcase\nfrom jetblack_serialization.xml import serialize, SerializerConfig\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(key_serializer=pascalcase)\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 XML\n\nWe can deserialize the XML as follows:\n\n```python\nfrom stringcase import snakecase\nfrom jetblack_serialization.xml import deserialize, SerializerConfig\n\ndct = deserialize(\n    text,\n    Annotated[Book, XMLEntity(\"Book\")],\n    SerializerConfig(key_deserializer=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.\n\n## Contributing\n\nTo run the tests with tox and pyenv:\n\n```bash\nVIRTUALENV_DISCOVERY=pyenv tox\n```\n",
    "bugtrack_url": null,
    "license": "Apache-2.0",
    "summary": "Serialization for JSON and XML using typing",
    "version": "4.0.10",
    "project_urls": {
        "Homepage": "https://github.com/rob-blackbourn/jetblack-serialization",
        "Issues": "https://github.com/rob-blackbourn/jetblack-serialization/issues"
    },
    "split_keywords": [
        "serialization",
        " json",
        " xml",
        " yaml"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "5093c9e530efdc9f8ab9b5e030d6d5b38a5e073ea838041820e52262df6c1940",
                "md5": "e042f03bba14a9fcaeb827e88b893045",
                "sha256": "8bdba9a71d4b3300eebcc2ac30fe54fe875c19c7b545aa5d97cd851534d3bc84"
            },
            "downloads": -1,
            "filename": "jetblack_serialization-4.0.10-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "e042f03bba14a9fcaeb827e88b893045",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.12",
            "size": 32273,
            "upload_time": "2025-09-09T06:37:37",
            "upload_time_iso_8601": "2025-09-09T06:37:37.258285Z",
            "url": "https://files.pythonhosted.org/packages/50/93/c9e530efdc9f8ab9b5e030d6d5b38a5e073ea838041820e52262df6c1940/jetblack_serialization-4.0.10-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "aef323cc256901d26cbd00421285cb6f15ab5b6313c59e3200e3c57a70b541b6",
                "md5": "7d8a2a615529c7b6bcd466e2439e6392",
                "sha256": "97b6f1576f756460f06e4c5db467673943a90f467450d4ac5ab188921d6a5d53"
            },
            "downloads": -1,
            "filename": "jetblack_serialization-4.0.10.tar.gz",
            "has_sig": false,
            "md5_digest": "7d8a2a615529c7b6bcd466e2439e6392",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.12",
            "size": 24797,
            "upload_time": "2025-09-09T06:37:38",
            "upload_time_iso_8601": "2025-09-09T06:37:38.862608Z",
            "url": "https://files.pythonhosted.org/packages/ae/f3/23cc256901d26cbd00421285cb6f15ab5b6313c59e3200e3c57a70b541b6/jetblack_serialization-4.0.10.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-09-09 06:37:38",
    "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: 2.51325s