-
Notifications
You must be signed in to change notification settings - Fork 43
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
pydantic model serialization disallows binary data (experimental API) #310
Comments
I'm assuming this will end up being a problem... It looks like I got this to work by subclassing from pydantic import BaseModel
class Model(BaseModel):
a: bytes
def model_dump(self, *args, **kwargs) -> dict[str, Any]:
if 'exclude' in kwargs.keys():
if 'a' not in kwargs['exclude']:
kwargs['exclude'].append('a')
else:
kwargs['exclude'] = ['a']
kwargs['mode'] = 'json'
json_model_dump = super().model_dump(*args, **kwargs)
python_model_dump = super().model_dump(include={"a"})
return {**json_model_dump, **python_model_dump}
Model(a=b'abc').model_dump(mode='json')
# {'a': b'abc'}
Model(a=b'\xa1').model_dump(mode='json')
# {'a': b'\xa1'} So now it's always binary! |
Hmm, yah this is due to the fact binary data isn't serializable to JSON (without base64 encoding it). The class Model(BaseModel):
a: bytes
def _get_anywidget_state(self):
state = self.model_dump(exclude=["a"], mode="json")
state["a"] = self.a
return state This will take precedent over the inferred anywidget/anywidget/_descriptor.py Lines 457 to 502 in 62ed7e4
|
Hmm, I'm not too worried about the regression of other date types. All of this stuff is behind
with Whereas if we switched to class Model(BaseModel):
a: bytes
dt: datetime
@field_serializer
def serialize_dt(self, dt: datetime, _info):
return dt.isoformat() If someone really wants to keep the behavior of anywidget and pydantic separate, then they can always implement |
It seems like you either need to manually handle |
Since |
To play devil's advocate, |
Sorry, I was referring to import builtins
builtins.datetime
# AttributeError: module 'builtins' has no attribute 'datetime' But I see your point, probably need to think more about it. Less magic is better IMO with regard to serialization, and I could imagine that they might be several different ways to serialize a datetime compared to bytes. If we default to |
The current implementation of
_get_pydantic_state_v2
is:anywidget/anywidget/_descriptor.py
Lines 653 to 655 in 620d380
When you have a model that serializes to binary data,
mode="json"
is ok only when the binary data is actually a utf8 string. I.e.:But because anywidget uses
remove_buffers
, settingmode="json"
isn't necessary.Though removing
mode="json"
might have regressions for other data types, like dates?The text was updated successfully, but these errors were encountered: