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
Migration to pydantic v2 #1745
Migration to pydantic v2 #1745
Conversation
As a note, a (definitely) temporary solution to at least support v2 would be to take advantage of the fact that the whole pydantic v1 API exists under the The barrier for implementing this is quite low, but of course, it doesn't then actually migrate to v2 (which would automatically deprecate v1 support). But it might be a nice temporary step for packages depending on OPT that would like to bump to pydantic v2 😉 |
I tried this when v2 first came out but none of our The only dep that is really forcing us to upgrade is still pymatgen, which, although it has no pydantic dependence itself, refuses to make the Materials Project API an optional dep, which is now forced to use pydantic v2 proper. I'm making a PR now that at least pins MP-API. I've used the pymatgen connection in optimade-python-tools myself but I'm increasingly thinking we can just deprecate the pymatgen adapter entirely, or at least remove it as a specific testing dep as its such a waste of time trying to keep up with them for our use case |
@ml-evs I've been working a bit on this. Not yet done, but I'm making progress. |
🫡 |
Ok. So I got it down to 3 failing tests, all regurgitating the same single error (check CI runs). Also. My commits are quite messy. I've done some static typing here and there - quite sporadically, all the while trying this and that (some of 'this' might still be left in the code here and there), but essentially, mainly going from using JSON Schema (where we do that) and use Concerning the current implementatins for It seems to me there are several improvements that could be done throughout the code. But I don't think any of us have the time to dedicate to an overhaul, unfortunately. |
Codecov Report
@@ Coverage Diff @@
## master #1745 +/- ##
==========================================
- Coverage 90.68% 90.29% -0.40%
==========================================
Files 74 75 +1
Lines 4616 4605 -11
==========================================
- Hits 4186 4158 -28
- Misses 430 447 +17
Flags with carried forward coverage won't be shown. Click here to find out more.
|
Huzzah! It all seems to work 🥳 It should be noted that b7c5588 also removes |
Will implement usage of |
The values for some unused query parameters are wrong/does not match the expected type. There should probably be some other way of specifying one's paging strategy than what is currently implemented. |
Any issues you could raise for specifics?
Awesome, thanks so much for this @CasperWA! Now to think about how to merge/release this... I'll do my best to go through most of the changes now, but @JPBergsma also has several major ongoing additions for OPTIMADE v1.2 open as PRs. After a quick look I think they could be adapted for pydantic v2 fairly easily (they don't use any of the existing hacks we had), so I can devote some time at least to trying that out. I would suggest we merge this PR, try to rebase @JPBergsma's changes over the next few days/weeks, and try to implement a few more bits using this base (e.g., some more 1.2 features that are in draft PRs atm) and if all is settled/tidied, make it the actual v1.0 release that supports the final v1.1.x OPTIMADE with pydantic v2. That would leave us in the state where all of OPTIMADE v1.1 is supported in v0.25.3 with pydantic v1, and in v1.0.0 with pydantic v2, potentially even with backports possible for v0.25.x series for those that cannot upgrade. The other option would be to make the current v0.25.3 as v1, then pydantic v2 support in an immediate v2, but not sure there is much of an advantage to that, unless we plan to also backport all OPTIMADE v1.2 features to pydantic v1. |
Also, I think I'm going to try to break off the non-pydantic upgrade stuff to a separate PR, e.g., running pyupgrade to get rid of all our py38 code (like |
I've forgotten most of it at the moment, but I remember coming up with some here and there during the work here. But I think I've already touched on the major ones, as well as tried to upgrade them. It's mainly about the logic in EntryCollections - the one I've looked at was the retrieval of attributes and such, but handling of the query parameters, I think could be done better perhaps?
This sounds like a good plan, if what you're expecting in @JPBergsma's changes is true 😉
I'd suggest the former option here - no need to make it more grandiose than that. One could consider taking a second look at dependency handling in the repository as well. For example, there is no need to depend on |
Concerning EDIT: Changed to typing.ClassVar. This makes a lot more sense as this is what was intended from the get go for this field. |
Fair enough, this upgrade certainly exposed a few things that were very hacky. I'll need to take a proper look but in some cases I think it is worth keeping the old behavior until after the next major release, e.g., I would like to upgrade my odbx server to pydantic v2 with minimal other code changes and things like the change from
Sure, I think the pylint stuff was only kept in for you :P Given that pre-commit does not integrate with any editors (by design), I quite like having a dev environment installable too, but I take your point. |
Right. That change is quite breaking indeed. Hmm. Maybe there's a workaround to be found? EDIT: Also, the currently implemented change would need some docs rewriting.
No worries - it's fine to keep in as well, when it's in an "extra" and you want dev's to have a specific tool or version of a tool available. |
Also - I'll stop pushing more commits to this branch now to not mess with the work you're currently doing. Just wanted to get that "fix" for |
Use pydantic v1 API wih v2 package Replace `regex` with `pattern` Use pydantic v2 API for model dumps Go use pydantic v2 API again Bump deps in pyproject and adjust for pydantic_settings Attempt to migrate some pydantic v2 features Run bump-pydantic Update deps in requirements Post pydantic-bump tweak number 3 Post pydantic-bump tweak number 4 Post pydantic-bump tweak number 5 Reintroduce email-validator dep via pydantic extra Placating mypy Use lax annotated type rather than validator Attempt to simplify some tests for pydantic v2 Bump pydantic version in pre-commit Bump to pydantic 2.3.0
- Reintroduce `http_client` extra as an alias for `http-client`
Still need to pass in a proper REF_TEMPLATE.
Lot's of changes here - mainly in optimade.server.schemas:retrieve_queryable_properties(). Using the `model_fields` and FieldInfo instead of the generated JSON Schema. Mainly due to the changes in the generated schema. This led to a bit of hacking concerning the type (FieldInfo.annotation). But otherwise, I think this is a better approach. Also implemented for EntryCollection.get_attribute_fields(). Otherwise, changes here and there to make tests work as well as doing some static typing sporadically.
Remove mp-api and emmet-core dependencies Remove emmet-core from requirements file as well Update mkdocstrings dependency in requirements file
Use the new Python handler for mkdocstrings - updating the configuration in all_models.md to include all submodules for optimade.models.
Needed to properly ONLY check if annotation was Union or Optional before using `get_args()`. Otherwise a type required as a list of strings is unpacked to `str`, which we do not want.
Use enum `.value` for comparison (check if this should be used elsewhere in the code for any Enum classes/types). Disable ignoring warning about pydantic v2 deprecations in order to use pydantic v2 methods in remaining places. Consider completely removing the special function used for setting `nullable=true` in JSON schema for 'SHOULD' OPTIMADE support fields. It seems `nullable` is no longer a valid field in OpenAPI v3.1.0, but also, the properties/fields this is added to already support the value being `null`.
This is no longer part of the OpenAPI spec as of v3.1. Fixes #1814
Also update some static typing here and there.
- Avoid running mypy on tests folder. - Remove mypy ignore statements from tests - Revert to having implicit Optional
e0063f3
to
63e3f7c
Compare
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 @CasperWA, finally gotten through this, made a few comments that I've fixed along the way, once the tests pass on my changes I will enact the plan described above, i.e.,
- Merge this PR
- Treat the new state as v1.0.0 pre-release (either officially or unofficially - I don't think our CI can do pre-releases on PyPI and I don't want to mess with it)
- Sit on it for a little while to see how well @JPBergsma's current changes slot in
- Release v1.0.0 with pydantic v2 support, then rebase new features on top of that and begin implementing v1.2 of OPTIMADE
optimade/server/routers/info.py
Outdated
properties=properties, | ||
output_fields_by_format=output_fields_by_format, | ||
schema=CONFIG.schema_url, | ||
# schema=CONFIG.schema_url, # I think this should be removed? |
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.
Indeed, looks like this snuck in here aswell as just the meta
response
# schema=CONFIG.schema_url, # I think this should be removed? |
- Tidy up changes re: `Datatype` - Revert to using `typing.Callable` due to old Python 3.9 bug - Move docstring note about dates back to config of Response model - Revert class name from `Datatype` back to `DataType` - Remove defunct comment
a551c17
to
9da64fd
Compare
This PR contains my WIP attempts to migrate to pydantic v2.
As we were doing some hacky stuff with pydantic internals, this process is not straightforward.
The three current stumbling blocks are
a) how we define
StrictField
andOptimadeField
to do injection/removal of certain keys from the final JSONSchema/OpenAPI schemas, which is currently completely broken by the new pydantic-core.b) complicated
Class Config
instances we currently use (only deprecated at the moment, so can get away with this for a bit longer) -- I've modified some already and they seem to workc) the standard issues supporting pymatgen as a dependency (waiting for their sub-deps to update)
Outside of that, this PR basically:
pydantic_settings
packageregex
forpattern
bump-pydantic
to update several validatorsAnnotated