-
-
Notifications
You must be signed in to change notification settings - Fork 7.3k
[python-fastapi] Fix additionalProperties support & support pydantic v2 #19312
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
base: master
Are you sure you want to change the base?
[python-fastapi] Fix additionalProperties support & support pydantic v2 #19312
Conversation
Previously additionalProperties were indented wrongly so that they appeared as a regular property. Also, adjust the controller code correspondingly. Depends on the openapi-generator PR OpenAPITools/openapi-generator#19312 (otherwise additionalProperties support does not work with the python-fastapi generator)
|
Thanks for the PR! I'll need something like this PR to move off python-pydantic-v1. I have a question about this bit:
Why remove |
The idea is to let the generated code fully leverage the fastapi/pydantic platform idioms, which include letting the route methods return typed objects that pydantic then maps and validates based on the type annotation. |
24b70a9 to
371a3e5
Compare
|
I updated the PR correspondingly but unfortunately this is still a breaking change since
I can look into making the adjustments some other evening. |
ab40757 to
e99c74f
Compare
f3161f8 to
66d1ff9
Compare
|
I like it! I anticipate using this as a client to replace python-pydantic-v1. Hopefully a maintainer can chime in/approve when you are ready! |
d83b593 to
001894e
Compare
1605ab8 to
94330f0
Compare
Relates to OpenAPITools#19312
b06b295 to
ef34d9d
Compare
|
Turns out the failed python client test was fixed here now. Correspondingly, I applied the fix also to the python-pydantic-v1 client test which failed for the same reason. Now that the merge conflicts are resolved and the CI build succeeds again, this PR is ready for review again. |
|
Thanks for your efforts with this MR, it would be really great to see this get merged (along with a few of the other python-fastapi fixes). |
|
Thank you for your work - as many I probably found this PR because I ran into similar problems with the python-fastapi generator. It would be really nice if the python-fastapi fix PRs could be merged. |
ef34d9d to
22f78fa
Compare
|
I rebased the PR now again to resolve the merge conflicts (which dropped my last commit that fixed the python-pydantic-v1 test since the fix is on the master branch now). However, now the Python client deserialization test fails with the following error: Though, that problem is not related to this PR which the master branch build of #21415 shows which also fails with the same error! (The same problem also makes the build of PR #21402 fail.) Thus, this PR is ready for review again! |
22f78fa to
95942a5
Compare
ef34d9d to
b69a8ee
Compare
|
Rebased the PR again to include the python unit test fix of #21423. This PR is ready for review again! |
Don't let models inherit the value type of additionalProperties and arrays. This is to fix a bug where the `python-fastapi` server generator generated invalid models that inherited the value type specified within additionalProperties.
Previously, the generated `additional_properties` field showed up within
the response of the generated API as opposed marshaling the model so that its fields are added to the root object.
Apparently that is because pydantic v2 does not honour the generated `to_dict` methods anymore (which would have mapped the object to the correct representation) but, instead, supports additional properties natively by specifying `extra=allow` within the `model_config`.
Correspondingly, the following changes have been applied:
* To allow additional fields, specify `extra=allow` within the `model_config`.
* Don't generate the `additional_properties` field - users can use pydantic's built-in `model.extra_fields` instead.
* Let the `{to|from}_{dict|json}` methods delegate to Pydantic's `model_dump[_json]` methods.
Exclude unset fields when marshalling api endpoint response bodies.
* Support oneOf and anyOf schemas the pydantic v2 way by generating them as Unions. * Generate model constructor that forcefully sets the discriminator field to ensure it is included in the marshalled representation.
b69a8ee to
ef7c699
Compare
|
I rebased the PR again to include the fixes from the main branch. Please review! |
|
@wing328 can you review the PR by any chance? |
|
@mgoltzsche thanks for the PR 🙏 it's a huge change. do you mind pinging me via Slack (https://app.slack.com/client/TLQFRCNJZ/dms) when you've time tomorrow or Friday for a few quick questions on this PR? |
|
Hey guys bumping the pull request would be great to get it in the mainstream branch |
|
Unfortunately it doesn't look like this PR will be merged. |
|
thanks for your effort so far! I can confirm that |
additionalPropertiesschema (or the array item schema) but the pydanticBaseModel.additionalPropertiesthe pydantic v2 way within__dict__: Previously, the generatedadditional_propertiesfield showed up within the response of the generated API as opposed marshaling the model so that its fields are added to/embedded into the root object. Apparently that is because pydantic v2 does not honour the generatedto_dictmethods (which would have mapped the object to the correct representation) but, instead, supports additional properties natively by specifyingextra=allowwithin themodel_config. Correspondingly, the following changes have been applied:extra=allowwithin themodel_config.additional_propertiesfield but use__dict__- users can use pydantic's built-inmodel.model_extrainstead.Don't generate the{to|from}_{dict|json}methods since pydantic is taking care of the model mapping based on the declared fields andmodel_config- users can use pydantic'smodel.model_dump[_json]instead.{to|from}_{dict|json}methods delegate to Pydantic'smodel_dump[_json]methods.exclude_unsetresponse marshalling option in order to omit fields from the response that weren't explicitly set by the code. This is so that non-required fields don't show up withnullvalues within the response (which would be invalid according to the OpenAPI spec, unless those fields are explicitly marked asnullablewithin the OpenAPI schema).oneOfandanyOfschemas the Pydantic v2 way:RootModel.Unions and leave it to Pydantic to validate and figure out the type.exclude_unsetmarshalling option being enabled).Closes #19311
Relates to #17703 (might also close that one)
Relates to #19454
cc @cbornet @tomplus @krjakbrjak @fa0311 @multani
PR checklist
Commit all changed files.
This is important, as CI jobs will verify all generator outputs of your HEAD commit as it would merge with master.
These must match the expectations made by your contribution.
You may regenerate an individual generator by passing the relevant config(s) as an argument to the script, for example
./bin/generate-samples.sh bin/configs/java*.IMPORTANT: Do NOT purge/delete any folders/files (e.g. tests) when regenerating the samples as manually written tests may be removed.
master(upcoming 7.6.0 minor release - breaking changes with fallbacks),8.0.x(breaking changes without fallbacks)