Generate Pydantic Schema
The GeneratePydanticSchema class was developed to make it easier to dynamically create Pydantic models from nested Python dictionaries.
On this page
#Overview
The GeneratePydanticSchema class was developed to make it easier to dynamically create Pydantic models from nested Python dictionaries. In scenarios where complex, structured data is received, such as in APIs or systems that deal with various JSON structures, this class automates the generation of Pydantic schemas, used for validating, converting and documenting those structures.
The problem the class solves is the manual, repetitive need to create Pydantic models for each complex data structure, which often varies in depth and format. By using this class, the developer passes in a data dictionary and gets a Pydantic model that exactly reflects the structure and types of that data, including nested schemas for inner objects and lists.
In practice, it can be used to validate input data, generate examples for automatic documentation or build adaptive interfaces in systems that consume dynamic data.
#Execution Flow
- The user instantiates the
GeneratePydanticSchemaclass, and may optionally provide aFieldMetadataParserobject to customize the extraction of field metadata. - The
convert()method is called with a Python dictionary representing the data to be modeled and a root name for the model (default "RootModel"). - The class recursively analyzes each key and value of the dictionary:
- For scalar fields, it determines the basic type.
- For nested dictionaries, it generates a new Pydantic model with a unique automatic name.
- For lists, it analyzes the type of the first element to define the type of the items in the list, generating models for objects if necessary.
- Fields receive metadata (description) generated automatically or through the analysis by the
metadata_parser. - All generated models are stored internally and can be retrieved with the
get_models()method. - If an error occurs during conversion, a
RuntimeErrorexception is raised with the error details.
#Class Methods Table
| Method | Description |
|---|---|
__init__ | Initializes the class with an optional metadata parser. |
convert | Converts a dictionary into a root Pydantic model. |
get_models | Returns all the Pydantic models generated so far. |
_generate_name | Generates unique names for nested models. |
_create_model | Creates a Pydantic model from defined fields. |
_resolve_type | Deduces the base type of the received value. |
_parse_object | Recursively builds Pydantic models for objects. |
_parse_field | Analyzes the type and metadata of an individual field. |
#Key Architecture Points and Insights
- Dynamic generation takes advantage of Pydantic's
create_modelmethod to create classes at runtime, making it easier to create models that are not known at coding time. - Recursive use allows the creation of nested models that reflect the complex structure of the input data.
- The incremental counter ensures unique names for the auxiliary models, avoiding collisions.
- The class depends on
FieldMetadataParserto enrich the fields with metadata, creating a separation that favors customization and extensibility of field analysis. - The specific handling of lists, with the attempt to singularize names (presumably using
inflector.singular_noun), shows attention to the naming of the models. - Careful handling of exceptions during parsing and conversion, recording the error message and keeping usability by exposing clear errors to the user.
- Internally, storing the models in a dictionary allows later lookup and reuse.
#Class and Methods Description
#GeneratePydanticSchema Class
#Description
This class has the role of converting complex, nested dictionaries into Pydantic models programmatically. It automates the generation of validation schemas that faithfully reflect the structure of the input data, with support for nested fields, lists and integration with a metadata parser to enrich the description of the fields.
Its use is recommended for dynamic validation scenarios and for building APIs or systems that receive diverse JSON data and need strong, explicit validation.
#Constructor Arguments
| Argument | Type | Description | Default Value |
|---|---|---|---|
metadata_parser | FieldMetadataParser | Object for analyzing and extracting field metadata. | New instance of FieldMetadataParser |
#Methods
#1. __init__
Description
Initializes the class instance, setting the metadata parser and preparing the internal storage for the generated models.
Arguments
metadata_parser(FieldMetadataParser): Optional parser for metadata extraction.
Returns
- Returns no value.
Raises
- None.
Examples
schema_generator = GeneratePydanticSchema()#2. convert
Description
Receives a Python dictionary and converts it into a root Pydantic model, automatically generating all the nested models needed for full validation of the structure.
Arguments
data(Dict[str, Any]): Data dictionary to be converted into a model.root_name(str): Name of the root model to be created. Default is "RootModel".
Returns
Type[BaseModel]: Pydantic model generated for the given dictionary.
Raises
RuntimeError: If an error occurs during data conversion.
Examples
data = {
"nome": "João",
"idade": 30,
"endereco": {
"rua": "Av. Brasil",
"numero": 100
}
}
model = schema_generator.convert(data, root_name="Pessoa")
# model agora é uma classe Pydantic com campos nome, idade e endereco (que é outro modelo)#3. get_models
Description
Returns all the Pydantic models created so far, including nested models generated during data conversion.
Arguments
None.
Returns
Dict[str, Type[BaseModel]]: Dictionary with the model names as keys and Pydantic classes as values.
Raises
None.
Examples
all_models = schema_generator.get_models()
# Pode acessar, por exemplo, all_models["Pessoa1"] para um modelo aninhado#4. _generate_name
Description
Generates a unique name for nested Pydantic models, combining a name base with an incremental counter.
Arguments
base(str): Base name for the model.
Returns
str: Unique generated name, e.g. "Endereco1".
Raises
None.
Examples
nome = schema_generator._generate_name("endereco")
# "Endereco1"#5. _create_model
Description
Dynamically creates a Pydantic model from a given name and fields, storing it in the internal dictionary.
Arguments
name(str): Name of the model.fields(Dict[str, Tuple[Any, Any]]): Mapping of fields to tuples (type, metadata).
Returns
Type[BaseModel]: Pydantic model created.
Raises
None.
Examples
fields = {
"nome": (str, ...),
"idade": (int, ...)
}
model = schema_generator._create_model("Pessoa", fields)#6. _resolve_type
Description
Determines the basic Pydantic type of a simple Python value.
Arguments
value(Any): Value whose type must be deduced.
Returns
Any: Corresponding Python type (str,bool,int,float,list,dictorAnyas a fallback).
Raises
None.
Examples
t = schema_generator._resolve_type(10) # int
t2 = schema_generator._resolve_type("hi") # str#7. _parse_object
Description
Analyzes a dictionary and creates a Pydantic model for it, recursively processing all the fields of the object.
Arguments
obj(Dict[str, Any]): Dictionary to be parsed.name(str): Name of the model to be created.
Returns
Type[BaseModel]: Pydantic model created for the analyzed object.
Raises
None.
Examples
model = schema_generator._parse_object({"a": 1, "b": "x"}, "SimpleModel")#8. _parse_field
Description
Determines the type and metadata for an individual field, handling the cases of dictionaries, lists and scalar values and applying custom analysis via metadata_parser.
Arguments
key(str): Name of the field.value(Any): Value of the field for type deduction.
Returns
Tuple[Any, Any]: Tuple with the field type and theFieldinstance containing metadata for Pydantic.
Raises
RuntimeError: If there is an error during parsing, it wraps the original error.
Examples
if __name__ == "__main__":
json_data = {
"script": {
"setting": {
"type": "str",
"description": "Onde o filme acontece",
"example": "Tokyo"
},
"genre": {
"type": "str",
"description": "Gênero do filme",
"example": "Heist"
},
"storyline": "A big robbery"
},
"context": {
"year": {
"type": "int",
"description": "Ano da história",
"example": 2025
}
},
"people": {
"characters": [
{
"name": {
"type": "str",
"description": "Nome do personagem"
},
"role": "protagonist"
}
]
}
}
converter = JsonToPydantic()
Movie = converter.convert(json_data, "Movie")
print(Movie.schema_json(indent=2))
# python -m src.content_parse.pydantic_shemaThis documentation offers a detailed guide for programmers to understand and use the GeneratePydanticSchema class in a practical and efficient way, ensuring fast and correct generation of Pydantic models for validating and manipulating complex data.
Source: src/content_parse/pydantic_schema.py