Created
November 5, 2023 13:42
-
-
Save pietz/b07c3220abe7dd54cf4ab7c7713b9011 to your computer and use it in GitHub Desktop.
Create a Pydantic Model from a JSON schema
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Schema(BaseModel): | |
title: str = "Model" | |
type: Any | |
properties: Optional[dict[str, Any]] | |
required: Optional[list[str]] | |
items: Optional['Schema'] | |
description: Optional[str] | |
@validator('type', pre=True) | |
def map_type(cls, v): | |
mapping = { | |
"string": str, | |
"number": float, | |
"integer": int, | |
"boolean": bool, | |
"object": dict, | |
"array": list, | |
"null": type(None), | |
} | |
return mapping.get(v, Any) | |
def to_model(self) -> BaseModel: | |
fields = {} | |
if self.properties: | |
for name, prop in self.properties.items(): | |
schema = Schema(**prop) | |
if schema.type == dict: | |
model = schema.to_model() | |
elif schema.type == list and schema.items: | |
if schema.items.type == dict: | |
model = list[schema.items.to_model()] | |
else: | |
model = list[schema.items.type] | |
else: | |
model = schema.type | |
default = ... if name not in self.required else None | |
field = Field(default, description=schema.description) | |
fields[name] = (model, field) | |
return create_model(self.title, **fields) | |
Schema.update_forward_refs() | |
# Note: Doesn't work with `$ref` fields | |
# | |
# with open("schema.json") as f: | |
# json_schema = json.load(f) | |
# schema = Schema(json_schema) | |
# PydanticModel = schema.to_model() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment