I am quite new to Pydantic. I have noticed how it is often used in validating input to FastAPI.
I have a project where I need to send something to another application's API endpoint and thought I would try structuring my data via a model class that inherits from Pydantic's BaseModel
.
I try something like this (MWE):
from uuid import UUID
import requests
from pydantic import BaseModel
class Item(BaseModel):
id: UUID
content: str
item = Item(id=UUID(int=1), content="Something")
Now if I try put'ing the object like this:
requests.put("http://localhost", json=item)
it complains with a TypeError saying that "Object of type Item is not JSON serializable". (It does not matter for the purpose of this demonstration that there is no one listening at 'localhost'.) OK, this is easy enough to work around:
requests.put("http://localhost", data=item.model_dump_json())
It turns out I need to put a list of Item
s and then it would be convenient to do something like this, which I cannot due to the error in the first example:
requests.put("http://localhost", json=[item, item])
This becomes somewhat more involved to do via serialising the individual Item
s.
This makes me wonder: is this the way I should be doing it at all? Probably not, how is it supposed to be done?
Is it the wrong choice in the first place to involve Pydantic here?
It's fine to use Pydantic for such a purpose. Your example looks also fine. Just do the following:
items = [Item(...), Item(...)]
requests.put("http://localhost", json=[item.dict() for item in items)])
Or you can even do something like this to skip list comprehensions in requests if you manage the format.
class Items(BaseModel):
data: list[Item]
items = Items(data=[Item(...), Item(...)])
items.dict()
If you have UUID fields you probably need to convert it to str
. There are a lot of ways to do it, so I'll just provide an example:
class Item(BaseModel):
id: UUID4
content: str
@model_serializer
def dump(self) -> dict:
return {
"id": str(self.id), # Can be done via validator, etc.
"content": self.content
}
UPD: I found another approach that I didn't know about before:
pydantic_core.to_jsonable_python([Item(...), Item(...)])
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With