-
-
Notifications
You must be signed in to change notification settings - Fork 74
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
Upgrade to Pydantic v2 #319
Conversation
@@ -22,7 +22,8 @@ classifiers = [ | |||
"Topic :: Software Development :: Libraries :: Python Modules", | |||
] | |||
dependencies = [ | |||
"pydantic>=1.9.1", | |||
"pydantic>=2.0", | |||
"pydantic-settings" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"pydantic-settings" | |
"pydantic-settings", |
@@ -6,10 +6,11 @@ | |||
setup( | |||
name="spectree", | |||
install_requires=[ | |||
"pydantic>=1.2", | |||
"pydantic>=2.0", | |||
"pydantic-settings" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"pydantic-settings" | |
"pydantic-settings", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for your contribution.
Pydantic v2 has too many breaking changes that lots of 3rd libraries are not able to upgrade in a short time.
This PR is not backward compatible (due to pydantic breaking changes). I'm not sure if we should make this library compatible with both pydantic v1 & v2. Or maybe we should add another abstract layer so that we can make it possible to support pydantic v1 & v2 and msgspec (ref #307)
That's a huge contribution, your effort is really appreciated. Pydantic v2 however still have some bugs and the ecosystem hasnt adapted yet, so I think it's too early to merge this at this moment. |
I understand of course, this is definitely just here to get the conversation started and test the waters. So is the ideal separation of layers for future spectree this?
|
Yeah. I wonder if we can detect the model (pydantic v1/v2, megspec) automatically. This layer should be used to validate the request/response and generate the OpenAPI model schema. |
Hi |
You can use |
At least for v2, pydantic appears to be including a But it seems like it might make it possible for the library at current moment to "simply" alias all of its imports to pydantic to the v1 version. Such that I, as a user of pydantic (that doesn't necessarily stop at API models) could upgrade to v2 without impacting the spectree-compatible v1 API models. |
This sounds like a good temporary solution. |
I've seen this approach used specifically with just: try:
from pydantic import v1 as pydantic
except ImportError:
import pydantic I didn't explore this yet, but could be worth looking into since it's a smaller change and also less likely to break for current v1 users. The only downside is spectree internally would still be using the v1 API instead of the v2 API. Although, that might not even matter since the long-term plan is to rehaul the internals to support msgspec anyways. #324 is exploring the reverse approach for fun and upgrading the code to v2 API and creating backports for v1 and version-specific logic to handle the breaking changes. |
This will have to be tested more thoroughly of course, but I hope this is a good start to move towards pydantic v2 :)
Changes:
BaseModel
method names, decorators, and config dict:model.parse_obj
->model.model_validate
model.dict
->model.model_dump(mode="json")
@root_validator
->@model_validator
@validator
->@field_validator
parse_raw(raw_stuff)
->model_validate(json.loads(raw_stuff))
schema
->model_json_schema
json
->model_dump_json
class Config: ...
->model_config = ConfigDict(...)
BaseModel
subclasses using__root__
switched to subclassRootModel
withroot
annotationValidationErrorElement
:input
andurl
BaseFile
(thanks to flask-openapi3's implementation)ValidationError
updated to useerr.json(indent=2)
instead ofjsonify(err.errors())
to avoidTypeError: _ is not JSONSerializable
errors from the newinput
field (indent=2
to keep response consistent to current)definitions
->$defs
req_validation_error.model.__name__
->req_validation_error.title
pydantic.EmailStr.validate
->pydantic.validate_email