Pydantic: Dynamically creating a model, with field types, examples and descriptions.

Pydantic: Dynamically creating a model, with field types, examples and descriptions.

Normally, Pydantic models are hard-coded and cannot change at runtime. However it is also possibly to build a Pydantic model 'on the fly'.

Here is a function to dynamically create a Pydantic model. Each field has a type, description and some examples:

from typing import Any, Tuple
from pydantic import BaseModel, Field, create_model

FieldDetails = Tuple[type, str, list[Any]]  # field type, description, examples

def create_dynamic_model(model_name:str, fields_dict: dict[str, FieldDetails]) -> type[BaseModel]:
    """
    Create a dynamic Pydantic model based on the provided fields dictionary.
    - why: we want to read the examples from example_store, not hard-code them.
   
    :param fields_dict: A dictionary where keys are field names and values are tuples of (type, description, examples)
    :return: A dynamically created Pydantic model
    """
    return create_model(
        model_name,
        **{
            field_name: (field_type, Field(..., description=field_desc, examples=examples))
            for field_name, (field_type, field_desc, examples) in fields_dict.items()
        }
    )

Example usage:

if __name__ == "__main__":
    # Define the fields for our dynamic model
    fields = {
        "name": (str, "The name of the person", ["Bob"]),
        "age": (int, "The age of the person", 54),
        "email": (str, "The email address of the person", "bob@hotmail.com"),
        "is_student": (bool, "Whether the person is a student or not", False),
    }

    # Create the dynamic model
    DynamicPerson = create_dynamic_model("Person", fields)

    # Create an instance of the model
    person = DynamicPerson(
        name="John Doe",
        age=30,
        email="john.doe@example.com",
        is_student=False,
    )

    # Print the model's schema
    print(DynamicPerson.schema_json(indent=2))

    # Print the instance
    print(person)

    # Access fields and their descriptions
    for field_name, field in DynamicPerson.model_fields.items():
        print(f"Field: {field_name}, Description: {field.description}")




Comments