# Copyright 2022 J.P. Morgan Chase & Co.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.
"""
Generate Apache Avro schemas for Python types including standard library data-classes and Pydantic data models.
The main API is a single function, :func:`generate`. Its first argument is the Python type or class to generate the Avro
schema for.
.. seealso::
Data types supported by **py-avro-schema**: :doc:`types`.
"""
import importlib.metadata
from typing import Optional, Type
import memoization
import orjson
from py_avro_schema._schemas import JSON_OPTIONS, Option, TypeNotSupportedError, schema
from py_avro_schema._typing import DecimalMeta, DecimalType
#: Library version, e.g. 1.0.0, taken from Git tags
__version__ = importlib.metadata.version("py-avro-schema")
__all__ = [
"DecimalMeta",
"DecimalType",
"Option",
"TypeNotSupportedError",
"generate",
]
[docs]
@memoization.cached
def generate(
py_type: Type,
*,
namespace: Optional[str] = None,
options: Option = Option(0),
) -> bytes:
"""
Return an Avro schema as a JSON-formatted bytestring for a given Python class or instance
This function is cached and can be called repeatedly with the same arguments without any performance penalty.
:param py_type: The Python class to generate a schema for.
:param namespace: The Avro namespace to add to schemas.
:param options: Schema generation options as defined by :class:`Option` enum values. Specify multiple values like
this: ``Option.INT_32 | Option.FLOAT_32``.
"""
schema_dict = schema(py_type, namespace=namespace, options=options)
json_options = 0
for opt in JSON_OPTIONS:
if opt in options:
json_options |= opt.value
schema_json = orjson.dumps(schema_dict, option=json_options)
return schema_json