Skip to content

Instantly share code, notes, and snippets.

@robyoung
Last active September 7, 2020 08:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save robyoung/20ef875103def4a5ead291e01b80f648 to your computer and use it in GitHub Desktop.
Save robyoung/20ef875103def4a5ead291e01b80f648 to your computer and use it in GitHub Desktop.
Auto-generate pydantic models
from typing import Optional
import pydantic
def _create_model(name, dct, annotations):
return type(
name,
(pydantic.BaseModel,),
{"__qualname__": name, "__annotations__": annotations, **dct},
)
def _optionalise(annotations):
return {name: Optional[value] for name, value in annotations.items()}
class MyMetaclass(type):
def __new__(cls, name, bases, dct):
annotations = dct.pop("__annotations__")
qual_name = dct.pop("__qualname__")
model = super().__new__(
cls,
name,
bases,
{
"Create": _create_model(f"Create{name}", dct, annotations),
"Update": _create_model(f"Update{name}", dct, _optionalise(annotations)),
"Get": _create_model(f"Get{name}", dct, {"id": int, **annotations}),
"__annotations__": annotations,
"__qualname__": qual_name,
},
)
return model
class User(metaclass=MyMetaclass):
name: str
age: int
def main():
create_data = {"name": "dave", "age": 31}
update_data = {"age": 32}
get_data = {"id": 123, **create_data}
create_user = User.Create(**create_data)
update_user = User.Update(**update_data)
get_user = User.Get(**get_data)
breakpoint()
print("")
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment