Skip to content

Instantly share code, notes, and snippets.

@h55nick
Created May 8, 2024 18:04
Show Gist options
  • Save h55nick/0e1d48b72ab9c5db33b89ba0443f41e7 to your computer and use it in GitHub Desktop.
Save h55nick/0e1d48b72ab9c5db33b89ba0443f41e7 to your computer and use it in GitHub Desktop.
def create_pydantic_model_from_json_schema(klass, schema):
"""
Creates a Pydantic model from a JSON schema.
"""
fields = {}
for prop_name, prop_info in schema['properties'].items():
field_type = prop_info.get('type', 'default') # if no type, then it's the default?
py_type = None
if field_type == 'default' or prop_name in ['properties', 'required', 'default', 'additionalProperties']:
continue
if field_type == 'array':
item_type = prop_info['items']['type']
if item_type == 'object':
py_type = list[create_pydantic_model_from_json_schema(f"{klass}_{prop_name}", prop_info['items'])]
else:
py_type = list[BASIC_TYPE_MAP.get(item_type, None)]
elif field_type == 'object':
if prop_info.get('properties', None):
py_type = create_pydantic_model_from_json_schema(f"{klass}_{prop_name}", prop_info)
elif prop_info.get('$ref'):
# NOTE: We probably need to make this more robust
ref_info = schema['properties'].get(prop_info['$ref'].split("/")[-1])
py_type = create_pydantic_model_from_json_schema(f"{klass}_{prop_name}", ref_info)
elif prop_info.get('additionalProperties', {}).get('$ref', None):
ref_info = schema['properties'].get(prop_info['additionalProperties']['$ref'].split("/")[-1])
py_type = dict[str, create_pydantic_model_from_json_schema(f"{klass}_{prop_name}", ref_info)]
else:
raise Exception(f"Object Error, {py_type} {prop_name} for {field_type}")
elif BASIC_TYPE_MAP.get(field_type):
py_type = BASIC_TYPE_MAP[field_type]
if py_type is None:
raise Exception(f"Error, {py_type} for {field_type}")
default = prop_info.get('default', ...) if prop_name in schema.get('required', []) else ...
description = prop_info.get('description', '')
fields[prop_name] = (py_type, Field(default, description=description))
return create_model(klass, **fields)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment