Skip to content

Commit 2af6c94

Browse files
Merge branch 'pydantic_v2_migration_do_not_squash_updates' into is4481/upgrade-director-v2-service
2 parents 5b64e8e + f07afbf commit 2af6c94

File tree

63 files changed

+481
-247
lines changed

Some content is hidden

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

63 files changed

+481
-247
lines changed

packages/common-library/tests/test_pydantic_validators.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
import pytest
55
from common_library.pydantic_validators import (
6-
validate_legacy_timedelta_str,
6+
_validate_legacy_timedelta_str,
77
validate_numeric_string_as_timedelta,
88
)
99
from faker import Faker
@@ -16,7 +16,7 @@ def test_validate_legacy_timedelta(monkeypatch: pytest.MonkeyPatch, faker: Faker
1616
class Settings(BaseSettings):
1717
APP_NAME: str
1818
REQUEST_TIMEOUT: Annotated[
19-
timedelta, BeforeValidator(validate_legacy_timedelta_str)
19+
timedelta, BeforeValidator(_validate_legacy_timedelta_str)
2020
] = Field(default=timedelta(hours=1))
2121

2222
model_config = SettingsConfigDict()

packages/models-library/src/models_library/api_schemas_directorv2/clusters.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ class ClusterDetailsGet(ClusterDetails):
112112

113113

114114
class ClusterCreate(BaseCluster):
115-
owner: GroupID | None
115+
owner: GroupID | None = None # type: ignore[assignment]
116116
authentication: ExternalClusterAuthentication
117117
access_rights: dict[GroupID, ClusterAccessRights] = Field(
118118
alias="accessRights", default_factory=dict

packages/models-library/src/models_library/api_schemas_directorv2/comp_tasks.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
AnyHttpUrl,
66
AnyUrl,
77
BaseModel,
8+
ConfigDict,
89
Field,
910
ValidationInfo,
1011
field_validator,
@@ -26,6 +27,17 @@ class ComputationGet(ComputationTask):
2627
None, description="the link where to stop the task"
2728
)
2829

30+
model_config = ConfigDict(
31+
json_schema_extra={
32+
"examples": [
33+
x | {"url": "http://url.local"} # type:ignore[operator]
34+
for x in ComputationTask.model_config[ # type:ignore[index,union-attr]
35+
"json_schema_extra"
36+
]["examples"]
37+
]
38+
}
39+
)
40+
2941

3042
class ComputationCreate(BaseModel):
3143
user_id: UserID

packages/models-library/src/models_library/api_schemas_dynamic_sidecar/telemetry.py

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@
88
Field,
99
NonNegativeFloat,
1010
NonNegativeInt,
11-
root_validator,
12-
validator,
11+
model_validator,
1312
)
1413

1514
from ..projects_nodes_io import NodeID
@@ -56,29 +55,13 @@ class DiskUsage(BaseModel):
5655
free: ByteSize = Field(description="remaining space")
5756

5857
total: ByteSize = Field(description="total space = free + used")
59-
used_percent: NonNegativeFloat = Field(
58+
used_percent: float = Field(
6059
ge=0.00,
6160
le=100.00,
6261
description="Percent of used space relative to the total space",
6362
)
6463

65-
@validator("free")
66-
@classmethod
67-
def _free_positive(cls, v: float) -> float:
68-
if v < 0:
69-
msg = f"free={v} cannot be a negative value"
70-
raise ValueError(msg)
71-
return v
72-
73-
@validator("used")
74-
@classmethod
75-
def _used_positive(cls, v: float) -> float:
76-
if v < 0:
77-
msg = f"used={v} cannot be a negative value"
78-
raise ValueError(msg)
79-
return v
80-
81-
@root_validator(pre=True)
64+
@model_validator(mode="before")
8265
@classmethod
8366
def _check_total(cls, values: dict[str, Any]) -> dict[str, Any]:
8467
total = values["total"]

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -311,12 +311,12 @@ class FileUploadCompleteFutureResponse(BaseModel):
311311

312312

313313
class FoldersBody(BaseModel):
314-
source: dict[str, Any] = Field(default_factory=dict)
315-
destination: dict[str, Any] = Field(default_factory=dict)
316-
nodes_map: dict[NodeID, NodeID] = Field(default_factory=dict)
314+
source: Annotated[dict[str, Any], Field(default_factory=dict)]
315+
destination: Annotated[dict[str, Any], Field(default_factory=dict)]
316+
nodes_map: Annotated[dict[NodeID, NodeID], Field(default_factory=dict)]
317317

318318
@model_validator(mode="after")
319-
def ensure_consistent_entries(self) -> Self:
319+
def ensure_consistent_entries(self: Self) -> Self:
320320
source_node_keys = (NodeID(n) for n in self.source.get("workbench", {}))
321321
if set(source_node_keys) != set(self.nodes_map.keys()):
322322
msg = "source project nodes do not fit with nodes_map entries"

packages/models-library/src/models_library/api_schemas_webserver/product.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
11
from datetime import datetime
22
from typing import Annotated, TypeAlias
33

4-
from pydantic import ConfigDict, Field, HttpUrl, NonNegativeInt, PositiveInt
4+
from pydantic import (
5+
ConfigDict,
6+
Field,
7+
HttpUrl,
8+
NonNegativeFloat,
9+
NonNegativeInt,
10+
PlainSerializer,
11+
PositiveInt,
12+
)
513

614
from ..basic_types import IDStr, NonNegativeDecimal
715
from ..emails import LowerCaseEmailStr
@@ -11,7 +19,10 @@
1119

1220
class GetCreditPrice(OutputSchema):
1321
product_name: str
14-
usd_per_credit: NonNegativeDecimal | None = Field(
22+
usd_per_credit: Annotated[
23+
NonNegativeDecimal,
24+
PlainSerializer(float, return_type=NonNegativeFloat, when_used="json"),
25+
] | None = Field(
1526
...,
1627
description="Price of a credit in USD. "
1728
"If None, then this product's price is UNDEFINED",

packages/models-library/src/models_library/api_schemas_webserver/projects.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,9 @@ class ProjectReplace(InputSchema):
107107
uuid: ProjectID
108108
name: ShortTruncatedStr
109109
description: LongTruncatedStr
110-
thumbnail: Annotated[HttpUrl | None, BeforeValidator(empty_str_to_none_pre_validator)] = Field(default=None)
110+
thumbnail: Annotated[
111+
HttpUrl | None, BeforeValidator(empty_str_to_none_pre_validator)
112+
] = Field(default=None)
111113
creation_date: DateTimeStr
112114
last_change_date: DateTimeStr
113115
workbench: NodesDict
@@ -127,13 +129,15 @@ class ProjectReplace(InputSchema):
127129
class ProjectPatch(InputSchema):
128130
name: ShortTruncatedStr | None = Field(default=None)
129131
description: LongTruncatedStr | None = Field(default=None)
130-
thumbnail: Annotated[HttpUrl | None, BeforeValidator(empty_str_to_none_pre_validator)] = Field(default=None)
132+
thumbnail: Annotated[
133+
HttpUrl | None, BeforeValidator(empty_str_to_none_pre_validator)
134+
] = Field(default=None)
131135
access_rights: dict[GroupIDStr, AccessRights] | None = Field(default=None)
132136
classifiers: list[ClassifierID] | None = Field(default=None)
133137
dev: dict | None = Field(default=None)
134138
ui: StudyUI | None = Field(default=None)
135139
quality: dict[str, Any] | None = Field(default=None)
136-
140+
137141

138142
__all__: tuple[str, ...] = (
139143
"EmptyModel",

packages/models-library/src/models_library/api_schemas_webserver/resource_usage.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
from datetime import datetime
22
from decimal import Decimal
3+
from typing import Annotated
34

4-
from pydantic import BaseModel, ConfigDict, Field
5+
from pydantic import BaseModel, ConfigDict, Field, PlainSerializer
56

67
from ..projects import ProjectID
78
from ..projects_nodes_io import NodeID
@@ -49,7 +50,9 @@ class PricingUnitGet(OutputSchema):
4950
pricing_unit_id: PricingUnitId
5051
unit_name: str
5152
unit_extra_info: UnitExtraInfo
52-
current_cost_per_unit: Decimal
53+
current_cost_per_unit: Annotated[
54+
Decimal, PlainSerializer(float, return_type=float, when_used="json")
55+
]
5356
default: bool
5457

5558

packages/models-library/src/models_library/api_schemas_webserver/wallets.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,14 @@
22
from decimal import Decimal
33
from typing import Annotated, Literal, TypeAlias
44

5-
from pydantic import ConfigDict, Field, HttpUrl, PlainSerializer, ValidationInfo, field_validator
5+
from pydantic import (
6+
ConfigDict,
7+
Field,
8+
HttpUrl,
9+
PlainSerializer,
10+
ValidationInfo,
11+
field_validator,
12+
)
613

714
from ..basic_types import AmountDecimal, IDStr, NonNegativeDecimal
815
from ..users import GroupID
@@ -20,10 +27,7 @@ class WalletGet(OutputSchema):
2027
created: datetime
2128
modified: datetime
2229

23-
model_config = ConfigDict(
24-
from_attributes=True,
25-
frozen=False
26-
)
30+
model_config = ConfigDict(from_attributes=True, frozen=False)
2731

2832

2933
class WalletGetWithAvailableCredits(WalletGet):
@@ -163,7 +167,7 @@ class PaymentMethodGet(OutputSchema):
163167
"autoRecharge": "False",
164168
},
165169
],
166-
}
170+
},
167171
)
168172

169173

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ class ProgressStructuredMessage(BaseModel):
1212
description: IDStr
1313
current: float
1414
total: int
15-
unit: str | None
16-
sub: "ProgressStructuredMessage | None"
15+
unit: str | None = None
16+
sub: "ProgressStructuredMessage | None" = None
1717

1818
model_config = ConfigDict(
1919
json_schema_extra={

0 commit comments

Comments
 (0)