Skip to content

Commit 1d713bf

Browse files
fix typecheck
1 parent f592daa commit 1d713bf

File tree

16 files changed

+87
-66
lines changed

16 files changed

+87
-66
lines changed

services/api-server/src/simcore_service_api_server/db/repositories/users.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import sqlalchemy as sa
22
from models_library.emails import LowerCaseEmailStr
3-
from pydantic import parse_obj_as
3+
from pydantic import TypeAdapter
44

55
from ..tables import UserStatus, users
66
from ._base import BaseRepository
@@ -14,4 +14,8 @@ async def get_active_user_email(self, user_id: int) -> LowerCaseEmailStr | None:
1414
(users.c.id == user_id) & (users.c.status == UserStatus.ACTIVE)
1515
)
1616
)
17-
return parse_obj_as(LowerCaseEmailStr, email) if email is not None else None
17+
return (
18+
TypeAdapter(LowerCaseEmailStr).validate_python(email)
19+
if email is not None
20+
else None
21+
)

services/api-server/src/simcore_service_api_server/models/schemas/jobs.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ def _compute_keyword_arguments_checksum(kwargs: KeywordArguments):
4646
for key in sorted(kwargs.keys()):
4747
value = kwargs[key]
4848
if isinstance(value, File):
49-
value = _compute_keyword_arguments_checksum(value.dict())
49+
value = _compute_keyword_arguments_checksum(value.model_dump())
5050
else:
5151
value = str(value)
5252
_dump_str += f"{key}:{value}"

services/api-server/src/simcore_service_api_server/models/schemas/solvers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ class Solver(BaseModel):
6969

7070
@classmethod
7171
def create_from_image(cls, image_meta: ServiceMetaDataPublished) -> "Solver":
72-
data = image_meta.dict(
72+
data = image_meta.model_dump(
7373
include={"name", "key", "version", "description", "contact"},
7474
)
7575

services/api-server/src/simcore_service_api_server/services/catalog.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ class TruncatedCatalogServiceOut(ServiceMetaDataPublished):
4747

4848
# Converters
4949
def to_solver(self) -> Solver:
50-
data = self.dict(
50+
data = self.model_dump(
5151
include={"name", "key", "version", "description", "contact", "owner"},
5252
)
5353

services/api-server/src/simcore_service_api_server/services/log_streaming.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ async def __aexit__(self, exc_type, exc, tb):
5252

5353
async def _distribute_logs(self, data: bytes):
5454
with log_catch(_logger, reraise=False):
55-
got = LoggerRabbitMessage.parse_raw(data)
55+
got = LoggerRabbitMessage.model_validate_json(data)
5656
item = JobLog(
5757
job_id=got.project_id,
5858
node_id=got.node_id,
@@ -121,12 +121,12 @@ async def log_generator(self) -> AsyncIterable[str]:
121121
log: JobLog = await asyncio.wait_for(
122122
self._queue.get(), timeout=self._log_check_timeout
123123
)
124-
yield log.json() + _NEW_LINE
124+
yield log.model_dump_json() + _NEW_LINE
125125
except asyncio.TimeoutError:
126126
done = await self._project_done()
127127
except BaseBackEndError as exc:
128128
_logger.info("%s", f"{exc}")
129-
yield ErrorGet(errors=[f"{exc}"]).json() + _NEW_LINE
129+
yield ErrorGet(errors=[f"{exc}"]).model_dump_json() + _NEW_LINE
130130
except Exception as exc: # pylint: disable=W0718
131131
error_code = create_error_code(exc)
132132
_logger.exception(
@@ -139,6 +139,6 @@ async def log_generator(self) -> AsyncIterable[str]:
139139
errors=[
140140
MSG_INTERNAL_ERROR_USER_FRIENDLY_TEMPLATE + f" (OEC: {error_code})"
141141
]
142-
).json() + _NEW_LINE
142+
).model_dump_json() + _NEW_LINE
143143
finally:
144144
await self._log_distributor.deregister(self._job_id)

services/api-server/src/simcore_service_api_server/services/solver_job_outputs.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import aiopg
55
from models_library.projects import ProjectID, ProjectIDStr
66
from models_library.projects_nodes_io import BaseFileLink, NodeID, NodeIDStr
7-
from pydantic import StrictBool, StrictFloat, StrictInt, parse_obj_as
7+
from pydantic import StrictBool, StrictFloat, StrictInt, TypeAdapter
88
from simcore_sdk import node_ports_v2
99
from simcore_sdk.node_ports_v2 import DBManager, Nodeports
1010
from simcore_service_api_server.exceptions.backend_errors import (
@@ -44,7 +44,7 @@ async def get_solver_output_results(
4444
port.property_type,
4545
port.value,
4646
)
47-
assert parse_obj_as(ResultsTypes, port.value) == port.value # type: ignore # nosec
47+
assert TypeAdapter(ResultsTypes).validate_python(port.value) == port.value # type: ignore # nosec
4848

4949
solver_output_results[port.key] = port.value
5050

services/api-server/src/simcore_service_api_server/services/study_job_models_converters.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from models_library.projects import DateTimeStr
1414
from models_library.projects_nodes import InputID
1515
from models_library.projects_nodes_io import LinkToFileTypes, NodeID, SimcoreS3FileID
16-
from pydantic import parse_obj_as
16+
from pydantic import TypeAdapter
1717

1818
from ..models.domain.projects import InputTypes, SimCoreFileLink
1919
from ..models.schemas.files import File
@@ -107,7 +107,7 @@ async def create_job_outputs_from_project_outputs(
107107
and {"store", "path"}.issubset(value.keys())
108108
):
109109
assert ( # nosec
110-
parse_obj_as(LinkToFileTypes, value) is not None # type: ignore[arg-type]
110+
TypeAdapter(LinkToFileTypes).validate_python(value) is not None
111111
)
112112

113113
path = value["path"]

services/api-server/src/simcore_service_api_server/services/webserver.py

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -234,23 +234,25 @@ async def _wait_for_long_running_task_results(self, lrt_response: httpx.Response
234234
f"{result_url}", cookies=self.session_cookies
235235
)
236236
result_response.raise_for_status()
237-
return Envelope.parse_raw(result_response.text).data
237+
return Envelope.model_validate_json(result_response.text).data
238238

239239
# PROFILE --------------------------------------------------
240240

241241
@_exception_mapper(_PROFILE_STATUS_MAP)
242242
async def get_me(self) -> Profile:
243243
response = await self.client.get("/me", cookies=self.session_cookies)
244244
response.raise_for_status()
245-
profile: Profile | None = Envelope[Profile].parse_raw(response.text).data
245+
profile: Profile | None = (
246+
Envelope[Profile].model_validate_json(response.text).data
247+
)
246248
assert profile is not None # nosec
247249
return profile
248250

249251
@_exception_mapper(_PROFILE_STATUS_MAP)
250252
async def update_me(self, *, profile_update: ProfileUpdate) -> Profile:
251253
response = await self.client.put(
252254
"/me",
253-
json=profile_update.dict(exclude_none=True),
255+
json=profile_update.model_dump(exclude_none=True),
254256
cookies=self.session_cookies,
255257
)
256258
response.raise_for_status()
@@ -316,7 +318,7 @@ async def get_project(self, *, project_id: UUID) -> ProjectGet:
316318
cookies=self.session_cookies,
317319
)
318320
response.raise_for_status()
319-
data = Envelope[ProjectGet].parse_raw(response.text).data
321+
data = Envelope[ProjectGet].model_validate_json(response.text).data
320322
assert data is not None # nosec
321323
return data
322324

@@ -360,7 +362,7 @@ async def get_project_metadata_ports(
360362
cookies=self.session_cookies,
361363
)
362364
response.raise_for_status()
363-
data = Envelope[list[StudyPort]].parse_raw(response.text).data
365+
data = Envelope[list[StudyPort]].model_validate_json(response.text).data
364366
assert data is not None # nosec
365367
assert isinstance(data, list) # nosec
366368
return data
@@ -374,7 +376,7 @@ async def get_project_metadata(
374376
cookies=self.session_cookies,
375377
)
376378
response.raise_for_status()
377-
data = Envelope[ProjectMetadataGet].parse_raw(response.text).data
379+
data = Envelope[ProjectMetadataGet].model_validate_json(response.text).data
378380
assert data is not None # nosec
379381
return data
380382

@@ -397,7 +399,7 @@ async def update_project_metadata(
397399
json=jsonable_encoder(ProjectMetadataUpdate(custom=metadata)),
398400
)
399401
response.raise_for_status()
400-
data = Envelope[ProjectMetadataGet].parse_raw(response.text).data
402+
data = Envelope[ProjectMetadataGet].model_validate_json(response.text).data
401403
assert data is not None # nosec
402404
return data
403405

@@ -411,7 +413,7 @@ async def get_project_node_pricing_unit(
411413
)
412414

413415
response.raise_for_status()
414-
data = Envelope[PricingUnitGet].parse_raw(response.text).data
416+
data = Envelope[PricingUnitGet].model_validate_json(response.text).data
415417
assert data is not None # nosec
416418
return data
417419

@@ -466,7 +468,9 @@ async def update_project_inputs(
466468
)
467469
response.raise_for_status()
468470
data: dict[NodeID, ProjectInputGet] | None = (
469-
Envelope[dict[NodeID, ProjectInputGet]].parse_raw(response.text).data
471+
Envelope[dict[NodeID, ProjectInputGet]]
472+
.model_validate_json(response.text)
473+
.data
470474
)
471475
assert data is not None # nosec
472476
return data
@@ -483,7 +487,9 @@ async def get_project_inputs(
483487
response.raise_for_status()
484488

485489
data: dict[NodeID, ProjectInputGet] | None = (
486-
Envelope[dict[NodeID, ProjectInputGet]].parse_raw(response.text).data
490+
Envelope[dict[NodeID, ProjectInputGet]]
491+
.model_validate_json(response.text)
492+
.data
487493
)
488494
assert data is not None # nosec
489495
return data
@@ -500,7 +506,9 @@ async def get_project_outputs(
500506
response.raise_for_status()
501507

502508
data: dict[NodeID, dict[str, Any]] | None = (
503-
Envelope[dict[NodeID, dict[str, Any]]].parse_raw(response.text).data
509+
Envelope[dict[NodeID, dict[str, Any]]]
510+
.model_validate_json(response.text)
511+
.data
504512
)
505513
assert data is not None # nosec
506514
return data
@@ -525,7 +533,11 @@ async def get_default_wallet(self) -> WalletGetWithAvailableCredits:
525533
cookies=self.session_cookies,
526534
)
527535
response.raise_for_status()
528-
data = Envelope[WalletGetWithAvailableCredits].parse_raw(response.text).data
536+
data = (
537+
Envelope[WalletGetWithAvailableCredits]
538+
.model_validate_json(response.text)
539+
.data
540+
)
529541
assert data is not None # nosec
530542
return data
531543

@@ -536,7 +548,11 @@ async def get_wallet(self, *, wallet_id: int) -> WalletGetWithAvailableCredits:
536548
cookies=self.session_cookies,
537549
)
538550
response.raise_for_status()
539-
data = Envelope[WalletGetWithAvailableCredits].parse_raw(response.text).data
551+
data = (
552+
Envelope[WalletGetWithAvailableCredits]
553+
.model_validate_json(response.text)
554+
.data
555+
)
540556
assert data is not None # nosec
541557
return data
542558

@@ -547,7 +563,7 @@ async def get_project_wallet(self, *, project_id: ProjectID) -> WalletGet | None
547563
cookies=self.session_cookies,
548564
)
549565
response.raise_for_status()
550-
data = Envelope[WalletGet].parse_raw(response.text).data
566+
data = Envelope[WalletGet].model_validate_json(response.text).data
551567
assert data is not None # nosec
552568
return data
553569

@@ -560,7 +576,7 @@ async def get_product_price(self) -> GetCreditPrice:
560576
cookies=self.session_cookies,
561577
)
562578
response.raise_for_status()
563-
data = Envelope[GetCreditPrice].parse_raw(response.text).data
579+
data = Envelope[GetCreditPrice].model_validate_json(response.text).data
564580
assert data is not None # nosec
565581
return data
566582

@@ -577,10 +593,12 @@ async def get_service_pricing_plan(
577593
cookies=self.session_cookies,
578594
)
579595
response.raise_for_status()
580-
pricing_plan_get = Envelope[PricingPlanGet].parse_raw(response.text).data
596+
pricing_plan_get = (
597+
Envelope[PricingPlanGet].model_validate_json(response.text).data
598+
)
581599
if pricing_plan_get:
582-
return ServicePricingPlanGet.construct(
583-
**pricing_plan_get.dict(exclude={"is_active"})
600+
return ServicePricingPlanGet.model_construct(
601+
**pricing_plan_get.model_dump(exclude={"is_active"})
584602
)
585603
return None
586604

services/api-server/tests/unit/api_solvers/test_api_routers_solvers_jobs.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
from fastapi import FastAPI
1919
from models_library.services import ServiceMetaDataPublished
2020
from models_library.utils.fastapi_encoders import jsonable_encoder
21-
from pydantic import AnyUrl, HttpUrl, parse_obj_as
21+
from pydantic import AnyUrl, HttpUrl, TypeAdapter
2222
from respx import MockRouter
2323
from simcore_service_api_server._meta import API_VTAG
2424
from simcore_service_api_server.core.settings import ApplicationSettings
@@ -55,7 +55,7 @@ def presigned_download_link(
5555
) -> Iterator[AnyUrl]:
5656
s3_client = boto3.client(
5757
"s3",
58-
endpoint_url=mocked_s3_server_url,
58+
endpoint_url=f"{mocked_s3_server_url}",
5959
# Some fake auth, otherwise botocore.exceptions.NoCredentialsError: Unable to locate credentials
6060
aws_secret_access_key="xxx", # noqa: S106
6161
aws_access_key_id="xxx",
@@ -79,7 +79,7 @@ def presigned_download_link(
7979
print("generated link", presigned_url)
8080

8181
# SEE also https://gist.github.com/amarjandu/77a7d8e33623bae1e4e5ba40dc043cb9
82-
return parse_obj_as(AnyUrl, presigned_url)
82+
return TypeAdapter(AnyUrl).validate_python(presigned_url)
8383

8484

8585
@pytest.fixture
@@ -350,7 +350,7 @@ async def test_run_solver_job(
350350
# Tests https://github.com/ITISFoundation/osparc-issues/issues/948
351351
"a_list": [1, 2, 3],
352352
}
353-
).dict(),
353+
).model_dump(),
354354
)
355355
assert resp.status_code == status.HTTP_201_CREATED
356356

services/api-server/tests/unit/api_studies/test_api_routes_studies_jobs.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
import respx
1515
from faker import Faker
1616
from fastapi import status
17-
from pydantic import parse_obj_as
1817
from pytest_simcore.helpers.httpx_calls_capture_models import (
1918
CreateRespxMockCallback,
2019
HttpApiCallCaptureModel,
@@ -45,7 +44,7 @@ async def test_studies_jobs_workflow(
4544
resp = await client.get("/v0/studies/{study_id}", auth=auth)
4645
assert resp.status_code == status.HTTP_200_OK
4746

48-
study = parse_obj_as(Study, resp.json())
47+
study = Study.model_validate(resp.json())
4948
assert study.uid == study_id
5049

5150
# Lists study jobs
@@ -56,7 +55,7 @@ async def test_studies_jobs_workflow(
5655
resp = await client.post("/v0/studies/{study_id}/jobs", auth=auth)
5756
assert resp.status_code == status.HTTP_201_CREATED
5857

59-
job = parse_obj_as(Job, resp.json())
58+
job = Job.model_validate(resp.json())
6059
job_id = job.id
6160

6261
# Get Study Job

0 commit comments

Comments
 (0)