pydantic-avro 0.9.3__tar.gz → 0.10.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pydantic_avro-0.9.3 → pydantic_avro-0.10.0}/PKG-INFO +1 -1
- {pydantic_avro-0.9.3 → pydantic_avro-0.10.0}/pyproject.toml +1 -1
- {pydantic_avro-0.9.3 → pydantic_avro-0.10.0}/setup.py +1 -1
- pydantic_avro-0.10.0/src/pydantic_avro/__init__.py +3 -0
- {pydantic_avro-0.9.3 → pydantic_avro-0.10.0}/src/pydantic_avro/to_avro/types.py +34 -4
- pydantic_avro-0.9.3/src/pydantic_avro/__init__.py +0 -1
- {pydantic_avro-0.9.3 → pydantic_avro-0.10.0}/LICENSE +0 -0
- {pydantic_avro-0.9.3 → pydantic_avro-0.10.0}/README.md +0 -0
- {pydantic_avro-0.9.3 → pydantic_avro-0.10.0}/src/pydantic_avro/__main__.py +0 -0
- {pydantic_avro-0.9.3 → pydantic_avro-0.10.0}/src/pydantic_avro/base.py +0 -0
- {pydantic_avro-0.9.3 → pydantic_avro-0.10.0}/src/pydantic_avro/from_avro/__init__.py +0 -0
- {pydantic_avro-0.9.3 → pydantic_avro-0.10.0}/src/pydantic_avro/from_avro/avro_to_pydantic.py +0 -0
- {pydantic_avro-0.9.3 → pydantic_avro-0.10.0}/src/pydantic_avro/from_avro/class_registery.py +0 -0
- {pydantic_avro-0.9.3 → pydantic_avro-0.10.0}/src/pydantic_avro/from_avro/types.py +0 -0
- {pydantic_avro-0.9.3 → pydantic_avro-0.10.0}/src/pydantic_avro/py.typed +0 -0
- {pydantic_avro-0.9.3 → pydantic_avro-0.10.0}/src/pydantic_avro/to_avro/__init__.py +0 -0
- {pydantic_avro-0.9.3 → pydantic_avro-0.10.0}/src/pydantic_avro/to_avro/base.py +0 -0
- {pydantic_avro-0.9.3 → pydantic_avro-0.10.0}/src/pydantic_avro/to_avro/config.py +0 -0
|
@@ -18,7 +18,7 @@ entry_points = \
|
|
|
18
18
|
|
|
19
19
|
setup_kwargs = {
|
|
20
20
|
'name': 'pydantic-avro',
|
|
21
|
-
'version': '0.
|
|
21
|
+
'version': '0.10.0',
|
|
22
22
|
'description': 'Converting pydantic classes to avro schemas',
|
|
23
23
|
'long_description': '[](https://github.com/godatadriven/pydantic-avro/actions/workflows/python-package.yml)\n[](https://codecov.io/gh/godatadriven/pydantic-avro)\n[](https://badge.fury.io/py/pydantic-avro)\n[](https://github.com/godatadriven/pydantic-avro/actions/workflows/codeql-analysis.yml)\n\n# pydantic-avro\n\nThis library can convert a pydantic class to a avro schema or generate python code from a avro schema.\n\n### Install\n\n```bash\npip install pydantic-avro\n```\n\n### Pydantic class to avro schema\n\n```python\nimport json\nfrom typing import Optional\n\nfrom pydantic_avro.base import AvroBase\n\n\nclass TestModel(AvroBase):\n key1: str\n key2: int\n key2: Optional[str]\n\n\nschema_dict: dict = TestModel.avro_schema()\nprint(json.dumps(schema_dict))\n\n```\n\n### Avro schema to pydantic\n\n```shell\n# Print to stdout\npydantic-avro avro_to_pydantic --asvc /path/to/schema.asvc\n\n# Save it to a file\npydantic-avro avro_to_pydantic --asvc /path/to/schema.asvc --output /path/to/output.py\n```\n\n### Specify expected Avro type\n\n```python\nfrom datetime import datetime\nfrom pydantic import Field\nfrom pydantic_avro.base import AvroBase \n\nclass ExampleModel(AvroBase):\n field1: int = Field(..., avro_type="long") # Explicitly set Avro type to "long"\n field2: datetime = Field(..., avro_type="timestamp-millis") # Explicitly set Avro type to "timestamp-millis"\n```\n\n### Install for developers\n\n###### Install package\n\n- Requirement: Poetry 1.*\n\n```shell\npoetry install\n```\n\n###### Run unit tests\n```shell\npytest\ncoverage run -m pytest # with coverage\n# or (depends on your local env) \npoetry run pytest\npoetry run coverage run -m pytest # with coverage\n```\n\n##### Run linting\n\nThe linting is checked in the github workflow. To fix and review issues run this:\n```shell\nblack . # Auto fix all issues\nisort . # Auto fix all issues\npflake . # Only display issues, fixing is manual\n```\n',
|
|
24
24
|
'author': "Peter van 't Hof'",
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from copy import deepcopy
|
|
1
2
|
from typing import Any, Dict, List, Optional, Set
|
|
2
3
|
|
|
3
4
|
from pydantic_avro.to_avro.config import DEFS_NAME
|
|
@@ -133,6 +134,13 @@ class AvroTypeConverter:
|
|
|
133
134
|
f = field_props.get("format")
|
|
134
135
|
r = field_props.get("$ref")
|
|
135
136
|
at = field_props.get("avro_type")
|
|
137
|
+
|
|
138
|
+
# For Pydantic v1, check json_schema_extra for avro_type
|
|
139
|
+
if at is None and "json_schema_extra" in field_props:
|
|
140
|
+
json_schema_extra = field_props.get("json_schema_extra")
|
|
141
|
+
if isinstance(json_schema_extra, dict):
|
|
142
|
+
at = json_schema_extra.get("avro_type")
|
|
143
|
+
|
|
136
144
|
if "allOf" in field_props and len(field_props["allOf"]) == 1:
|
|
137
145
|
r = field_props["allOf"][0]["$ref"]
|
|
138
146
|
if ("prefixItems" in field_props or ("minItems" in field_props and "maxItems" in field_props)) and t == "array":
|
|
@@ -142,9 +150,9 @@ class AvroTypeConverter:
|
|
|
142
150
|
discriminator = field_props.get("discriminator")
|
|
143
151
|
|
|
144
152
|
if u is not None:
|
|
145
|
-
return self._union_to_avro(u, avro_type_dict, discriminator)
|
|
153
|
+
return self._union_to_avro(u, avro_type_dict, discriminator, parent_avro_type=at)
|
|
146
154
|
elif o is not None:
|
|
147
|
-
return self._union_to_avro(o, avro_type_dict, discriminator)
|
|
155
|
+
return self._union_to_avro(o, avro_type_dict, discriminator, parent_avro_type=at)
|
|
148
156
|
elif r is not None:
|
|
149
157
|
return self._handle_references(r, avro_type_dict)
|
|
150
158
|
elif t is None:
|
|
@@ -232,15 +240,37 @@ class AvroTypeConverter:
|
|
|
232
240
|
value_type = self._get_avro_type_dict(a)["type"]
|
|
233
241
|
return {"type": "map", "values": value_type}
|
|
234
242
|
|
|
235
|
-
def
|
|
243
|
+
def _should_propagate_avro_type(self, union_element: dict, parent_avro_type: str) -> bool:
|
|
244
|
+
"""Determine if parent avro_type should be propagated to this union element"""
|
|
245
|
+
# Don't propagate to null types or elements that already have avro_type
|
|
246
|
+
if union_element.get("type") == "null" or "avro_type" in union_element:
|
|
247
|
+
return False
|
|
248
|
+
|
|
249
|
+
element_format = union_element.get("format")
|
|
250
|
+
|
|
251
|
+
# Only propagate temporal avro_types to date-time formatted elements
|
|
252
|
+
temporal_avro_types = {"timestamp-millis", "timestamp-micros", "time-millis", "time-micros", "date"}
|
|
253
|
+
if parent_avro_type in temporal_avro_types:
|
|
254
|
+
return element_format in {"date-time", "date", "time"}
|
|
255
|
+
|
|
256
|
+
# For other avro_types, only propagate if there's no format (meaning it's not already specialized)
|
|
257
|
+
return element_format is None
|
|
258
|
+
|
|
259
|
+
def _union_to_avro(self, field_props: list, avro_type_dict: dict, discriminator: Optional[dict] = None, parent_avro_type: Optional[str] = None) -> dict:
|
|
236
260
|
"""Returns a type of a union field, including discriminated unions"""
|
|
237
261
|
# Handle discriminated unions
|
|
238
262
|
if discriminator is not None:
|
|
239
263
|
return self._discriminated_union_to_avro(field_props, avro_type_dict, discriminator)
|
|
240
264
|
|
|
241
|
-
# Standard union handling
|
|
265
|
+
# Standard union handling
|
|
242
266
|
avro_type_dict["type"] = []
|
|
243
267
|
for union_element in field_props:
|
|
268
|
+
# Propagate parent avro_type to compatible union elements
|
|
269
|
+
if parent_avro_type is not None and self._should_propagate_avro_type(union_element, parent_avro_type):
|
|
270
|
+
# Create a deep copy to avoid modifying the original
|
|
271
|
+
union_element = deepcopy(union_element)
|
|
272
|
+
union_element["avro_type"] = parent_avro_type
|
|
273
|
+
|
|
244
274
|
t = self._get_avro_type_dict(union_element)
|
|
245
275
|
avro_type_dict["type"].append(t["type"])
|
|
246
276
|
return avro_type_dict
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
from pydantic_avro.to_avro.base import AvroBase
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pydantic_avro-0.9.3 → pydantic_avro-0.10.0}/src/pydantic_avro/from_avro/avro_to_pydantic.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|