<@ULVA73B9P> is the JSONSerializer class supposed ...
# ask-marvin
p
@Marvin is the JSONSerializer class supposed to be able to serialize pydantic
BaseModel
objects? When I run this code snippet:
Copy code
from pydantic import BaseModel
from prefect.serializers import JSONSerializer
 
class M(BaseModel):
    f1: str
    f2: int
 
m = M(f1="model", m2=1234)
ser = JSONSerializer(dumps_kwargs={"sort_keys": True})
ser.dumps(((m,), {}))
I get this error:
Copy code
python3.10/site-packages/pydantic/v1/json.py:90, in pydantic_encoder(obj)
     88     return encoder(obj)
     89 else:  # We have exited the for loop without finding a suitable encoder
---> 90     raise TypeError(f"Object of type '{obj.__class__.__name__}' is not JSON serializable")

TypeError: Object of type 'M' is not JSON serializable
m
The Prefect's JSONSerializer should be able to serialize Pydantic
BaseModel
objects as it adds support for all types supported by Pydantic. However, you might be running into issues because of the way you're trying to serialize the Pydantic model. When you're trying to serialize a Pydantic model, you should first convert it to a dictionary using the
.dict()
method, like so:
Copy code
ser.dumps(((m.dict(),), {}))
This is because the JSONSerializer expects a JSON serializable object, and a Pydantic model is not directly serializable - it needs to be converted to a dictionary first. Here's the corrected code:
Copy code
from pydantic import BaseModel
from prefect.serializers import JSONSerializer
 
class M(BaseModel):
    f1: str
    f2: int
 
m = M(f1="model", f2=1234)
ser = JSONSerializer(dumps_kwargs={"sort_keys": True})
ser.dumps(((m.dict(),), {}))
This should serialize your Pydantic model without any issues.
p
okay, but according to this PR: https://github.com/PrefectHQ/prefect/pull/7048 it looks like the intention here was to make
BaseModel
instances serializable with JSON
the related issue here (https://github.com/PrefectHQ/prefect/issues/7010) was also marked as closed
This is the test that I ran to verify this for myself:
Copy code
from prefect.serializers import JSONSerializer
from pydantic import BaseModel


class M(BaseModel):
    f1: str
    f2: int


ser = JSONSerializer(dumps_kwargs={"sort_keys": True})
m = M(f1="asdf", f2=1234)

ser.dumps(((m,), {}))  # Causes TypeError, which then triggers the cloud pickler in the `hash_objects` function