Name | dataclasses-avroschema JSON |
Version |
0.60.2
JSON |
| download |
home_page | None |
Summary | Generate Avro Schemas from Python classes. Serialize/Deserialize python instances with avro schemas |
upload_time | 2024-06-07 13:27:52 |
maintainer | None |
docs_url | None |
author | Marcos Schroh |
requires_python | <4.0,>=3.8 |
license | MIT |
keywords |
|
VCS |
|
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
# Dataclasses Avro Schema Generator
Generate [avro schemas](https://avro.apache.org/docs/1.8.2/spec.html) from python dataclasses. [Code generation](https://marcosschroh.github.io/dataclasses-avroschema/model_generator/) from avro schemas. [Serialize/Deserialize](https://marcosschroh.github.io/dataclasses-avroschema/serialization/) python instances with avro schemas
[![Tests](https://github.com/marcosschroh/dataclasses-avroschema/actions/workflows/tests.yaml/badge.svg)](https://github.com/marcosschroh/dataclasses-avroschema/actions/workflows/tests.yaml)
[![GitHub license](https://img.shields.io/github/license/marcosschroh/dataclasses-avroschema.svg)](https://github.com/marcosschroh/dataclasses-avroschema/blob/master/LICENSE)
[![codecov](https://codecov.io/gh/marcosschroh/dataclasses-avroschema/branch/master/graph/badge.svg)](https://codecov.io/gh/marcosschroh/dataclasses-avroschema)
![python version](https://img.shields.io/badge/python-3.8%2B-yellowgreen)
## Requirements
`python 3.8+`
## Installation
with `pip` or `poetry`:
`pip install dataclasses-avroschema` or `poetry add dataclasses-avroschema`
### Extras
- [pydantic](https://docs.pydantic.dev/): `pip install 'dataclasses-avroschema[pydantic]'` or `poetry add dataclasses-avroschema --extras "pydantic"`
- [faust-streaming](https://github.com/faust-streaming/faust): `pip install 'dataclasses-avroschema[faust]'` or `poetry add dataclasses-avroschema --extras "faust"`
- [faker](https://github.com/joke2k/faker): `pip install 'dataclasses-avroschema[faker]'` or `poetry add dataclasses-avroschema --extras "faker"`
*Note*: You can install all extra dependencies with `pip install dataclasses-avroschema[faust, pydantic, faker]` or `poetry add dataclasses-avroschema --extras "pydantic faust faker"`
### CLI
To install `avro schemas cli` install [dc-avro](https://marcosschroh.github.io/dc-avro/)
`pip install 'dataclasses-avroschema[cli]'` or `poetry add dataclasses-avroschema --with cli`
## Documentation
https://marcosschroh.github.io/dataclasses-avroschema/
## Usage
### Generating the avro schema
```python
from dataclasses import dataclass
import enum
import typing
from dataclasses_avroschema import AvroModel, types
class FavoriteColor(enum.Enum):
BLUE = "BLUE"
YELLOW = "YELLOW"
GREEN = "GREEN"
@dataclass
class User(AvroModel):
"An User"
name: str
age: int
pets: typing.List[str]
accounts: typing.Dict[str, int]
favorite_colors: FavoriteColor
country: str = "Argentina"
address: str = None
class Meta:
namespace = "User.v1"
aliases = ["user-v1", "super user"]
User.avro_schema()
'{
"type": "record",
"name": "User",
"doc": "An User",
"namespace": "User.v1",
"aliases": ["user-v1", "super user"],
"fields": [
{"name": "name", "type": "string"},
{"name": "age", "type": "long"},
{"name": "pets", "type": "array", "items": "string"},
{"name": "accounts", "type": "map", "values": "long"},
{"name": "favorite_color", "type": {"type": "enum", "name": "FavoriteColor", "symbols": ["Blue", "Yellow", "Green"]}}
{"name": "country", "type": "string", "default": "Argentina"},
{"name": "address", "type": ["null", "string"], "default": null}
]
}'
User.avro_schema_to_python()
{
"type": "record",
"name": "User",
"doc": "An User",
"namespace": "User.v1",
"aliases": ["user-v1", "super user"],
"fields": [
{"name": "name", "type": "string"},
{"name": "age", "type": "long"},
{"name": "pets", "type": {"type": "array", "items": "string", "name": "pet"}},
{"name": "accounts", "type": {"type": "map", "values": "long", "name": "account"}},
{"name": "favorite_colors", "type": {"type": "enum", "name": "FavoriteColor", "symbols": ["BLUE", "YELLOW", "GREEN"]}},
{"name": "country", "type": "string", "default": "Argentina"},
{"name": "address", "type": ["null", "string"], "default": None}
],
}
```
### Serialization to avro or avro-json and json payload
For serialization is neccesary to use python class/dataclasses instance
```python
from dataclasses import dataclass
import typing
from dataclasses_avroschema import AvroModel
@dataclass
class Address(AvroModel):
"An Address"
street: str
street_number: int
@dataclass
class User(AvroModel):
"User with multiple Address"
name: str
age: int
addresses: typing.List[Address]
address_data = {
"street": "test",
"street_number": 10,
}
# create an Address instance
address = Address(**address_data)
data_user = {
"name": "john",
"age": 20,
"addresses": [address],
}
# create an User instance
user = User(**data_user)
user.serialize()
# >>> b"\x08john(\x02\x08test\x14\x00"
user.serialize(serialization_type="avro-json")
# >>> b'{"name": "john", "age": 20, "addresses": [{"street": "test", "street_number": 10}]}'
# Get the json from the instance
user.to_json()
# >>> '{"name": "john", "age": 20, "addresses": [{"street": "test", "street_number": 10}]}'
# Get a python dict
user.to_dict()
# >>> {"name": "john", "age": 20, "addresses": [{"street": "test", "street_number": 10}]}
```
### Deserialization
Deserialization could take place with an instance dataclass or the dataclass itself. Can return the dict representation or a new class instance
```python
import typing
import dataclasses
from dataclasses_avroschema import AvroModel
@dataclasses.dataclass
class Address(AvroModel):
"An Address"
street: str
street_number: int
@dataclasses.dataclass
class User(AvroModel):
"User with multiple Address"
name: str
age: int
addresses: typing.List[Address]
avro_binary = b"\x08john(\x02\x08test\x14\x00"
avro_json_binary = b'{"name": "john", "age": 20, "addresses": [{"street": "test", "street_number": 10}]}'
# return a new class instance!!
User.deserialize(avro_binary)
# >>>> User(name='john', age=20, addresses=[Address(street='test', street_number=10)])
# return a python dict
User.deserialize(avro_binary, create_instance=False)
# >>> {"name": "john", "age": 20, "addresses": [{"street": "test", "street_number": 10}]}
# return a new class instance!!
User.deserialize(avro_json_binary, serialization_type="avro-json")
# >>>> User(name='john', age=20, addresses=[Address(street='test', street_number=10)])
# return a python dict
User.deserialize(avro_json_binary, serialization_type="avro-json", create_instance=False)
# >>> {"name": "john", "age": 20, "addresses": [{"street": "test", "street_number": 10}]}
```
## Pydantic integration
To add `dataclasses-avroschema` functionality to `pydantic` you only need to replace `BaseModel` by `AvroBaseModel`:
```python
import typing
import enum
import dataclasses
from dataclasses_avroschema.pydantic import AvroBaseModel
from pydantic import Field
class FavoriteColor(str, enum.Enum):
BLUE = "BLUE"
YELLOW = "YELLOW"
GREEN = "GREEN"
@dataclasses.dataclass
class UserAdvance(AvroBaseModel):
name: str
age: int
pets: typing.List[str] = Field(default_factory=lambda: ["dog", "cat"])
accounts: typing.Dict[str, int] = Field(default_factory=lambda: {"key": 1})
has_car: bool = False
favorite_colors: FavoriteColor = FavoriteColor.BLUE
country: str = "Argentina"
address: str = None
class Meta:
schema_doc = False
# Avro schema
UserAdvance.avro_schema()
'{
"type": "record",
"name": "UserAdvance",
"fields": [
{"name": "name", "type": "string"},
{"name": "age", "type": "long"},
{"name": "pets", "type": {"type": "array", "items": "string", "name": "pet"}, "default": ["dog", "cat"]},
{"name": "accounts", "type": {"type": "map", "values": "long", "name": "account"}, "default": {"key": 1}},
{"name": "has_car", "type": "boolean", "default": false},
{"name": "favorite_colors", "type": {"type": "enum", "name": "favorite_color", "symbols": ["BLUE", "YELLOW", "GREEN"]}, "default": "BLUE"},
{"name": "country", "type": "string", "default": "Argentina"},
{"name": "address", "type": ["null", "string"], "default": null}
]
}'
# Json schema
UserAdvance.json_schema()
{
"title": "UserAdvance",
"description": "UserAdvance(*, name: str, age: int, pets: List[str] = None, ...",
"type": "object",
"properties": {
"name": {"title": "Name", "type": "string"},
"age": {"title": "Age", "type": "integer"},
"pets": {"title": "Pets", "type": "array", "items": {"type": "string"}},
"accounts": {"title": "Accounts", "type": "object", "additionalProperties": {"type": "integer"}},
"has_car": {"title": "Has Car", "default": false, "type": "boolean"},
"favorite_colors": {"default": "BLUE", "allOf": [{"$ref": "#/definitions/FavoriteColor"}]},
"country": {"title": "Country", "default": "Argentina", "type": "string"},
"address": {"title": "Address", "type": "string"}}, "required": ["name", "age"], "definitions": {"FavoriteColor": {"title": "FavoriteColor", "description": "An enumeration.", "enum": ["BLUE", "YELLOW", "GREEN"], "type": "string"}}
}
user = UserAdvance(name="bond", age=50)
# pydantic
user.dict()
# >>> {'name': 'bond', 'age': 50, 'pets': ['dog', 'cat'], 'accounts': {'key': 1}, 'has_car': False, 'favorite_colors': <FavoriteColor.BLUE: 'BLUE'>, 'country': 'Argentina', 'address': None}
# pydantic
user.json()
# >>> '{"name": "bond", "age": 50, "pets": ["dog", "cat"], "accounts": {"key": 1}, "has_car": false, "favorite_colors": "BLUE", "country": "Argentina", "address": null}'
# pydantic
user = UserAdvance(name="bond")
# ValidationError: 1 validation error for UserAdvance
# age
# field required (type=value_error.missing)
# dataclasses-avroschema
event = user.serialize()
print(event)
# >>> b'\x08bondd\x04\x06dog\x06cat\x00\x02\x06key\x02\x00\x00\x00\x12Argentina\x00'
UserAdvance.deserialize(data=event)
# >>> UserAdvance(name='bond', age=50, pets=['dog', 'cat'], accounts={'key': 1}, has_car=False, favorite_colors=<FavoriteColor.BLUE: 'BLUE'>, country='Argentina', address=None)
```
## Examples with python streaming drivers (kafka and redis)
Under [examples](https://github.com/marcosschroh/dataclasses-avroschema/tree/master/examples) folder you can find 3 differents kafka examples, one with [aiokafka](https://github.com/aio-libs/aiokafka) (`async`) showing the simplest use case when a `AvroModel` instance is serialized and sent it thorught kafka, and the event is consumed.
The other two examples are `sync` using the [kafka-python](https://github.com/dpkp/kafka-python) driver, where the `avro-json` serialization and `schema evolution` (`FULL` compatibility) is shown.
Also, there are two `redis` examples using `redis streams` with [walrus](https://github.com/coleifer/walrus) and [redisgears-py](https://github.com/RedisGears/redisgears-py)
## Factory and fixtures
[Dataclasses Avro Schema](https://github.com/marcosschroh/dataclasses-avroschema) also includes a `factory` feature, so you can generate `fast` python instances and use them, for example, to test your data streaming pipelines. Instances can be generated using the `fake` method.
*Note*: This feature is not enabled by default and requires you have the `faker` extra installed. You may install it with `pip install 'dataclasses-avroschema[faker]'`
```python
import typing
import dataclasses
from dataclasses_avroschema import AvroModel
@dataclasses.dataclass
class Address(AvroModel):
"An Address"
street: str
street_number: int
@dataclasses.dataclass
class User(AvroModel):
"User with multiple Address"
name: str
age: int
addresses: typing.List[Address]
Address.fake()
# >>>> Address(street='PxZJILDRgbXyhWrrPWxQ', street_number=2067)
User.fake()
# >>>> User(name='VGSBbOGfSGjkMDnefHIZ', age=8974, addresses=[Address(street='vNpPYgesiHUwwzGcmMiS', street_number=4790)])
```
## Features
* [x] Primitive types: int, long, double, float, boolean, string and null support
* [x] Complex types: enum, array, map, fixed, unions and records support
* [x] `typing.Annotated` supported
* [x] `typing.Literal` supported
* [x] Logical Types: date, time (millis and micro), datetime (millis and micro), uuid support
* [X] Schema relations (oneToOne, oneToMany)
* [X] Recursive Schemas
* [X] Generate Avro Schemas from `faust.Record`
* [X] Instance serialization correspondent to `avro schema` generated
* [X] Data deserialization. Return python dict or class instance
* [X] Generate json from python class instance
* [X] Case Schemas
* [X] Generate models from `avsc` files
* [X] Examples of integration with `kafka` drivers: [aiokafka](https://github.com/aio-libs/aiokafka), [kafka-python](https://github.com/dpkp/kafka-python)
* [X] Example of integration with `redis` drivers: [walrus](https://github.com/coleifer/walrus) and [redisgears-py](https://github.com/RedisGears/redisgears-py)
* [X] Factory instances
* [X] [Pydantic](https://pydantic-docs.helpmanual.io/) integration
## Development
[Poetry](https://python-poetry.org/docs/) is needed to install the dependencies and develope locally
1. Install dependencies: `poetry install --all-extras`
2. Code linting: `./scripts/format`
3. Run tests: `./scripts/test`
For commit messages we use [commitizen](https://commitizen-tools.github.io/commitizen/) in order to standardize a way of committing rules
Raw data
{
"_id": null,
"home_page": null,
"name": "dataclasses-avroschema",
"maintainer": null,
"docs_url": null,
"requires_python": "<4.0,>=3.8",
"maintainer_email": null,
"keywords": null,
"author": "Marcos Schroh",
"author_email": "schrohm@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/96/a7/99f0b7b8af3e8ed09e33d092d9dc2bf81a9e3eedd994b0d9c5ca7c4fef3f/dataclasses_avroschema-0.60.2.tar.gz",
"platform": null,
"description": "# Dataclasses Avro Schema Generator\n\nGenerate [avro schemas](https://avro.apache.org/docs/1.8.2/spec.html) from python dataclasses. [Code generation](https://marcosschroh.github.io/dataclasses-avroschema/model_generator/) from avro schemas. [Serialize/Deserialize](https://marcosschroh.github.io/dataclasses-avroschema/serialization/) python instances with avro schemas\n\n[![Tests](https://github.com/marcosschroh/dataclasses-avroschema/actions/workflows/tests.yaml/badge.svg)](https://github.com/marcosschroh/dataclasses-avroschema/actions/workflows/tests.yaml)\n[![GitHub license](https://img.shields.io/github/license/marcosschroh/dataclasses-avroschema.svg)](https://github.com/marcosschroh/dataclasses-avroschema/blob/master/LICENSE)\n[![codecov](https://codecov.io/gh/marcosschroh/dataclasses-avroschema/branch/master/graph/badge.svg)](https://codecov.io/gh/marcosschroh/dataclasses-avroschema)\n![python version](https://img.shields.io/badge/python-3.8%2B-yellowgreen)\n\n## Requirements\n\n`python 3.8+`\n\n## Installation\n\nwith `pip` or `poetry`:\n\n`pip install dataclasses-avroschema` or `poetry add dataclasses-avroschema`\n\n### Extras\n\n- [pydantic](https://docs.pydantic.dev/): `pip install 'dataclasses-avroschema[pydantic]'` or `poetry add dataclasses-avroschema --extras \"pydantic\"`\n- [faust-streaming](https://github.com/faust-streaming/faust): `pip install 'dataclasses-avroschema[faust]'` or `poetry add dataclasses-avroschema --extras \"faust\"`\n- [faker](https://github.com/joke2k/faker): `pip install 'dataclasses-avroschema[faker]'` or `poetry add dataclasses-avroschema --extras \"faker\"`\n\n*Note*: You can install all extra dependencies with `pip install dataclasses-avroschema[faust, pydantic, faker]` or `poetry add dataclasses-avroschema --extras \"pydantic faust faker\"`\n\n### CLI\n\nTo install `avro schemas cli` install [dc-avro](https://marcosschroh.github.io/dc-avro/)\n\n`pip install 'dataclasses-avroschema[cli]'` or `poetry add dataclasses-avroschema --with cli`\n\n## Documentation\n\nhttps://marcosschroh.github.io/dataclasses-avroschema/\n\n## Usage\n\n### Generating the avro schema\n\n```python\nfrom dataclasses import dataclass\nimport enum\n\nimport typing\n\nfrom dataclasses_avroschema import AvroModel, types\n\n\nclass FavoriteColor(enum.Enum):\n BLUE = \"BLUE\"\n YELLOW = \"YELLOW\"\n GREEN = \"GREEN\"\n\n\n@dataclass\nclass User(AvroModel):\n \"An User\"\n name: str\n age: int\n pets: typing.List[str]\n accounts: typing.Dict[str, int]\n favorite_colors: FavoriteColor\n country: str = \"Argentina\"\n address: str = None\n\n class Meta:\n namespace = \"User.v1\"\n aliases = [\"user-v1\", \"super user\"]\n\nUser.avro_schema()\n\n'{\n \"type\": \"record\",\n \"name\": \"User\",\n \"doc\": \"An User\",\n \"namespace\": \"User.v1\",\n \"aliases\": [\"user-v1\", \"super user\"],\n \"fields\": [\n {\"name\": \"name\", \"type\": \"string\"},\n {\"name\": \"age\", \"type\": \"long\"},\n {\"name\": \"pets\", \"type\": \"array\", \"items\": \"string\"},\n {\"name\": \"accounts\", \"type\": \"map\", \"values\": \"long\"},\n {\"name\": \"favorite_color\", \"type\": {\"type\": \"enum\", \"name\": \"FavoriteColor\", \"symbols\": [\"Blue\", \"Yellow\", \"Green\"]}}\n {\"name\": \"country\", \"type\": \"string\", \"default\": \"Argentina\"},\n {\"name\": \"address\", \"type\": [\"null\", \"string\"], \"default\": null}\n ]\n}'\n\nUser.avro_schema_to_python()\n\n{\n \"type\": \"record\",\n \"name\": \"User\",\n \"doc\": \"An User\",\n \"namespace\": \"User.v1\",\n \"aliases\": [\"user-v1\", \"super user\"],\n \"fields\": [\n {\"name\": \"name\", \"type\": \"string\"},\n {\"name\": \"age\", \"type\": \"long\"},\n {\"name\": \"pets\", \"type\": {\"type\": \"array\", \"items\": \"string\", \"name\": \"pet\"}},\n {\"name\": \"accounts\", \"type\": {\"type\": \"map\", \"values\": \"long\", \"name\": \"account\"}},\n {\"name\": \"favorite_colors\", \"type\": {\"type\": \"enum\", \"name\": \"FavoriteColor\", \"symbols\": [\"BLUE\", \"YELLOW\", \"GREEN\"]}},\n {\"name\": \"country\", \"type\": \"string\", \"default\": \"Argentina\"},\n {\"name\": \"address\", \"type\": [\"null\", \"string\"], \"default\": None}\n ],\n}\n```\n\n### Serialization to avro or avro-json and json payload\n\nFor serialization is neccesary to use python class/dataclasses instance\n\n```python\nfrom dataclasses import dataclass\n\nimport typing\n\nfrom dataclasses_avroschema import AvroModel\n\n\n@dataclass\nclass Address(AvroModel):\n \"An Address\"\n street: str\n street_number: int\n\n\n@dataclass\nclass User(AvroModel):\n \"User with multiple Address\"\n name: str\n age: int\n addresses: typing.List[Address]\n\naddress_data = {\n \"street\": \"test\",\n \"street_number\": 10,\n}\n\n# create an Address instance\naddress = Address(**address_data)\n\ndata_user = {\n \"name\": \"john\",\n \"age\": 20,\n \"addresses\": [address],\n}\n\n# create an User instance\nuser = User(**data_user)\n\nuser.serialize()\n# >>> b\"\\x08john(\\x02\\x08test\\x14\\x00\"\n\nuser.serialize(serialization_type=\"avro-json\")\n# >>> b'{\"name\": \"john\", \"age\": 20, \"addresses\": [{\"street\": \"test\", \"street_number\": 10}]}'\n\n# Get the json from the instance\nuser.to_json()\n# >>> '{\"name\": \"john\", \"age\": 20, \"addresses\": [{\"street\": \"test\", \"street_number\": 10}]}'\n\n# Get a python dict\nuser.to_dict()\n# >>> {\"name\": \"john\", \"age\": 20, \"addresses\": [{\"street\": \"test\", \"street_number\": 10}]}\n\n```\n\n### Deserialization\n\nDeserialization could take place with an instance dataclass or the dataclass itself. Can return the dict representation or a new class instance\n\n```python\nimport typing\nimport dataclasses\n\nfrom dataclasses_avroschema import AvroModel\n\n\n@dataclasses.dataclass\nclass Address(AvroModel):\n \"An Address\"\n street: str\n street_number: int\n\n@dataclasses.dataclass\nclass User(AvroModel):\n \"User with multiple Address\"\n name: str\n age: int\n addresses: typing.List[Address]\n\navro_binary = b\"\\x08john(\\x02\\x08test\\x14\\x00\"\navro_json_binary = b'{\"name\": \"john\", \"age\": 20, \"addresses\": [{\"street\": \"test\", \"street_number\": 10}]}'\n\n# return a new class instance!!\nUser.deserialize(avro_binary)\n# >>>> User(name='john', age=20, addresses=[Address(street='test', street_number=10)])\n\n# return a python dict\nUser.deserialize(avro_binary, create_instance=False)\n# >>> {\"name\": \"john\", \"age\": 20, \"addresses\": [{\"street\": \"test\", \"street_number\": 10}]}\n\n# return a new class instance!!\nUser.deserialize(avro_json_binary, serialization_type=\"avro-json\")\n# >>>> User(name='john', age=20, addresses=[Address(street='test', street_number=10)])\n\n# return a python dict\nUser.deserialize(avro_json_binary, serialization_type=\"avro-json\", create_instance=False)\n# >>> {\"name\": \"john\", \"age\": 20, \"addresses\": [{\"street\": \"test\", \"street_number\": 10}]}\n```\n\n## Pydantic integration\n\nTo add `dataclasses-avroschema` functionality to `pydantic` you only need to replace `BaseModel` by `AvroBaseModel`:\n\n```python\nimport typing\nimport enum\nimport dataclasses\n\nfrom dataclasses_avroschema.pydantic import AvroBaseModel\n\nfrom pydantic import Field\n\n\nclass FavoriteColor(str, enum.Enum):\n BLUE = \"BLUE\"\n YELLOW = \"YELLOW\"\n GREEN = \"GREEN\"\n\n\n@dataclasses.dataclass\nclass UserAdvance(AvroBaseModel):\n name: str\n age: int\n pets: typing.List[str] = Field(default_factory=lambda: [\"dog\", \"cat\"])\n accounts: typing.Dict[str, int] = Field(default_factory=lambda: {\"key\": 1})\n has_car: bool = False\n favorite_colors: FavoriteColor = FavoriteColor.BLUE\n country: str = \"Argentina\"\n address: str = None\n\n class Meta:\n schema_doc = False\n\n\n# Avro schema\nUserAdvance.avro_schema()\n'{\n \"type\": \"record\",\n \"name\": \"UserAdvance\",\n \"fields\": [\n {\"name\": \"name\", \"type\": \"string\"},\n {\"name\": \"age\", \"type\": \"long\"},\n {\"name\": \"pets\", \"type\": {\"type\": \"array\", \"items\": \"string\", \"name\": \"pet\"}, \"default\": [\"dog\", \"cat\"]},\n {\"name\": \"accounts\", \"type\": {\"type\": \"map\", \"values\": \"long\", \"name\": \"account\"}, \"default\": {\"key\": 1}},\n {\"name\": \"has_car\", \"type\": \"boolean\", \"default\": false},\n {\"name\": \"favorite_colors\", \"type\": {\"type\": \"enum\", \"name\": \"favorite_color\", \"symbols\": [\"BLUE\", \"YELLOW\", \"GREEN\"]}, \"default\": \"BLUE\"},\n {\"name\": \"country\", \"type\": \"string\", \"default\": \"Argentina\"},\n {\"name\": \"address\", \"type\": [\"null\", \"string\"], \"default\": null}\n ]\n}'\n\n# Json schema\nUserAdvance.json_schema()\n\n{\n \"title\": \"UserAdvance\",\n \"description\": \"UserAdvance(*, name: str, age: int, pets: List[str] = None, ...\",\n \"type\": \"object\",\n \"properties\": {\n \"name\": {\"title\": \"Name\", \"type\": \"string\"},\n \"age\": {\"title\": \"Age\", \"type\": \"integer\"},\n \"pets\": {\"title\": \"Pets\", \"type\": \"array\", \"items\": {\"type\": \"string\"}},\n \"accounts\": {\"title\": \"Accounts\", \"type\": \"object\", \"additionalProperties\": {\"type\": \"integer\"}},\n \"has_car\": {\"title\": \"Has Car\", \"default\": false, \"type\": \"boolean\"},\n \"favorite_colors\": {\"default\": \"BLUE\", \"allOf\": [{\"$ref\": \"#/definitions/FavoriteColor\"}]},\n \"country\": {\"title\": \"Country\", \"default\": \"Argentina\", \"type\": \"string\"},\n \"address\": {\"title\": \"Address\", \"type\": \"string\"}}, \"required\": [\"name\", \"age\"], \"definitions\": {\"FavoriteColor\": {\"title\": \"FavoriteColor\", \"description\": \"An enumeration.\", \"enum\": [\"BLUE\", \"YELLOW\", \"GREEN\"], \"type\": \"string\"}}\n}\n\nuser = UserAdvance(name=\"bond\", age=50)\n\n# pydantic\nuser.dict()\n# >>> {'name': 'bond', 'age': 50, 'pets': ['dog', 'cat'], 'accounts': {'key': 1}, 'has_car': False, 'favorite_colors': <FavoriteColor.BLUE: 'BLUE'>, 'country': 'Argentina', 'address': None}\n\n# pydantic\nuser.json()\n# >>> '{\"name\": \"bond\", \"age\": 50, \"pets\": [\"dog\", \"cat\"], \"accounts\": {\"key\": 1}, \"has_car\": false, \"favorite_colors\": \"BLUE\", \"country\": \"Argentina\", \"address\": null}'\n\n# pydantic\nuser = UserAdvance(name=\"bond\")\n\n# ValidationError: 1 validation error for UserAdvance\n# age\n# field required (type=value_error.missing)\n\n\n# dataclasses-avroschema\nevent = user.serialize()\nprint(event)\n# >>> b'\\x08bondd\\x04\\x06dog\\x06cat\\x00\\x02\\x06key\\x02\\x00\\x00\\x00\\x12Argentina\\x00'\n\nUserAdvance.deserialize(data=event)\n# >>> UserAdvance(name='bond', age=50, pets=['dog', 'cat'], accounts={'key': 1}, has_car=False, favorite_colors=<FavoriteColor.BLUE: 'BLUE'>, country='Argentina', address=None)\n```\n\n## Examples with python streaming drivers (kafka and redis)\n\nUnder [examples](https://github.com/marcosschroh/dataclasses-avroschema/tree/master/examples) folder you can find 3 differents kafka examples, one with [aiokafka](https://github.com/aio-libs/aiokafka) (`async`) showing the simplest use case when a `AvroModel` instance is serialized and sent it thorught kafka, and the event is consumed.\nThe other two examples are `sync` using the [kafka-python](https://github.com/dpkp/kafka-python) driver, where the `avro-json` serialization and `schema evolution` (`FULL` compatibility) is shown.\nAlso, there are two `redis` examples using `redis streams` with [walrus](https://github.com/coleifer/walrus) and [redisgears-py](https://github.com/RedisGears/redisgears-py)\n\n## Factory and fixtures\n\n[Dataclasses Avro Schema](https://github.com/marcosschroh/dataclasses-avroschema) also includes a `factory` feature, so you can generate `fast` python instances and use them, for example, to test your data streaming pipelines. Instances can be generated using the `fake` method.\n\n*Note*: This feature is not enabled by default and requires you have the `faker` extra installed. You may install it with `pip install 'dataclasses-avroschema[faker]'`\n\n\n```python\nimport typing\nimport dataclasses\n\nfrom dataclasses_avroschema import AvroModel\n\n\n@dataclasses.dataclass\nclass Address(AvroModel):\n \"An Address\"\n street: str\n street_number: int\n\n\n@dataclasses.dataclass\nclass User(AvroModel):\n \"User with multiple Address\"\n name: str\n age: int\n addresses: typing.List[Address]\n\n\nAddress.fake()\n# >>>> Address(street='PxZJILDRgbXyhWrrPWxQ', street_number=2067)\n\nUser.fake()\n# >>>> User(name='VGSBbOGfSGjkMDnefHIZ', age=8974, addresses=[Address(street='vNpPYgesiHUwwzGcmMiS', street_number=4790)])\n```\n\n## Features\n\n* [x] Primitive types: int, long, double, float, boolean, string and null support\n* [x] Complex types: enum, array, map, fixed, unions and records support\n* [x] `typing.Annotated` supported\n* [x] `typing.Literal` supported\n* [x] Logical Types: date, time (millis and micro), datetime (millis and micro), uuid support\n* [X] Schema relations (oneToOne, oneToMany)\n* [X] Recursive Schemas\n* [X] Generate Avro Schemas from `faust.Record`\n* [X] Instance serialization correspondent to `avro schema` generated\n* [X] Data deserialization. Return python dict or class instance\n* [X] Generate json from python class instance\n* [X] Case Schemas\n* [X] Generate models from `avsc` files\n* [X] Examples of integration with `kafka` drivers: [aiokafka](https://github.com/aio-libs/aiokafka), [kafka-python](https://github.com/dpkp/kafka-python)\n* [X] Example of integration with `redis` drivers: [walrus](https://github.com/coleifer/walrus) and [redisgears-py](https://github.com/RedisGears/redisgears-py)\n* [X] Factory instances\n* [X] [Pydantic](https://pydantic-docs.helpmanual.io/) integration\n\n## Development\n\n[Poetry](https://python-poetry.org/docs/) is needed to install the dependencies and develope locally\n\n1. Install dependencies: `poetry install --all-extras`\n2. Code linting: `./scripts/format`\n3. Run tests: `./scripts/test`\n\nFor commit messages we use [commitizen](https://commitizen-tools.github.io/commitizen/) in order to standardize a way of committing rules\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Generate Avro Schemas from Python classes. Serialize/Deserialize python instances with avro schemas",
"version": "0.60.2",
"project_urls": null,
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "bb81df01c0d7134c1eaf272cca527f1ac0b3ff212c27c156eac69d6f9cd37f3b",
"md5": "da18d0d17003504ed572e707ce36138b",
"sha256": "5552ef2bf76d490ac6d3029371b5224a5af301bb7e20a9a3f0192e419bc47eec"
},
"downloads": -1,
"filename": "dataclasses_avroschema-0.60.2-py3-none-any.whl",
"has_sig": false,
"md5_digest": "da18d0d17003504ed572e707ce36138b",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<4.0,>=3.8",
"size": 50789,
"upload_time": "2024-06-07T13:27:49",
"upload_time_iso_8601": "2024-06-07T13:27:49.522607Z",
"url": "https://files.pythonhosted.org/packages/bb/81/df01c0d7134c1eaf272cca527f1ac0b3ff212c27c156eac69d6f9cd37f3b/dataclasses_avroschema-0.60.2-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "96a799f0b7b8af3e8ed09e33d092d9dc2bf81a9e3eedd994b0d9c5ca7c4fef3f",
"md5": "9da4342aba3ebf9506fe6b919e0db2a7",
"sha256": "b72b9cf819a1f795c77c10e8a150073ec0d754f88e79b18079473b7a32d15cc6"
},
"downloads": -1,
"filename": "dataclasses_avroschema-0.60.2.tar.gz",
"has_sig": false,
"md5_digest": "9da4342aba3ebf9506fe6b919e0db2a7",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<4.0,>=3.8",
"size": 39430,
"upload_time": "2024-06-07T13:27:52",
"upload_time_iso_8601": "2024-06-07T13:27:52.216616Z",
"url": "https://files.pythonhosted.org/packages/96/a7/99f0b7b8af3e8ed09e33d092d9dc2bf81a9e3eedd994b0d9c5ca7c4fef3f/dataclasses_avroschema-0.60.2.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-06-07 13:27:52",
"github": false,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"lcname": "dataclasses-avroschema"
}