Last active
July 4, 2023 23:14
-
-
Save viniciusao/4861a111eb2ab51b06d535e5623e2dbe to your computer and use it in GitHub Desktop.
typing.NamedTuple with pydantic.
This file contains 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
from contextlib import suppress | |
from typing import NamedTuple | |
from pydantic import create_model_from_namedtuple, BaseModel, root_validator | |
class FunctionNumber101(NamedTuple): | |
width: float | |
height: float | |
def area(cls, values=None): | |
try: | |
values = cls._asdict() | |
except AttributeError: | |
values = {x: y for x, y in zip(cls.__fields__, values.values())} | |
if values['width'] <= 0 or values['height'] <= 0: | |
raise ValueError("width and height must be positive") | |
if not hasattr(cls, '__fields__'): | |
return values['width'] * values['height'] | |
return values | |
def namedtuple_to_basemodel(nt, *args): | |
nt_methods = {} | |
nt_input = {x: y for x, y in zip(nt._fields, args)} | |
tuple_methods = 'count', 'index' | |
for method_name in dir(nt): | |
method = getattr(nt, method_name) | |
callable_ = callable(method) | |
not_tuple_method = method_name not in tuple_methods | |
if method_name.isalpha() and callable_ and not_tuple_method: | |
nt_methods[method_name] = root_validator(method) | |
pydantic_model = create_model_from_namedtuple(nt, __validators__=nt_methods) | |
return pydantic_model(**nt_input) | |
def get_rectangle_area(width: float, height: float): | |
model = namedtuple_to_basemodel(FunctionNumber101, width, height) | |
assert isinstance(model, BaseModel) | |
get_rectangle_area(10, 1) | |
square = FunctionNumber101(10, 10) | |
assert square.area() == 100 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment