Skip to content
Advertisement

Return all extra passed to pydantic model

I’m trying to get a list of all extra fields not defined in the schema. I saw solution posted here but it ignores any nested models. Optimal solution would create a variable in the Pydantic model with extras that I could access after new object with passed data is created but not sure if this is even possible.

Here is the code I’m working with.

Edit: I want .extras to be something like a property that returns not just the extra data directly on that instance, but also the extra data on any nested model instances it holds

JavaScript

Advertisement

Answer

The following solution does not produce a list of keys as you described, but instead a nested dictionary of key-value-pairs from the extra attributes:

JavaScript

Output:

JavaScript

If you do want your list of keys instead, you can use these methods:

JavaScript

Calling extra_fields on the previous example model instance gives the following output:

JavaScript

Both solutions just recursively iterate over all fields except extra.

The annotations assume Python 3.10+. If this causes problems, replace all types T | None with typing.Optional[T]. If you are using <3.9, (first of all, upgrade your Python :P) replace things like list[str] with typing.List[str].

The cached method for retrieving the required_names is just for efficiency, so that it is only ever called once for any given model class.

I left the build_extra root validator basically unchanged.

Caveat:

In the current implementation, if you have nested models in container fields, their extras are ignored. For example, if you had something like addresses: list[Address] on your CatRequest.

If I find the time, I’ll try and amend the solution later. Though I suspect that this may be non-trivial because of the different “shapes” such fields can come in. Also it is not entirely clear how that should look in the output.

Hope this helps.

Advertisement