Skip to content

Commit d2d81c0

Browse files
⬆️ Upgrade models-library (pydantic v2) (#6333)
Co-authored-by: Andrei Neagu <[email protected]>
1 parent 6d6f5c5 commit d2d81c0

File tree

126 files changed

+2444
-2081
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

126 files changed

+2444
-2081
lines changed

packages/models-library/requirements/_base.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,5 @@ arrow
77
jsonschema
88
orjson
99
pydantic[email]
10+
pydantic-settings
11+
pydantic-extra-types

packages/models-library/requirements/_base.txt

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
annotated-types==0.7.0
2+
# via pydantic
13
arrow==1.3.0
24
# via -r requirements/_base.in
35
attrs==24.2.0
@@ -18,12 +20,22 @@ orjson==3.10.7
1820
# via
1921
# -c requirements/../../../requirements/constraints.txt
2022
# -r requirements/_base.in
21-
pydantic==1.10.17
23+
pydantic==2.9.1
2224
# via
2325
# -c requirements/../../../requirements/constraints.txt
2426
# -r requirements/_base.in
27+
# pydantic-extra-types
28+
# pydantic-settings
29+
pydantic-core==2.23.3
30+
# via pydantic
31+
pydantic-extra-types==2.9.0
32+
# via -r requirements/_base.in
33+
pydantic-settings==2.4.0
34+
# via -r requirements/_base.in
2535
python-dateutil==2.9.0.post0
2636
# via arrow
37+
python-dotenv==1.0.1
38+
# via pydantic-settings
2739
referencing==0.35.1
2840
# via
2941
# jsonschema
@@ -37,4 +49,6 @@ six==1.16.0
3749
types-python-dateutil==2.9.0.20240821
3850
# via arrow
3951
typing-extensions==4.12.2
40-
# via pydantic
52+
# via
53+
# pydantic
54+
# pydantic-core

packages/models-library/requirements/_test.txt

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ coverage==7.6.1
88
# via
99
# -r requirements/_test.in
1010
# pytest-cov
11-
exceptiongroup==1.2.2
12-
# via pytest
1311
faker==27.0.0
1412
# via -r requirements/_test.in
1513
flexcache==0.3
@@ -68,7 +66,9 @@ python-dateutil==2.9.0.post0
6866
# -c requirements/_base.txt
6967
# faker
7068
python-dotenv==1.0.1
71-
# via -r requirements/_test.in
69+
# via
70+
# -c requirements/_base.txt
71+
# -r requirements/_test.in
7272
pyyaml==6.0.2
7373
# via
7474
# -c requirements/../../../requirements/constraints.txt
@@ -87,10 +87,6 @@ six==1.16.0
8787
# python-dateutil
8888
termcolor==2.4.0
8989
# via pytest-sugar
90-
tomli==2.0.1
91-
# via
92-
# coverage
93-
# pytest
9490
types-jsonschema==4.23.0.20240813
9591
# via -r requirements/_test.in
9692
types-pyyaml==6.0.12.20240808

packages/models-library/requirements/_tools.txt

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -78,14 +78,6 @@ setuptools==73.0.1
7878
# via pip-tools
7979
shellingham==1.5.4
8080
# via typer
81-
tomli==2.0.1
82-
# via
83-
# -c requirements/_test.txt
84-
# black
85-
# build
86-
# mypy
87-
# pip-tools
88-
# pylint
8981
tomlkit==0.13.2
9082
# via pylint
9183
typer==0.12.4
@@ -94,8 +86,6 @@ typing-extensions==4.12.2
9486
# via
9587
# -c requirements/_base.txt
9688
# -c requirements/_test.txt
97-
# astroid
98-
# black
9989
# mypy
10090
# typer
10191
virtualenv==20.26.3

packages/models-library/scripts/validate-pg-projects.py

100755100644
Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,10 @@
44

55
import typer
66
from models_library.projects import ProjectAtDB
7-
from pydantic import Json, ValidationError, validator
8-
from pydantic.main import Extra
7+
from pydantic import ConfigDict, Json, ValidationError, field_validator
98

109

1110
class ProjectFromCsv(ProjectAtDB):
12-
class Config(ProjectAtDB.Config):
13-
extra = Extra.forbid
14-
1511
# TODO: missing in ProjectAtDB
1612

1713
access_rights: Json
@@ -22,17 +18,19 @@ class Config(ProjectAtDB.Config):
2218

2319
hidden: bool
2420

21+
model_config = ConfigDict(extra="forbid")
22+
2523
# NOTE: validators introduced to parse CSV
2624

27-
@validator("published", "hidden", pre=True, check_fields=False)
25+
@field_validator("published", "hidden", mode="before", check_fields=False)
2826
@classmethod
2927
def empty_str_as_false(cls, v):
3028
# See booleans for >v1.0 https://pydantic-docs.helpmanual.io/usage/types/#booleans
3129
if isinstance(v, str) and v == "":
3230
return False
3331
return v
3432

35-
@validator("workbench", pre=True, check_fields=False)
33+
@field_validator("workbench", mode="before", check_fields=False)
3634
@classmethod
3735
def jsonstr_to_dict(cls, v):
3836
if isinstance(v, str):
Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
from pydantic import BaseModel, Extra, Field
1+
from pydantic import BaseModel, ConfigDict, Field
22

33

44
class AccessRights(BaseModel):
55
read: bool = Field(..., description="has read access")
66
write: bool = Field(..., description="has write access")
77
delete: bool = Field(..., description="has deletion rights")
88

9-
class Config:
10-
extra = Extra.forbid
9+
model_config = ConfigDict(extra="forbid")

packages/models-library/src/models_library/aiodocker_api.py

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from pydantic import Field, validator
1+
from pydantic import ConfigDict, Field, field_validator
22

33
from .generated_models.docker_rest_api import (
44
ContainerSpec,
@@ -16,7 +16,7 @@ class AioDockerContainerSpec(ContainerSpec):
1616
description="aiodocker expects here a dictionary and re-convert it back internally`.\n",
1717
)
1818

19-
@validator("Env", pre=True)
19+
@field_validator("Env", mode="before")
2020
@classmethod
2121
def convert_list_to_dict(cls, v):
2222
if v is not None and isinstance(v, list):
@@ -37,8 +37,7 @@ class AioDockerResources1(Resources1):
3737
None, description="Define resources reservation.", alias="Reservations"
3838
)
3939

40-
class Config(Resources1.Config): # type: ignore
41-
allow_population_by_field_name = True
40+
model_config = ConfigDict(populate_by_name=True)
4241

4342

4443
class AioDockerTaskSpec(TaskSpec):
@@ -55,6 +54,4 @@ class AioDockerTaskSpec(TaskSpec):
5554
class AioDockerServiceSpec(ServiceSpec):
5655
TaskTemplate: AioDockerTaskSpec | None = None
5756

58-
class Config(ServiceSpec.Config): # type: ignore
59-
alias_generator = camel_to_snake
60-
allow_population_by_field_name = True
57+
model_config = ConfigDict(populate_by_name=True, alias_generator=camel_to_snake)
Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
from typing import Any, ClassVar
2-
3-
from pydantic import BaseModel, Field
1+
from pydantic import BaseModel, ConfigDict, Field
42

53
from ..basic_types import VersionStr
64

@@ -12,11 +10,12 @@ class BaseMeta(BaseModel):
1210
default=None, description="Maps every route's path tag with a released version"
1311
)
1412

15-
class Config:
16-
schema_extra: ClassVar[dict[str, Any]] = {
13+
model_config = ConfigDict(
14+
json_schema_extra={
1715
"example": {
1816
"name": "simcore_service_foo",
1917
"version": "2.4.45",
2018
"released": {"v1": "1.3.4", "v2": "2.4.45"},
2119
}
2220
}
21+
)

packages/models-library/src/models_library/api_schemas_api_server/api_keys.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from pydantic import BaseModel, Field, SecretStr
1+
from pydantic import BaseModel, ConfigDict, Field, SecretStr
22

33

44
class ApiKey(BaseModel):
@@ -15,5 +15,4 @@ class ApiKeyInDB(BaseModel):
1515
user_id: int
1616
product_name: str
1717

18-
class Config:
19-
orm_mode = True
18+
model_config = ConfigDict(from_attributes=True)

packages/models-library/src/models_library/api_schemas_catalog/services.py

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
from datetime import datetime
2-
from typing import Any, ClassVar, TypeAlias
2+
from typing import Any, TypeAlias
33

44
from models_library.rpc_pagination import PageRpc
5-
from pydantic import BaseModel, Extra, Field, HttpUrl, NonNegativeInt
5+
from pydantic import BaseModel, ConfigDict, Field, HttpUrl, NonNegativeInt
66

77
from ..boot_options import BootOptions
88
from ..emails import LowerCaseEmailStr
@@ -23,23 +23,23 @@
2323

2424

2525
class ServiceUpdate(ServiceMetaDataEditable, ServiceAccessRights):
26-
class Config:
27-
schema_extra: ClassVar[dict[str, Any]] = {
26+
model_config = ConfigDict(
27+
json_schema_extra={
2828
"example": {
2929
# ServiceAccessRights
3030
"accessRights": {
3131
1: {
3232
"execute_access": False,
3333
"write_access": False,
34-
},
34+
}, # type: ignore[dict-item]
3535
2: {
3636
"execute_access": True,
3737
"write_access": True,
38-
},
38+
}, # type: ignore[dict-item]
3939
44: {
4040
"execute_access": False,
4141
"write_access": False,
42-
},
42+
}, # type: ignore[dict-item]
4343
},
4444
# ServiceMetaData = ServiceCommonData +
4545
"name": "My Human Readable Service Name",
@@ -72,6 +72,7 @@ class Config:
7272
},
7373
}
7474
}
75+
)
7576

7677

7778
_EXAMPLE_FILEPICKER: dict[str, Any] = {
@@ -206,12 +207,11 @@ class ServiceGet(
206207
): # pylint: disable=too-many-ancestors
207208
owner: LowerCaseEmailStr | None
208209

209-
class Config:
210-
allow_population_by_field_name = True
211-
extra = Extra.ignore
212-
schema_extra: ClassVar[dict[str, Any]] = {
213-
"examples": [_EXAMPLE_FILEPICKER, _EXAMPLE_SLEEPER]
214-
}
210+
model_config = ConfigDict(
211+
extra="ignore",
212+
populate_by_name=True,
213+
json_schema_extra={"examples": [_EXAMPLE_FILEPICKER, _EXAMPLE_SLEEPER]},
214+
)
215215

216216

217217
class ServiceGetV2(BaseModel):
@@ -229,7 +229,7 @@ class ServiceGetV2(BaseModel):
229229
service_type: ServiceType = Field(default=..., alias="type")
230230

231231
contact: LowerCaseEmailStr | None
232-
authors: list[Author] = Field(..., min_items=1)
232+
authors: list[Author] = Field(..., min_length=1)
233233
owner: LowerCaseEmailStr | None
234234

235235
inputs: ServiceInputsDict
@@ -249,11 +249,11 @@ class ServiceGetV2(BaseModel):
249249
" It includes current release.",
250250
)
251251

252-
class Config:
253-
extra = Extra.forbid
254-
alias_generator = snake_to_camel
255-
allow_population_by_field_name = True
256-
schema_extra: ClassVar[dict[str, Any]] = {
252+
model_config = ConfigDict(
253+
extra="forbid",
254+
populate_by_name=True,
255+
alias_generator=snake_to_camel,
256+
json_schema_extra={
257257
"examples": [
258258
{
259259
**_EXAMPLE_SLEEPER, # v2.2.1 (latest)
@@ -304,7 +304,8 @@ class Config:
304304
],
305305
},
306306
]
307-
}
307+
},
308+
)
308309

309310

310311
PageRpcServicesGetV2: TypeAlias = PageRpc[
@@ -330,12 +331,13 @@ class ServiceUpdateV2(BaseModel):
330331

331332
access_rights: dict[GroupID, ServiceGroupAccessRightsV2] | None = None
332333

333-
class Config:
334-
extra = Extra.forbid
335-
alias_generator = snake_to_camel
336-
allow_population_by_field_name = True
334+
model_config = ConfigDict(
335+
extra="forbid",
336+
populate_by_name=True,
337+
alias_generator=snake_to_camel,
338+
)
337339

338340

339-
assert set(ServiceUpdateV2.__fields__.keys()) - set( # nosec
340-
ServiceGetV2.__fields__.keys()
341+
assert set(ServiceUpdateV2.model_fields.keys()) - set( # nosec
342+
ServiceGetV2.model_fields.keys()
341343
) == {"deprecated"}

0 commit comments

Comments
 (0)