gilesknap / notion-data

Python classes to represent Notion API objects
Apache License 2.0
0 stars 0 forks source link

Dynamically Typed field getting warnings #4

Open gilesknap opened 3 months ago

gilesknap commented 3 months ago

The Page class is all statically typed except that the Properties field is a dict[str, _PropertyUnion].

I'm able to generate a Dynamic Model for the field at de-serialize time using a validator: https://github.com/gilesknap/notion-data/blob/0ab221127d857377421e436b7b0d2473e6f0a3e1/src/notion_data/page.py#L198-L202

This all works beautifully and allows me to do things like this: https://github.com/gilesknap/notion-data/blob/0ab221127d857377421e436b7b0d2473e6f0a3e1/tests/test_system/test_pages.py#L35-L42 EXCEPT I get this warning and have to surpress UserWarning for the tests to pass:

FAILED tests/test_system/test_pages.py::test_db_page - UserWarning: Pydantic serializer warnings:
  Expected `dict[str, Union[Checkbox, CreatedBy, CreatedTime, Date, Email, Files, Formula, LastEditedBy, LastEditedTime, MultiSelect, Number, People, Relation, Status, TitleClass]]` but got `Properties` - serialized value may not be as expected

Don't want to be eating warnings.

@coretl @GDYendell any ideas on this?

GDYendell commented 3 months ago

I definitely saw this warning a lot working on pvi, but not now.

I am not sure dict_model_instance is doing what you want. Have you tried checking the output of page.properties.model_dump() is as you expect?

You may benefit from defining the unions explicitly, rather than using .subclasses, and using pydantic Discriminator and Tag. They are relatively static presumably?

https://github.com/epics-containers/pvi/blob/main/src/pvi/typed_model.py#L16 may give some inspiration.

gilesknap commented 3 months ago

Thanks @GDYendell I will take a look at your suggestion.

Although I have now realized that the rather trivial answer to my issue is simply to declare properties as:

    # Properties' keys are the column names from parent database
    # Therefore dynamic - model is created by validate_properties below
    properties: dict[str, _PropertyUnion] | Root

(where Root is my BaseModel with some config)