From 079e9d4261604a83af1ead39825506178a308028 Mon Sep 17 00:00:00 2001 From: Giancarlo Romeo Date: Thu, 10 Oct 2024 10:21:11 +0200 Subject: [PATCH 01/37] upgrade reqs --- services/api-server/requirements/_base.txt | 344 ++++++++++++++++++-- services/api-server/requirements/_test.txt | 19 -- services/api-server/requirements/_tools.txt | 10 - 3 files changed, 324 insertions(+), 49 deletions(-) diff --git a/services/api-server/requirements/_base.txt b/services/api-server/requirements/_base.txt index a132d7fb2a6..2665017fcb3 100644 --- a/services/api-server/requirements/_base.txt +++ b/services/api-server/requirements/_base.txt @@ -1,16 +1,55 @@ aio-pika==9.4.1 + # via + # -r requirements/../../../packages/service-library/requirements/_base.in + # -r requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/_base.in aiocache==0.12.2 + # via -r requirements/../../../packages/simcore-sdk/requirements/_base.in aiodebug==2.3.0 + # via + # -r requirements/../../../packages/service-library/requirements/_base.in + # -r requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/_base.in aiodocker==0.21.0 + # via + # -r requirements/../../../packages/service-library/requirements/_base.in + # -r requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/_base.in aiofiles==23.2.1 + # via + # -r requirements/../../../packages/service-library/requirements/_base.in + # -r requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/_base.in + # -r requirements/../../../packages/simcore-sdk/requirements/_base.in + # -r requirements/_base.in aiohttp==3.9.3 - # via aiodocker + # via + # -c requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/postgres-database/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/postgres-database/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../requirements/constraints.txt + # -c requirements/../../../requirements/constraints.txt + # -r requirements/../../../packages/simcore-sdk/requirements/_base.in + # aiodocker aiopg==1.4.0 + # via + # -r requirements/../../../packages/simcore-sdk/requirements/_base.in + # -r requirements/_base.in aiormq==6.8.0 # via aio-pika aiosignal==1.3.1 # via aiohttp alembic==1.13.1 + # via + # -r requirements/../../../packages/postgres-database/requirements/_base.in + # -r requirements/../../../packages/simcore-sdk/requirements/../../../packages/postgres-database/requirements/_base.in +annotated-types==0.7.0 + # via pydantic anyio==4.3.0 # via # fast-depends @@ -19,12 +58,17 @@ anyio==4.3.0 # starlette # watchfiles arrow==1.3.0 + # via + # -r requirements/../../../packages/models-library/requirements/_base.in + # -r requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/_base.in + # -r requirements/../../../packages/service-library/requirements/_base.in + # -r requirements/../../../packages/simcore-sdk/requirements/../../../packages/models-library/requirements/_base.in + # -r requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/_base.in + # -r requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/_base.in async-timeout==4.0.3 # via - # aiohttp # aiopg # asyncpg - # redis asyncpg==0.29.0 # via sqlalchemy attrs==23.2.0 @@ -33,6 +77,20 @@ attrs==23.2.0 # jsonschema certifi==2024.2.2 # via + # -c requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/postgres-database/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/postgres-database/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../requirements/constraints.txt + # -c requirements/../../../requirements/constraints.txt # httpcore # httpx cffi==1.16.0 @@ -42,22 +100,46 @@ click==8.1.7 # typer # uvicorn cryptography==42.0.5 + # via + # -c requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/postgres-database/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/postgres-database/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../requirements/constraints.txt + # -c requirements/../../../requirements/constraints.txt + # -r requirements/_base.in dnspython==2.6.1 # via email-validator email-validator==2.1.1 # via # fastapi # pydantic -exceptiongroup==1.2.0 - # via anyio fast-depends==2.4.2 # via faststream -fastapi==0.99.1 +fastapi==0.114.2 # via + # -r requirements/../../../packages/service-library/requirements/_fastapi.in + # -r requirements/_base.in # fastapi-pagination # prometheus-fastapi-instrumentator +fastapi-cli==0.0.5 + # via fastapi fastapi-pagination==0.12.17 + # via + # -c requirements/./constraints.txt + # -r requirements/_base.in faststream==0.5.10 + # via + # -r requirements/../../../packages/service-library/requirements/_base.in + # -r requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/_base.in frozenlist==1.4.1 # via # aiohttp @@ -73,7 +155,24 @@ httpcore==1.0.5 httptools==0.6.1 # via uvicorn httpx==0.27.0 - # via fastapi + # via + # -c requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/postgres-database/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/postgres-database/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../requirements/constraints.txt + # -c requirements/../../../requirements/constraints.txt + # -r requirements/../../../packages/service-library/requirements/_fastapi.in + # -r requirements/_base.in + # fastapi idna==3.6 # via # anyio @@ -83,10 +182,46 @@ idna==3.6 itsdangerous==2.1.2 # via fastapi jinja2==3.1.3 - # via fastapi + # via + # -c requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/postgres-database/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/postgres-database/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../requirements/constraints.txt + # -c requirements/../../../requirements/constraints.txt + # fastapi jsonschema==3.2.0 + # via + # -c requirements/./constraints.txt + # -r requirements/../../../packages/models-library/requirements/_base.in + # -r requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/_base.in + # -r requirements/../../../packages/simcore-sdk/requirements/../../../packages/models-library/requirements/_base.in + # -r requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/_base.in mako==1.3.2 - # via alembic + # via + # -c requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/postgres-database/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/postgres-database/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../requirements/constraints.txt + # -c requirements/../../../requirements/constraints.txt + # alembic markdown-it-py==3.0.0 # via rich markupsafe==2.1.5 @@ -100,46 +235,166 @@ multidict==6.0.5 # aiohttp # yarl orjson==3.10.0 - # via fastapi + # via + # -c requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/postgres-database/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/postgres-database/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../requirements/constraints.txt + # -c requirements/../../../requirements/constraints.txt + # -r requirements/../../../packages/models-library/requirements/_base.in + # -r requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/_base.in + # -r requirements/../../../packages/simcore-sdk/requirements/../../../packages/models-library/requirements/_base.in + # -r requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/_base.in + # -r requirements/_base.in + # fastapi packaging==24.0 + # via + # -r requirements/../../../packages/simcore-sdk/requirements/_base.in + # -r requirements/_base.in pamqp==3.3.0 # via aiormq parse==1.20.2 + # via -r requirements/_base.in pint==0.23 + # via -r requirements/../../../packages/simcore-sdk/requirements/_base.in prometheus-client==0.20.0 - # via prometheus-fastapi-instrumentator + # via + # -r requirements/../../../packages/service-library/requirements/_fastapi.in + # prometheus-fastapi-instrumentator prometheus-fastapi-instrumentator==6.1.0 + # via -r requirements/../../../packages/service-library/requirements/_fastapi.in psycopg2-binary==2.9.9 # via # aiopg # sqlalchemy pycparser==2.22 # via cffi -pydantic==1.10.14 +pydantic==2.9.2 # via + # -c requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/postgres-database/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/postgres-database/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../requirements/constraints.txt + # -c requirements/../../../requirements/constraints.txt + # -r requirements/../../../packages/models-library/requirements/_base.in + # -r requirements/../../../packages/postgres-database/requirements/_base.in + # -r requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/_base.in + # -r requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/_base.in + # -r requirements/../../../packages/service-library/requirements/_base.in + # -r requirements/../../../packages/settings-library/requirements/_base.in + # -r requirements/../../../packages/simcore-sdk/requirements/../../../packages/models-library/requirements/_base.in + # -r requirements/../../../packages/simcore-sdk/requirements/../../../packages/postgres-database/requirements/_base.in + # -r requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/_base.in + # -r requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/_base.in + # -r requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/_base.in + # -r requirements/../../../packages/simcore-sdk/requirements/../../../packages/settings-library/requirements/_base.in + # -r requirements/../../../packages/simcore-sdk/requirements/_base.in + # -r requirements/_base.in # fast-depends # fastapi # fastapi-pagination + # pydantic-extra-types + # pydantic-settings +pydantic-core==2.23.4 + # via pydantic +pydantic-extra-types==2.9.0 + # via + # -r requirements/../../../packages/models-library/requirements/_base.in + # -r requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/_base.in + # -r requirements/../../../packages/simcore-sdk/requirements/../../../packages/models-library/requirements/_base.in + # -r requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/_base.in + # fastapi +pydantic-settings==2.5.2 + # via + # -r requirements/../../../packages/models-library/requirements/_base.in + # -r requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/_base.in + # -r requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/_base.in + # -r requirements/../../../packages/settings-library/requirements/_base.in + # -r requirements/../../../packages/simcore-sdk/requirements/../../../packages/models-library/requirements/_base.in + # -r requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/_base.in + # -r requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/_base.in + # -r requirements/../../../packages/simcore-sdk/requirements/../../../packages/settings-library/requirements/_base.in + # fastapi pygments==2.17.2 # via rich pyinstrument==4.6.2 + # via + # -r requirements/../../../packages/service-library/requirements/_base.in + # -r requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/_base.in pyrsistent==0.20.0 # via jsonschema python-dateutil==2.9.0.post0 # via arrow python-dotenv==1.0.1 # via - # pydantic + # pydantic-settings # uvicorn python-multipart==0.0.9 # via fastapi pyyaml==6.0.1 # via + # -c requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/postgres-database/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/postgres-database/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../requirements/constraints.txt + # -c requirements/../../../requirements/constraints.txt + # -r requirements/../../../packages/service-library/requirements/_base.in + # -r requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/_base.in + # -r requirements/_base.in # fastapi # uvicorn redis==5.0.4 + # via + # -c requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/postgres-database/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/postgres-database/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../requirements/constraints.txt + # -c requirements/../../../requirements/constraints.txt + # -r requirements/../../../packages/service-library/requirements/_base.in + # -r requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/_base.in rich==13.7.1 - # via typer + # via + # -r requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/_base.in + # -r requirements/../../../packages/settings-library/requirements/_base.in + # -r requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/_base.in + # -r requirements/../../../packages/simcore-sdk/requirements/../../../packages/settings-library/requirements/_base.in + # typer setuptools==69.2.0 # via jsonschema shellingham==1.5.4 @@ -154,9 +409,25 @@ sniffio==1.3.1 # httpx sqlalchemy==1.4.52 # via + # -c requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/postgres-database/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/postgres-database/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../requirements/constraints.txt + # -c requirements/../../../requirements/constraints.txt + # -r requirements/../../../packages/postgres-database/requirements/_base.in + # -r requirements/../../../packages/simcore-sdk/requirements/../../../packages/postgres-database/requirements/_base.in # aiopg # alembic -starlette==0.27.0 +starlette==0.38.5 # via # -c requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/postgres-database/requirements/../../../requirements/constraints.txt @@ -180,9 +451,23 @@ tenacity==8.5.0 # -r requirements/../../../packages/simcore-sdk/requirements/_base.in # -r requirements/_base.in toolz==0.12.1 + # via + # -r requirements/../../../packages/service-library/requirements/_base.in + # -r requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/_base.in tqdm==4.66.2 + # via + # -r requirements/../../../packages/service-library/requirements/_base.in + # -r requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/_base.in + # -r requirements/../../../packages/simcore-sdk/requirements/_base.in typer==0.12.3 - # via faststream + # via + # -r requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/_base.in + # -r requirements/../../../packages/settings-library/requirements/_base.in + # -r requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/_base.in + # -r requirements/../../../packages/simcore-sdk/requirements/../../../packages/settings-library/requirements/_base.in + # -r requirements/_base.in + # fastapi-cli + # faststream types-python-dateutil==2.9.0.20240316 # via arrow typing-extensions==4.10.0 @@ -190,18 +475,35 @@ typing-extensions==4.10.0 # aiodebug # aiodocker # alembic - # anyio # fastapi # fastapi-pagination # faststream # pint # pydantic + # pydantic-core # typer - # uvicorn ujson==5.9.0 - # via fastapi + # via + # -c requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/postgres-database/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/postgres-database/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../requirements/constraints.txt + # -c requirements/../../../requirements/constraints.txt + # fastapi uvicorn==0.29.0 - # via fastapi + # via + # -r requirements/../../../packages/service-library/requirements/_fastapi.in + # fastapi + # fastapi-cli uvloop==0.19.0 # via uvicorn watchfiles==0.21.0 @@ -210,6 +512,8 @@ websockets==12.0 # via uvicorn yarl==1.9.4 # via + # -r requirements/../../../packages/postgres-database/requirements/_base.in + # -r requirements/../../../packages/simcore-sdk/requirements/../../../packages/postgres-database/requirements/_base.in # aio-pika # aiohttp # aiormq diff --git a/services/api-server/requirements/_test.txt b/services/api-server/requirements/_test.txt index 8a1ddb9caa4..323a41f35d6 100644 --- a/services/api-server/requirements/_test.txt +++ b/services/api-server/requirements/_test.txt @@ -19,10 +19,6 @@ anyio==4.3.0 # httpx asgi-lifespan==2.1.0 # via -r requirements/_test.in -async-timeout==4.0.3 - # via - # -c requirements/_base.txt - # aiohttp attrs==23.2.0 # via # -c requirements/_base.txt @@ -91,11 +87,6 @@ ecdsa==0.19.0 # moto # python-jose # sshpubkeys -exceptiongroup==1.2.0 - # via - # -c requirements/_base.txt - # anyio - # pytest faker==27.0.0 # via -r requirements/_test.in flask==2.1.3 @@ -111,10 +102,6 @@ frozenlist==1.4.1 # aiosignal graphql-core==3.2.3 # via moto -greenlet==3.0.3 - # via - # -c requirements/_base.txt - # sqlalchemy h11==0.14.0 # via # -c requirements/_base.txt @@ -318,11 +305,6 @@ sqlalchemy2-stubs==0.0.2a38 # via sqlalchemy sshpubkeys==3.3.1 # via moto -tomli==2.0.1 - # via - # coverage - # mypy - # pytest types-aiofiles==24.1.0.20240626 # via -r requirements/_test.in types-awscrt==0.21.2 @@ -335,7 +317,6 @@ typing-extensions==4.10.0 # via # -c requirements/_base.txt # alembic - # anyio # boto3-stubs # mypy # sqlalchemy2-stubs diff --git a/services/api-server/requirements/_tools.txt b/services/api-server/requirements/_tools.txt index ee67b7d505f..a741d4f592a 100644 --- a/services/api-server/requirements/_tools.txt +++ b/services/api-server/requirements/_tools.txt @@ -91,22 +91,12 @@ setuptools==69.2.0 # -c requirements/_base.txt # -c requirements/_test.txt # pip-tools -tomli==2.0.1 - # via - # -c requirements/_test.txt - # black - # build - # mypy - # pip-tools - # pylint tomlkit==0.13.2 # via pylint typing-extensions==4.10.0 # via # -c requirements/_base.txt # -c requirements/_test.txt - # astroid - # black # mypy virtualenv==20.26.3 # via pre-commit From 0fb353aba52692f1a879d21e4e1462c64efde263 Mon Sep 17 00:00:00 2001 From: Giancarlo Romeo Date: Thu, 10 Oct 2024 10:24:02 +0200 Subject: [PATCH 02/37] fix code --- .../api/routes/solvers.py | 2 - .../api/routes/solvers_jobs.py | 2 +- .../core/application.py | 2 +- .../core/settings.py | 50 ++++++++++----- .../exceptions/_base.py | 2 +- .../models/api_resources.py | 28 ++++----- .../models/basic_types.py | 15 ++--- .../models/pagination.py | 18 +++--- .../models/schemas/errors.py | 9 +-- .../models/schemas/files.py | 40 ++++++------ .../models/schemas/jobs.py | 62 +++++++++---------- .../models/schemas/meta.py | 10 ++- .../models/schemas/profiles.py | 14 ++--- .../models/schemas/solvers.py | 34 +++++----- .../models/schemas/studies.py | 8 ++- .../services/catalog.py | 28 ++++++--- .../services/director_v2.py | 26 +++++--- .../services/solver_job_models_converters.py | 34 +++++----- .../services/storage.py | 20 +++--- .../services/webserver.py | 4 +- .../tests/unit/_with_db/conftest.py | 2 +- .../tests/unit/_with_db/test_api_user.py | 4 +- .../tests/unit/api_solvers/conftest.py | 4 +- .../test_api_routers_solvers_jobs.py | 8 +-- .../test_api_routers_solvers_jobs_delete.py | 17 +++-- .../test_api_routers_solvers_jobs_logs.py | 14 ++--- .../test_api_routers_solvers_jobs_metadata.py | 18 +++--- .../test_api_routers_solvers_jobs_read.py | 11 ++-- .../test_api_routers_studies_jobs_metadata.py | 11 ++-- .../api_studies/test_api_routes_studies.py | 16 ++--- .../test_api_routes_studies_jobs.py | 8 +-- .../unit/captures/test__mocks_captures.py | 8 +-- services/api-server/tests/unit/conftest.py | 4 +- .../api-server/tests/unit/test__fastapi.py | 4 +- .../api-server/tests/unit/test_api_files.py | 4 +- .../tests/unit/test_api_solver_jobs.py | 12 ++-- .../api-server/tests/unit/test_credits.py | 2 +- services/api-server/tests/unit/test_models.py | 2 +- .../tests/unit/test_models_schemas_files.py | 2 +- .../tests/unit/test_models_schemas_jobs.py | 4 +- .../tests/unit/test_models_schemas_solvers.py | 2 +- .../tests/unit/test_services_rabbitmq.py | 12 ++-- ...t_services_solver_job_models_converters.py | 24 +++---- 43 files changed, 327 insertions(+), 274 deletions(-) diff --git a/services/api-server/src/simcore_service_api_server/api/routes/solvers.py b/services/api-server/src/simcore_service_api_server/api/routes/solvers.py index 18e23820826..83e1289698a 100644 --- a/services/api-server/src/simcore_service_api_server/api/routes/solvers.py +++ b/services/api-server/src/simcore_service_api_server/api/routes/solvers.py @@ -7,7 +7,6 @@ from httpx import HTTPStatusError from models_library.api_schemas_api_server.pricing_plans import ServicePricingPlanGet from pydantic import ValidationError -from pydantic.errors import PydanticValueError from ...exceptions.service_errors_utils import DEFAULT_BACKEND_SERVICE_STATUS_CODES from ...models.basic_types import VersionStr @@ -230,7 +229,6 @@ async def get_solver_release( IndexError, ValidationError, HTTPStatusError, - PydanticValueError, ) as err: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, diff --git a/services/api-server/src/simcore_service_api_server/api/routes/solvers_jobs.py b/services/api-server/src/simcore_service_api_server/api/routes/solvers_jobs.py index 560d656d5d4..4e10d367434 100644 --- a/services/api-server/src/simcore_service_api_server/api/routes/solvers_jobs.py +++ b/services/api-server/src/simcore_service_api_server/api/routes/solvers_jobs.py @@ -51,7 +51,7 @@ def _compose_job_resource_name(solver_key, solver_version, job_id) -> str: """Creates a unique resource name for solver's jobs""" return Job.compose_resource_name( - parent_name=Solver.compose_resource_name(solver_key, solver_version), # type: ignore + parent_name=Solver.compose_resource_name(solver_key, solver_version), job_id=job_id, ) diff --git a/services/api-server/src/simcore_service_api_server/core/application.py b/services/api-server/src/simcore_service_api_server/core/application.py index 82612bfe86c..30560b924b0 100644 --- a/services/api-server/src/simcore_service_api_server/core/application.py +++ b/services/api-server/src/simcore_service_api_server/core/application.py @@ -53,7 +53,7 @@ def init_app(settings: ApplicationSettings | None = None) -> FastAPI: config_all_loggers( log_format_local_dev_enabled=settings.API_SERVER_LOG_FORMAT_LOCAL_DEV_ENABLED ) - _logger.debug("App settings:\n%s", settings.json(indent=2)) + _logger.debug("App settings:\n%s", settings.model_dump_json(indent=2)) # Labeling title = "osparc.io public API" diff --git a/services/api-server/src/simcore_service_api_server/core/settings.py b/services/api-server/src/simcore_service_api_server/core/settings.py index 9cc61e1c11a..d717258bad4 100644 --- a/services/api-server/src/simcore_service_api_server/core/settings.py +++ b/services/api-server/src/simcore_service_api_server/core/settings.py @@ -1,8 +1,14 @@ from functools import cached_property from models_library.basic_types import BootModeEnum, LogLevel -from pydantic import Field, NonNegativeInt, PositiveInt, SecretStr -from pydantic.class_validators import validator +from pydantic import ( + AliasChoices, + Field, + NonNegativeInt, + PositiveInt, + SecretStr, + field_validator, +) from settings_library.base import BaseCustomSettings from settings_library.catalog import CatalogSettings from settings_library.director_v2 import DirectorV2Settings @@ -24,11 +30,14 @@ class WebServerSettings(WebServerBaseSettings, MixinSessionSettings): description="Secret key to encrypt cookies. " 'TIP: python3 -c "from cryptography.fernet import *; print(Fernet.generate_key())"', min_length=44, - env=["SESSION_SECRET_KEY", "WEBSERVER_SESSION_SECRET_KEY"], + validation_alias=AliasChoices( + "SESSION_SECRET_KEY", "WEBSERVER_SESSION_SECRET_KEY" + ), ) WEBSERVER_SESSION_NAME: str = DEFAULT_SESSION_COOKIE_NAME - @validator("WEBSERVER_SESSION_SECRET_KEY") + @field_validator("WEBSERVER_SESSION_SECRET_KEY") + @classmethod @classmethod def check_valid_fernet_key(cls, v): return cls.do_check_valid_fernet_key(v) @@ -41,21 +50,25 @@ class BasicSettings(BaseCustomSettings, MixinLoggingSettings): # DEVELOPMENT API_SERVER_DEV_FEATURES_ENABLED: bool = Field( default=False, - env=["API_SERVER_DEV_FEATURES_ENABLED", "FAKE_API_SERVER_ENABLED"], + validation_alias=AliasChoices( + "API_SERVER_DEV_FEATURES_ENABLED", "FAKE_API_SERVER_ENABLED" + ), ) # LOGGING LOG_LEVEL: LogLevel = Field( default=LogLevel.INFO.value, - env=["API_SERVER_LOGLEVEL", "LOG_LEVEL", "LOGLEVEL"], + validation_alias=AliasChoices("API_SERVER_LOGLEVEL", "LOG_LEVEL", "LOGLEVEL"), ) API_SERVER_LOG_FORMAT_LOCAL_DEV_ENABLED: bool = Field( default=False, - env=["API_SERVER_LOG_FORMAT_LOCAL_DEV_ENABLED", "LOG_FORMAT_LOCAL_DEV_ENABLED"], + validation_alias=AliasChoices( + "API_SERVER_LOG_FORMAT_LOCAL_DEV_ENABLED", "LOG_FORMAT_LOCAL_DEV_ENABLED" + ), description="Enables local development log format. WARNING: make sure it is disabled if you want to have structured logs!", ) - @validator("LOG_LEVEL", pre=True) + @field_validator("LOG_LEVEL", mode="before") @classmethod def _validate_loglevel(cls, value) -> str: log_level: str = cls.validate_log_level(value) @@ -66,18 +79,27 @@ class ApplicationSettings(BasicSettings): # DOCKER BOOT SC_BOOT_MODE: BootModeEnum | None - API_SERVER_POSTGRES: PostgresSettings | None = Field(auto_default_from_env=True) + API_SERVER_POSTGRES: PostgresSettings | None = Field( + json_schema_extra={"auto_default_from_env": True} + ) API_SERVER_RABBITMQ: RabbitSettings | None = Field( - auto_default_from_env=True, description="settings for service/rabbitmq" + json_schema_extra={"auto_default_from_env": True}, + description="settings for service/rabbitmq", ) # SERVICES with http API - API_SERVER_WEBSERVER: WebServerSettings | None = Field(auto_default_from_env=True) - API_SERVER_CATALOG: CatalogSettings | None = Field(auto_default_from_env=True) - API_SERVER_STORAGE: StorageSettings | None = Field(auto_default_from_env=True) + API_SERVER_WEBSERVER: WebServerSettings | None = Field( + json_schema_extra={"auto_default_from_env": True} + ) + API_SERVER_CATALOG: CatalogSettings | None = Field( + json_schema_extra={"auto_default_from_env": True} + ) + API_SERVER_STORAGE: StorageSettings | None = Field( + json_schema_extra={"auto_default_from_env": True} + ) API_SERVER_DIRECTOR_V2: DirectorV2Settings | None = Field( - auto_default_from_env=True + json_schema_extra={"auto_default_from_env": True} ) API_SERVER_LOG_CHECK_TIMEOUT_SECONDS: NonNegativeInt = 3 * 60 API_SERVER_PROMETHEUS_INSTRUMENTATION_ENABLED: bool = True diff --git a/services/api-server/src/simcore_service_api_server/exceptions/_base.py b/services/api-server/src/simcore_service_api_server/exceptions/_base.py index 2e0b2e13c4f..5ea7664ec23 100644 --- a/services/api-server/src/simcore_service_api_server/exceptions/_base.py +++ b/services/api-server/src/simcore_service_api_server/exceptions/_base.py @@ -1,6 +1,6 @@ from typing import Any -from models_library.errors_classes import OsparcErrorMixin +from common_library.errors_classes import OsparcErrorMixin class ApiServerBaseError(OsparcErrorMixin, Exception): diff --git a/services/api-server/src/simcore_service_api_server/models/api_resources.py b/services/api-server/src/simcore_service_api_server/models/api_resources.py index 3f64fd323c0..aae7531a837 100644 --- a/services/api-server/src/simcore_service_api_server/models/api_resources.py +++ b/services/api-server/src/simcore_service_api_server/models/api_resources.py @@ -1,9 +1,9 @@ import re import urllib.parse -from typing import Any +from typing import Annotated, Any, TypeAlias -from pydantic import BaseModel, Field -from pydantic.types import ConstrainedStr +from pydantic import BaseModel, Field, TypeAdapter +from pydantic.types import StringConstraints # RESOURCE NAMES https://cloud.google.com/apis/design/resource_names # @@ -30,18 +30,16 @@ _RELATIVE_RESOURCE_NAME_RE = r"^([^\s/]+/?){1,10}$" -class RelativeResourceName(ConstrainedStr): - regex = re.compile(_RELATIVE_RESOURCE_NAME_RE) - - class Config: - frozen = True +RelativeResourceName: TypeAlias = Annotated[ + str, StringConstraints(pattern=_RELATIVE_RESOURCE_NAME_RE) +] # NOTE: we quote parts in a single resource_name and unquote when split def parse_last_resource_id(resource_name: RelativeResourceName) -> str: - if match := RelativeResourceName.regex.match(resource_name): + if match := re.match(_RELATIVE_RESOURCE_NAME_RE, resource_name): last_quoted_part = match.group(1) return urllib.parse.unquote_plus(last_quoted_part) msg = f"Invalid '{resource_name=}' does not match RelativeResourceName" @@ -53,7 +51,7 @@ def compose_resource_name(*collection_or_resource_ids) -> RelativeResourceName: urllib.parse.quote_plus(f"{_id}".lstrip("/")) for _id in collection_or_resource_ids ] - return RelativeResourceName("/".join(quoted_parts)) + return TypeAdapter(RelativeResourceName).validate_python("/".join(quoted_parts)) def split_resource_name(resource_name: RelativeResourceName) -> list[str]: @@ -67,10 +65,12 @@ def split_resource_name(resource_name: RelativeResourceName) -> list[str]: # Resource IDs must be clearly documented whether they are assigned by the client, the server, or either # class BaseResource(BaseModel): - name: RelativeResourceName = Field(None, example="solvers/isolve/releases/1.2.3") - id: Any = Field(None, description="Resource ID", example="1.2.3") # noqa: A003 + name: RelativeResourceName = Field(None, examples=["solvers/isolve/releases/1.2.3"]) + id: Any = Field(None, description="Resource ID", examples=["1.2.3"]) # noqa: A003 class BaseCollection(BaseModel): - name: RelativeResourceName = Field(None, example="solvers/isolve/releases") - id: Any = Field(None, description="Collection ID", example="releases") # noqa: A003 + name: RelativeResourceName = Field(None, examples=["solvers/isolve/releases"]) + id: Any = Field( + None, description="Collection ID", examples=["releases"] + ) # noqa: A003 diff --git a/services/api-server/src/simcore_service_api_server/models/basic_types.py b/services/api-server/src/simcore_service_api_server/models/basic_types.py index 53ea6fe31ce..8e0c4c79af2 100644 --- a/services/api-server/src/simcore_service_api_server/models/basic_types.py +++ b/services/api-server/src/simcore_service_api_server/models/basic_types.py @@ -1,17 +1,14 @@ -import re +from typing import Annotated, TypeAlias from fastapi.responses import StreamingResponse from models_library.basic_regex import SIMPLE_VERSION_RE -from pydantic import ConstrainedStr +from pydantic import StringConstraints +VersionStr: TypeAlias = Annotated[ + str, StringConstraints(strip_whitespace=True, pattern=SIMPLE_VERSION_RE) +] -class VersionStr(ConstrainedStr): - strip_whitespace = True - regex = re.compile(SIMPLE_VERSION_RE) - - -class FileNameStr(ConstrainedStr): - strip_whitespace = True +FileNameStr: TypeAlias = Annotated[str, StringConstraints(strip_whitespace=True)] class LogStreamingResponse(StreamingResponse): diff --git a/services/api-server/src/simcore_service_api_server/models/pagination.py b/services/api-server/src/simcore_service_api_server/models/pagination.py index 44013b068e5..f35969592cc 100644 --- a/services/api-server/src/simcore_service_api_server/models/pagination.py +++ b/services/api-server/src/simcore_service_api_server/models/pagination.py @@ -7,7 +7,7 @@ """ from collections.abc import Sequence -from typing import Any, ClassVar, Generic, TypeAlias, TypeVar +from typing import Generic, TypeAlias, TypeVar from fastapi_pagination.limit_offset import LimitOffsetParams from fastapi_pagination.links.limit_offset import ( @@ -18,8 +18,7 @@ MAXIMUM_NUMBER_OF_ITEMS_PER_PAGE, ) from models_library.utils.pydantic_tools_extension import FieldNotRequired -from pydantic import Field, NonNegativeInt, validator -from pydantic.generics import GenericModel +from pydantic import BaseModel, ConfigDict, Field, NonNegativeInt, field_validator T = TypeVar("T") @@ -35,7 +34,7 @@ PaginationParams: TypeAlias = LimitOffsetParams -class OnePage(GenericModel, Generic[T]): +class OnePage(BaseModel, Generic[T]): """ A single page is used to envelope a small sequence that does not require pagination @@ -47,7 +46,7 @@ class OnePage(GenericModel, Generic[T]): items: Sequence[T] total: NonNegativeInt = FieldNotRequired() - @validator("total", pre=True) + @field_validator("total", mode="before") @classmethod def check_total(cls, v, values): items = values["items"] @@ -60,9 +59,9 @@ def check_total(cls, v, values): return v - class Config: - frozen = True - schema_extra: ClassVar[dict[str, Any]] = { + model_config = ConfigDict( + frozen=True, + json_schema_extra={ "examples": [ { "total": 1, @@ -72,7 +71,8 @@ class Config: "items": ["one"], }, ], - } + }, + ) __all__: tuple[str, ...] = ( diff --git a/services/api-server/src/simcore_service_api_server/models/schemas/errors.py b/services/api-server/src/simcore_service_api_server/models/schemas/errors.py index 306ac959058..3243f5e44b9 100644 --- a/services/api-server/src/simcore_service_api_server/models/schemas/errors.py +++ b/services/api-server/src/simcore_service_api_server/models/schemas/errors.py @@ -1,6 +1,6 @@ -from typing import Any, ClassVar +from typing import Any -from pydantic import BaseModel +from pydantic import BaseModel, ConfigDict class ErrorGet(BaseModel): @@ -11,8 +11,8 @@ class ErrorGet(BaseModel): # - https://github.com/ITISFoundation/osparc-simcore/issues/2446 errors: list[Any] - class Config: - schema_extra: ClassVar[dict[str, Any]] = { + model_config = ConfigDict( + json_schema_extra={ "example": { "errors": [ "some error message", @@ -20,3 +20,4 @@ class Config: ] } } + ) diff --git a/services/api-server/src/simcore_service_api_server/models/schemas/files.py b/services/api-server/src/simcore_service_api_server/models/schemas/files.py index eece67dfa59..42686f0876e 100644 --- a/services/api-server/src/simcore_service_api_server/models/schemas/files.py +++ b/services/api-server/src/simcore_service_api_server/models/schemas/files.py @@ -1,6 +1,6 @@ from mimetypes import guess_type from pathlib import Path -from typing import Any, ClassVar +from typing import Annotated from urllib.parse import quote as _quote from urllib.parse import unquote as _unquote from uuid import UUID, uuid3 @@ -14,18 +14,19 @@ AnyUrl, BaseModel, ByteSize, - ConstrainedStr, + ConfigDict, Field, - parse_obj_as, - validator, + StringConstraints, + TypeAdapter, + ValidationInfo, + field_validator, ) from servicelib.file_utils import create_sha256_checksum _NAMESPACE_FILEID_KEY = UUID("aa154444-d22d-4290-bb15-df37dba87865") -class FileName(ConstrainedStr): - strip_whitespace = True +FileName = Annotated[str, StringConstraints(strip_whitespace=True)] class ClientFile(BaseModel): @@ -46,7 +47,9 @@ class File(BaseModel): filename: str = Field(..., description="Name of the file with extension") content_type: str | None = Field( - default=None, description="Guess of type content [EXPERIMENTAL]" + default=None, + description="Guess of type content [EXPERIMENTAL]", + validate_default=True, ) sha256_checksum: SHA256Str | None = Field( default=None, @@ -55,9 +58,9 @@ class File(BaseModel): ) e_tag: ETag | None = Field(default=None, description="S3 entity tag") - class Config: - allow_population_by_field_name = True - schema_extra: ClassVar[dict[str, Any]] = { + model_config = ConfigDict( + populate_by_name=True, + json_schema_extra={ "examples": [ # complete { @@ -72,13 +75,14 @@ class Config: "filename": "whitepaper.pdf", }, ] - } + }, + ) - @validator("content_type", always=True, pre=True) + @field_validator("content_type", mode="before") @classmethod - def guess_content_type(cls, v, values): + def guess_content_type(cls, v, info: ValidationInfo): if v is None: - filename = values.get("filename") + filename = info.data.get("filename") if filename: mime_content_type, _ = guess_type(filename, strict=False) return mime_content_type @@ -133,8 +137,8 @@ async def create_from_client_file( @classmethod async def create_from_quoted_storage_id(cls, quoted_storage_id: str) -> "File": - storage_file_id: StorageFileID = parse_obj_as( - StorageFileID, _unquote(quoted_storage_id) # type: ignore[arg-type] + storage_file_id: StorageFileID = TypeAdapter(StorageFileID).validate_python( + _unquote(quoted_storage_id) ) _, fid, fname = Path(storage_file_id).parts return cls(id=UUID(fid), filename=fname, checksum=None) @@ -146,8 +150,8 @@ def create_id(cls, *keys) -> UUID: @property def storage_file_id(self) -> StorageFileID: """Get the StorageFileId associated with this file""" - return parse_obj_as( - StorageFileID, f"api/{self.id}/{self.filename}" # type: ignore[arg-type] + return TypeAdapter(StorageFileID).validate_python( + f"api/{self.id}/{self.filename}" ) @property diff --git a/services/api-server/src/simcore_service_api_server/models/schemas/jobs.py b/services/api-server/src/simcore_service_api_server/models/schemas/jobs.py index a190d4e182b..f3c2c16672b 100644 --- a/services/api-server/src/simcore_service_api_server/models/schemas/jobs.py +++ b/services/api-server/src/simcore_service_api_server/models/schemas/jobs.py @@ -1,7 +1,7 @@ import datetime import hashlib import logging -from typing import Any, ClassVar, TypeAlias +from typing import Annotated, TypeAlias from uuid import UUID, uuid4 from models_library.projects import ProjectID @@ -9,24 +9,22 @@ from models_library.projects_state import RunningState from pydantic import ( BaseModel, - ConstrainedInt, - Extra, + ConfigDict, Field, HttpUrl, PositiveInt, StrictBool, StrictFloat, StrictInt, + TypeAdapter, ValidationError, - parse_obj_as, - validator, + field_validator, ) from servicelib.logging_utils import LogLevelInt, LogMessageStr from starlette.datastructures import Headers from ...models.schemas.files import File from ...models.schemas.solvers import Solver -from .._utils_pydantic import BaseConfig from ..api_resources import ( RelativeResourceName, compose_resource_name, @@ -69,10 +67,9 @@ class JobInputs(BaseModel): # TODO: gibt es platz fuer metadata? - class Config(BaseConfig): - frozen = True - allow_mutation = False - schema_extra: ClassVar[dict[str, Any]] = { + model_config = ConfigDict( + frozen=True, + json_schema_extra={ "example": { "values": { "x": 4.33, @@ -85,7 +82,8 @@ class Config(BaseConfig): }, } } - } + }, + ) def compute_checksum(self): return _compute_keyword_arguments_checksum(self.values) @@ -102,10 +100,9 @@ class JobOutputs(BaseModel): # TODO: an error might have occurred at the level of the job, i.e. affects all outputs, or only # on one specific output. - class Config(BaseConfig): - frozen = True - allow_mutation = False - schema_extra: ClassVar[dict[str, Any]] = { + model_config = ConfigDict( + frozen=True, + json_schema_extra={ "example": { "job_id": "99d9ac65-9f10-4e2f-a433-b5e412bb037b", "results": { @@ -119,7 +116,8 @@ class Config(BaseConfig): }, }, } - } + }, + ) def compute_results_checksum(self): return _compute_keyword_arguments_checksum(self.results) @@ -179,8 +177,8 @@ class Job(BaseModel): ..., description="Link to the job outputs (sub-collection)" ) - class Config(BaseConfig): - schema_extra: ClassVar[dict[str, Any]] = { + model_config = ConfigDict( + json_schema_extra={ "example": { "id": "f622946d-fd29-35b9-a193-abdd1095167c", "name": "solvers/isolve/releases/1.3.4/jobs/f622946d-fd29-35b9-a193-abdd1095167c", @@ -192,8 +190,9 @@ class Config(BaseConfig): "outputs_url": "https://api.osparc.io/v0/solvers/isolve/releases/1.3.4/jobs/f622946d-fd29-35b9-a193-abdd1095167c/outputs", } } + ) - @validator("name", pre=True) + @field_validator("name", mode="before") @classmethod def check_name(cls, v, values): _id = str(values["id"]) @@ -224,7 +223,7 @@ def create_now( @classmethod def create_solver_job(cls, *, solver: Solver, inputs: JobInputs): return Job.create_now( - parent_name=solver.name, # type: ignore + parent_name=solver.name, inputs_checksum=inputs.compute_checksum(), ) @@ -247,9 +246,7 @@ def resource_name(self) -> str: return self.name -class PercentageInt(ConstrainedInt): - ge = 0 - le = 100 +PercentageInt = Annotated[int, Field(ge=0, le=100)] class JobStatus(BaseModel): @@ -259,7 +256,7 @@ class JobStatus(BaseModel): job_id: JobID state: RunningState - progress: PercentageInt = Field(default=PercentageInt(0)) + progress: PercentageInt = Field(default=0) # Timestamps on states submitted_at: datetime.datetime = Field( @@ -274,8 +271,8 @@ class JobStatus(BaseModel): description="Timestamp at which the solver finished or killed execution or None if the event did not occur", ) - class Config(BaseConfig): - schema_extra: ClassVar[dict[str, Any]] = { + model_config = ConfigDict( + json_schema_extra={ "example": { "job_id": "145beae4-a3a8-4fde-adbb-4e8257c2c083", "state": RunningState.STARTED, @@ -285,31 +282,31 @@ class Config(BaseConfig): "stopped_at": None, } } + ) class JobPricingSpecification(BaseModel): pricing_plan: PositiveInt = Field(..., alias="x-pricing-plan") pricing_unit: PositiveInt = Field(..., alias="x-pricing-unit") - class Config: - extra = Extra.ignore + model_config = ConfigDict(extra="ignore") @classmethod def create_from_headers(cls, headers: Headers) -> "JobPricingSpecification | None": try: - return parse_obj_as(JobPricingSpecification, headers) + return TypeAdapter(cls).validate_python(headers) except ValidationError: return None class JobLog(BaseModel): job_id: ProjectID - node_id: NodeID | None + node_id: NodeID | None = None log_level: LogLevelInt messages: list[LogMessageStr] - class Config(BaseConfig): - schema_extra: ClassVar[dict[str, Any]] = { + model_config = ConfigDict( + json_schema_extra={ "example": { "job_id": "145beae4-a3a8-4fde-adbb-4e8257c2c083", "node_id": "3742215e-6756-48d2-8b73-4d043065309f", @@ -317,3 +314,4 @@ class Config(BaseConfig): "messages": ["PROGRESS: 5/10"], } } + ) diff --git a/services/api-server/src/simcore_service_api_server/models/schemas/meta.py b/services/api-server/src/simcore_service_api_server/models/schemas/meta.py index ea358f1433f..64f80a45b9b 100644 --- a/services/api-server/src/simcore_service_api_server/models/schemas/meta.py +++ b/services/api-server/src/simcore_service_api_server/models/schemas/meta.py @@ -1,15 +1,12 @@ -from typing import ClassVar - from models_library.api_schemas__common.meta import BaseMeta -from pydantic import AnyHttpUrl +from pydantic import AnyHttpUrl, ConfigDict class Meta(BaseMeta): docs_url: AnyHttpUrl docs_dev_url: AnyHttpUrl - - class Config: - schema_extra: ClassVar = { + model_config = ConfigDict( + json_schema_extra={ "example": { "name": "simcore_service_foo", "version": "2.4.45", @@ -18,3 +15,4 @@ class Config: "docs_dev_url": "https://api.osparc.io/dev/doc", } } + ) diff --git a/services/api-server/src/simcore_service_api_server/models/schemas/profiles.py b/services/api-server/src/simcore_service_api_server/models/schemas/profiles.py index 8f86f2e693f..76b283aa4a9 100644 --- a/services/api-server/src/simcore_service_api_server/models/schemas/profiles.py +++ b/services/api-server/src/simcore_service_api_server/models/schemas/profiles.py @@ -1,17 +1,16 @@ from enum import auto -from typing import Any, ClassVar from models_library.emails import LowerCaseEmailStr from models_library.users import FirstNameStr, LastNameStr, UserID from models_library.utils.enums import StrAutoEnum -from pydantic import BaseModel, Field, validator +from pydantic import BaseModel, ConfigDict, Field, field_validator from ..domain.groups import Groups class ProfileCommon(BaseModel): - first_name: FirstNameStr | None = Field(None, example="James") - last_name: LastNameStr | None = Field(None, example="Maxwell") + first_name: FirstNameStr | None = Field(None, examples=["James"]) + last_name: LastNameStr | None = Field(None, examples=["Maxwell"]) class ProfileUpdate(ProfileCommon): @@ -39,15 +38,15 @@ class Profile(ProfileCommon): max_length=40, ) - @validator("role", pre=True) + @field_validator("role", mode="before") @classmethod def enforce_role_upper(cls, v): if v: return v.upper() return v - class Config: - schema_extra: ClassVar[dict[str, Any]] = { + model_config = ConfigDict( + json_schema_extra={ "example": { "id": "20", "first_name": "James", @@ -70,3 +69,4 @@ class Config: "gravatar_id": "9a8930a5b20d7048e37740bac5c1ca4f", } } + ) diff --git a/services/api-server/src/simcore_service_api_server/models/schemas/solvers.py b/services/api-server/src/simcore_service_api_server/models/schemas/solvers.py index a99017852a5..f7531346e84 100644 --- a/services/api-server/src/simcore_service_api_server/models/schemas/solvers.py +++ b/services/api-server/src/simcore_service_api_server/models/schemas/solvers.py @@ -1,12 +1,12 @@ import urllib.parse -from typing import Any, ClassVar, Literal +from typing import Annotated, Any, Literal import packaging.version from models_library.basic_regex import PUBLIC_VARIABLE_NAME_RE from models_library.services import ServiceMetaDataPublished from models_library.services_regex import COMPUTATIONAL_SERVICE_KEY_RE from packaging.version import Version -from pydantic import BaseModel, ConstrainedStr, Extra, Field, HttpUrl +from pydantic import BaseModel, ConfigDict, Field, HttpUrl, StringConstraints from ..api_resources import compose_resource_name from ..basic_types import VersionStr @@ -30,9 +30,9 @@ SOLVER_RESOURCE_NAME_RE = r"^solvers/([^\s/]+)/releases/([\d\.]+)$" -class SolverKeyId(ConstrainedStr): - strip_whitespace = True - regex = COMPUTATIONAL_SERVICE_KEY_RE +SolverKeyId = Annotated[ + str, StringConstraints(strip_whitespace=True, pattern=COMPUTATIONAL_SERVICE_KEY_RE) +] class Solver(BaseModel): @@ -46,17 +46,16 @@ class Solver(BaseModel): # Human readables Identifiers title: str = Field(..., description="Human readable name") - description: str | None + description: str | None = None maintainer: str # TODO: consider released: Optional[datetime] required? # TODO: consider version_aliases: list[str] = [] # remaining tags # Get links to other resources url: HttpUrl | None = Field(..., description="Link to get this resource") - - class Config: - extra = Extra.ignore - schema_extra: ClassVar[dict[str, Any]] = { + model_config = ConfigDict( + extra="ignore", + json_schema_extra={ "example": { "id": "simcore/services/comp/isolve", "version": "2.1.1", @@ -65,7 +64,8 @@ class Config: "maintainer": "info@itis.swiss", "url": "https://api.osparc.io/v0/solvers/simcore%2Fservices%2Fcomp%2Fisolve/releases/2.1.1", } - } + }, + ) @classmethod def create_from_image(cls, image_meta: ServiceMetaDataPublished) -> "Solver": @@ -114,7 +114,7 @@ class SolverPort(BaseModel): key: str = Field( ..., description="port identifier name", - regex=PUBLIC_VARIABLE_NAME_RE, + pattern=PUBLIC_VARIABLE_NAME_RE, title="Key name", ) kind: PortKindStr @@ -122,10 +122,9 @@ class SolverPort(BaseModel): None, description="jsonschema for the port's value. SEE https://json-schema.org", ) - - class Config: - extra = Extra.ignore - schema_extra: ClassVar[dict[str, Any]] = { + model_config = ConfigDict( + extra="ignore", + json_schema_extra={ "example": { "key": "input_2", "kind": "input", @@ -137,4 +136,5 @@ class Config: "maximum": 5, }, } - } + }, + ) diff --git a/services/api-server/src/simcore_service_api_server/models/schemas/studies.py b/services/api-server/src/simcore_service_api_server/models/schemas/studies.py index 96c63ee7910..806ec309017 100644 --- a/services/api-server/src/simcore_service_api_server/models/schemas/studies.py +++ b/services/api-server/src/simcore_service_api_server/models/schemas/studies.py @@ -1,15 +1,17 @@ -from typing import TypeAlias +from typing import Annotated, TypeAlias from models_library import projects, projects_nodes_io from models_library.utils import pydantic_tools_extension -from pydantic import AnyUrl, BaseModel, Field +from pydantic import AnyUrl, BaseModel, BeforeValidator, Field, TypeAdapter from .. import api_resources from . import solvers StudyID: TypeAlias = projects.ProjectID NodeName: TypeAlias = str -DownloadLink: TypeAlias = AnyUrl +DownloadLink: TypeAlias = Annotated[ + str, BeforeValidator(lambda x: str(TypeAdapter(AnyUrl).validate_python(x))) +] class Study(BaseModel): diff --git a/services/api-server/src/simcore_service_api_server/services/catalog.py b/services/api-server/src/simcore_service_api_server/services/catalog.py index 56a7d648790..758fe44792a 100644 --- a/services/api-server/src/simcore_service_api_server/services/catalog.py +++ b/services/api-server/src/simcore_service_api_server/services/catalog.py @@ -9,7 +9,7 @@ from fastapi import FastAPI, status from models_library.emails import LowerCaseEmailStr from models_library.services import ServiceMetaDataPublished, ServiceType -from pydantic import Extra, ValidationError, parse_obj_as, parse_raw_as +from pydantic import ConfigDict, TypeAdapter, ValidationError from settings_library.catalog import CatalogSettings from simcore_service_api_server.exceptions.backend_errors import ( ListSolversOrStudiesError, @@ -43,9 +43,7 @@ class TruncatedCatalogServiceOut(ServiceMetaDataPublished): """ owner: LowerCaseEmailStr | None - - class Config: - extra = Extra.ignore + model_config = ConfigDict(extra="ignore") # Converters def to_solver(self) -> Solver: @@ -70,6 +68,17 @@ def to_solver(self) -> Solver: _exception_mapper = partial(service_exception_mapper, "Catalog") +_TRUNCATED_CATALOG_SERVICE_OUT_ADAPTER: TypeAdapter[ + TruncatedCatalogServiceOut +] = TypeAdapter(TruncatedCatalogServiceOut) +_LIST_OF_TRUNCATED_CATALOG_SERVICE_OUT_ADAPTER: TypeAdapter[ + list[TruncatedCatalogServiceOut] +] = TypeAdapter(list[TruncatedCatalogServiceOut]) + + +def _parse_response(type_adapter: TypeAdapter, response): + return type_adapter.validate_json(response.text) + @dataclass class CatalogApi(BaseServiceClientApi): @@ -99,7 +108,10 @@ async def list_solvers( services: list[ TruncatedCatalogServiceOut ] = await asyncio.get_event_loop().run_in_executor( - None, parse_raw_as, list[TruncatedCatalogServiceOut], response.text + None, + _parse_response, + _LIST_OF_TRUNCATED_CATALOG_SERVICE_OUT_ADAPTER, + response.text, ) solvers = [] for service in services: @@ -115,7 +127,7 @@ async def list_solvers( # invalid items instead of returning error _logger.warning( "Skipping invalid service returned by catalog '%s': %s", - service.json(), + service.model_dump_json(), err, ) return solvers @@ -140,7 +152,7 @@ async def get_service( service: ( TruncatedCatalogServiceOut ) = await asyncio.get_event_loop().run_in_executor( - None, parse_raw_as, TruncatedCatalogServiceOut, response.text + None, _parse_response, _TRUNCATED_CATALOG_SERVICE_OUT_ADAPTER, response.text ) assert ( # nosec service.service_type == ServiceType.COMPUTATIONAL @@ -167,7 +179,7 @@ async def get_service_ports( response.raise_for_status() - return parse_obj_as(list[SolverPort], response.json()) + return TypeAdapter(list[SolverPort]).validate_python(response.json()) async def list_latest_releases( self, *, user_id: int, product_name: str diff --git a/services/api-server/src/simcore_service_api_server/services/director_v2.py b/services/api-server/src/simcore_service_api_server/services/director_v2.py index ff31490b072..8d79ad66d75 100644 --- a/services/api-server/src/simcore_service_api_server/services/director_v2.py +++ b/services/api-server/src/simcore_service_api_server/services/director_v2.py @@ -1,6 +1,5 @@ import logging from functools import partial -from typing import Any, ClassVar from uuid import UUID from fastapi import FastAPI @@ -8,7 +7,15 @@ from models_library.projects_nodes_io import NodeID from models_library.projects_pipeline import ComputationTask from models_library.projects_state import RunningState -from pydantic import AnyHttpUrl, AnyUrl, BaseModel, Field, PositiveInt, parse_raw_as +from pydantic import ( + AnyHttpUrl, + AnyUrl, + BaseModel, + ConfigDict, + Field, + PositiveInt, + TypeAdapter, +) from simcore_service_api_server.exceptions.backend_errors import ( JobNotFoundError, LogFileNotFoundError, @@ -40,18 +47,19 @@ class ComputationTaskGet(ComputationTask): def guess_progress(self) -> PercentageInt: # guess progress based on self.state if self.state in [RunningState.SUCCESS, RunningState.FAILED]: - return PercentageInt(100) - return PercentageInt(0) + return 100 + return 0 - class Config: - schema_extra: ClassVar[dict[str, Any]] = { + model_config = ConfigDict( + json_schema_extra={ "examples": [ { - **ComputationTask.Config.schema_extra["examples"][0], + **ComputationTask.model_config["json_schema_extra"]["examples"][0], # type: ignore "url": "https://link-to-stop-computation", } ] } + ) class TaskLogFileGet(BaseModel): @@ -179,7 +187,9 @@ async def get_computation_logs( response.raise_for_status() log_links: list[LogLink] = [] - for r in parse_raw_as(list[TaskLogFileGet], response.text or "[]"): + for r in TypeAdapter(list[TaskLogFileGet]).validate_python( + response.text or "[]" + ): if r.download_link: log_links.append( LogLink(node_name=f"{r.task_id}", download_link=r.download_link) diff --git a/services/api-server/src/simcore_service_api_server/services/solver_job_models_converters.py b/services/api-server/src/simcore_service_api_server/services/solver_job_models_converters.py index 137463e1263..a8988037f65 100644 --- a/services/api-server/src/simcore_service_api_server/services/solver_job_models_converters.py +++ b/services/api-server/src/simcore_service_api_server/services/solver_job_models_converters.py @@ -6,14 +6,14 @@ import urllib.parse import uuid from collections.abc import Callable -from datetime import datetime +from datetime import datetime, timezone from functools import lru_cache import arrow from models_library.api_schemas_webserver.projects import ProjectCreateNew, ProjectGet from models_library.basic_types import KeyIDStr from models_library.projects_nodes import InputID -from pydantic import parse_obj_as +from pydantic import TypeAdapter from ..models.basic_types import VersionStr from ..models.domain.projects import InputTypes, Node, SimCoreFileLink, StudyUI @@ -45,7 +45,7 @@ def format_datetime(snapshot: datetime) -> str: def now_str() -> str: # NOTE: backend MUST use UTC - return format_datetime(datetime.utcnow()) + return format_datetime(datetime.now(timezone.utc)) # CONVERTERS -------------- @@ -62,14 +62,14 @@ def create_node_inputs_from_job_inputs( node_inputs: dict[InputID, InputTypes] = {} for name, value in inputs.values.items(): - assert parse_obj_as(ArgumentTypes, value) == value # type: ignore # nosec - assert parse_obj_as(KeyIDStr, name) is not None # nosec + assert TypeAdapter(ArgumentTypes).validate_python(value) == value # type: ignore # nosec + assert TypeAdapter(KeyIDStr).validate_python(name) is not None # nosec if isinstance(value, File): # FIXME: ensure this aligns with storage policy node_inputs[KeyIDStr(name)] = SimCoreFileLink( store=0, - path=f"api/{value.id}/{value.filename}", # type: ignore[arg-type] + path=f"api/{value.id}/{value.filename}", label=value.filename, eTag=value.e_tag, ) @@ -88,10 +88,8 @@ def create_job_inputs_from_node_inputs(inputs: dict[InputID, InputTypes]) -> Job """ input_values: dict[str, ArgumentTypes] = {} for name, value in inputs.items(): - assert parse_obj_as(InputID, name) == name # nosec - assert ( # nosec - parse_obj_as(InputTypes, value) == value # type: ignore[arg-type] - ) + assert TypeAdapter(InputID).validate_python(name) == name # nosec + assert TypeAdapter(InputTypes).validate_python(value) == value # nosec if isinstance(value, SimCoreFileLink): # FIXME: ensure this aligns with storage policy @@ -141,15 +139,15 @@ def create_new_project_for_job( ) solver_service = Node( - key=solver.id, # type: ignore[arg-type] - version=solver.version, # type: ignore[arg-type] + key=solver.id, + version=solver.version, label=solver.title, inputs=solver_inputs, inputsUnits={}, ) # Ensembles project model so it can be used as input for create_project - job_info = job.json( + job_info = job.model_dump_json( include={"id", "name", "inputs_checksum", "created_at"}, indent=2 ) @@ -158,7 +156,7 @@ def create_new_project_for_job( name=job.name, # NOTE: this IS an identifier as well. MUST NOT be changed in the case of project APIs! description=f"Study associated to solver job:\n{job_info}", thumbnail="https://via.placeholder.com/170x120.png", # type: ignore[arg-type] - workbench={solver_id: solver_service}, # type: ignore[dict-item] + workbench={solver_id: solver_service}, ui=StudyUI( workbench={ f"{solver_id}": { # type: ignore[dict-item] @@ -208,10 +206,10 @@ def create_job_from_project( job = Job( id=job_id, - name=project.name, # type: ignore[arg-type] + name=project.name, inputs_checksum=job_inputs.compute_checksum(), created_at=project.creation_date, # type: ignore[arg-type] - runner_name=solver_name, # type: ignore + runner_name=solver_name, url=url_for( "get_job", solver_key=solver_key, @@ -231,7 +229,9 @@ def create_job_from_project( ), ) - assert all(getattr(job, f) for f in job.__fields__ if f.endswith("url")) # nosec + assert all( + getattr(job, f) for f in job.model_fields.keys() if f.endswith("url") + ) # nosec return job diff --git a/services/api-server/src/simcore_service_api_server/services/storage.py b/services/api-server/src/simcore_service_api_server/services/storage.py index 13920d8a931..442520c1582 100644 --- a/services/api-server/src/simcore_service_api_server/services/storage.py +++ b/services/api-server/src/simcore_service_api_server/services/storage.py @@ -72,9 +72,11 @@ async def list_files( ) response.raise_for_status() - files_metadata = Envelope[FileMetaDataArray].parse_raw(response.text).data + files_metadata = ( + Envelope[FileMetaDataArray].model_validate_json(response.text).data + ) files: list[StorageFileMetaData] = ( - [] if files_metadata is None else files_metadata.__root__ + [] if files_metadata is None else files_metadata.root ) return files @@ -107,9 +109,11 @@ async def search_owned_files( ) response.raise_for_status() - files_metadata = Envelope[FileMetaDataArray].parse_raw(response.text).data + files_metadata = ( + Envelope[FileMetaDataArray].model_validate_json(response.text).data + ) files: list[StorageFileMetaData] = ( - [] if files_metadata is None else files_metadata.__root__ + [] if files_metadata is None else files_metadata.root ) assert len(files) <= limit if limit else True # nosec return files @@ -127,7 +131,7 @@ async def get_download_link( response.raise_for_status() presigned_link: PresignedLink | None = ( - Envelope[PresignedLink].parse_raw(response.text).data + Envelope[PresignedLink].model_validate_json(response.text).data ) assert presigned_link is not None link: AnyUrl = presigned_link.link @@ -154,7 +158,7 @@ async def get_upload_links( ) response.raise_for_status() - enveloped_data = Envelope[FileUploadSchema].parse_raw(response.text) + enveloped_data = Envelope[FileUploadSchema].model_validate_json(response.text) assert enveloped_data.data # nosec return enveloped_data.data @@ -200,7 +204,9 @@ async def create_soft_link( ) response.raise_for_status() - stored_file_meta = Envelope[StorageFileMetaData].parse_raw(response.text).data + stored_file_meta = ( + Envelope[StorageFileMetaData].model_validate_json(response.text).data + ) assert stored_file_meta is not None file_meta: File = to_file_api_model(stored_file_meta) return file_meta diff --git a/services/api-server/src/simcore_service_api_server/services/webserver.py b/services/api-server/src/simcore_service_api_server/services/webserver.py index 0d265248dc2..a6e71677950 100644 --- a/services/api-server/src/simcore_service_api_server/services/webserver.py +++ b/services/api-server/src/simcore_service_api_server/services/webserver.py @@ -282,7 +282,7 @@ async def create_project( ) response.raise_for_status() result = await self._wait_for_long_running_task_results(response) - return ProjectGet.parse_obj(result) + return ProjectGet.model_validate(result) @_exception_mapper(_JOB_STATUS_MAP) async def clone_project( @@ -307,7 +307,7 @@ async def clone_project( ) response.raise_for_status() result = await self._wait_for_long_running_task_results(response) - return ProjectGet.parse_obj(result) + return ProjectGet.model_validate(result) @_exception_mapper(_JOB_STATUS_MAP) async def get_project(self, *, project_id: UUID) -> ProjectGet: diff --git a/services/api-server/tests/unit/_with_db/conftest.py b/services/api-server/tests/unit/_with_db/conftest.py index 57450561ce4..89cf5f22344 100644 --- a/services/api-server/tests/unit/_with_db/conftest.py +++ b/services/api-server/tests/unit/_with_db/conftest.py @@ -161,7 +161,7 @@ def app_environment( assert "API_SERVER_POSTGRES" not in envs # Should be sufficient to create settings - print(PostgresSettings.create_from_envs().json(indent=1)) + print(PostgresSettings.create_from_envs().model_dump_json(indent=1)) return envs diff --git a/services/api-server/tests/unit/_with_db/test_api_user.py b/services/api-server/tests/unit/_with_db/test_api_user.py index 87d2de26c64..0a42177867b 100644 --- a/services/api-server/tests/unit/_with_db/test_api_user.py +++ b/services/api-server/tests/unit/_with_db/test_api_user.py @@ -32,7 +32,7 @@ def mocked_webserver_service_api(app: FastAPI): ) as respx_mock: # NOTE: webserver-api uses the same schema as api-server! # in-memory fake data - me = deepcopy(Profile.Config.schema_extra["example"]) + me = deepcopy(Profile.model_config["json_schema_extra"]["example"]) def _get_me(request): return httpx.Response(status.HTTP_200_OK, json={"data": me}) @@ -86,6 +86,6 @@ async def test_update_profile( ) assert resp.status_code == status.HTTP_200_OK, resp.text - profile = Profile.parse_obj(resp.json()) + profile = Profile.model_validate(resp.json()) assert profile.first_name == "Oliver" assert profile.last_name == "Heaviside" diff --git a/services/api-server/tests/unit/api_solvers/conftest.py b/services/api-server/tests/unit/api_solvers/conftest.py index a7b813776da..ec8bf7d5630 100644 --- a/services/api-server/tests/unit/api_solvers/conftest.py +++ b/services/api-server/tests/unit/api_solvers/conftest.py @@ -96,8 +96,8 @@ async def mocked_directorv2_service( stop_time: Final[datetime] = datetime.now() + timedelta(seconds=5) def _get_computation(request: httpx.Request, **kwargs) -> httpx.Response: - task = ComputationTaskGet.parse_obj( - ComputationTaskGet.Config.schema_extra["examples"][0] + task = ComputationTaskGet.model_validate( + ComputationTaskGet.model_config["json_schema_extra"]["examples"][0] ) if datetime.now() > stop_time: task.state = RunningState.SUCCESS diff --git a/services/api-server/tests/unit/api_solvers/test_api_routers_solvers_jobs.py b/services/api-server/tests/unit/api_solvers/test_api_routers_solvers_jobs.py index ed3ae76cfbd..4adc0e851ff 100644 --- a/services/api-server/tests/unit/api_solvers/test_api_routers_solvers_jobs.py +++ b/services/api-server/tests/unit/api_solvers/test_api_routers_solvers_jobs.py @@ -247,7 +247,7 @@ async def test_run_solver_job( ).respond( status.HTTP_201_CREATED, json=jsonable_encoder( - ComputationTaskGet.parse_obj( + ComputationTaskGet.model_validate( { "id": project_id, "state": "UNKNOWN", @@ -314,7 +314,7 @@ async def test_run_solver_job( example = next( e - for e in ServiceMetaDataPublished.Config.schema_extra["examples"] + for e in ServiceMetaDataPublished.model_config["json_schema_extra"]["examples"] if "boot-options" in e ) @@ -358,7 +358,7 @@ async def test_run_solver_job( assert mocked_webserver_service_api["get_task_status"].called assert mocked_webserver_service_api["get_task_result"].called - job = Job.parse_obj(resp.json()) + job = Job.model_validate(resp.json()) # Start Job resp = await client.post( @@ -369,5 +369,5 @@ async def test_run_solver_job( assert resp.status_code == status.HTTP_202_ACCEPTED assert mocked_directorv2_service_api["inspect_computation"].called - job_status = JobStatus.parse_obj(resp.json()) + job_status = JobStatus.model_validate(resp.json()) assert job_status.progress == 0.0 diff --git a/services/api-server/tests/unit/api_solvers/test_api_routers_solvers_jobs_delete.py b/services/api-server/tests/unit/api_solvers/test_api_routers_solvers_jobs_delete.py index 000a586836a..bdb3886ebec 100644 --- a/services/api-server/tests/unit/api_solvers/test_api_routers_solvers_jobs_delete.py +++ b/services/api-server/tests/unit/api_solvers/test_api_routers_solvers_jobs_delete.py @@ -11,7 +11,7 @@ import pytest from faker import Faker from models_library.basic_regex import UUID_RE_BASE -from pydantic import parse_file_as +from pydantic import TypeAdapter from pytest_simcore.helpers.httpx_calls_capture_models import HttpApiCallCaptureModel from respx import MockRouter from servicelib.common_headers import ( @@ -42,7 +42,7 @@ def mocked_backend_services_apis_for_delete_non_existing_project( template = environment.get_template(mock_name) def _response(request: httpx.Request, project_id: str): - capture = HttpApiCallCaptureModel.parse_raw( + capture = HttpApiCallCaptureModel.model_validate_json( template.render(project_id=project_id) ) return httpx.Response( @@ -91,9 +91,8 @@ def mocked_backend_services_apis_for_create_and_delete_solver_job( mock_name = "on_create_job.json" # fixture - captures = parse_file_as( - list[HttpApiCallCaptureModel], - project_tests_dir / "mocks" / mock_name, + captures = TypeAdapter(list[HttpApiCallCaptureModel]).validate_json( + Path(project_tests_dir / "mocks" / mock_name).read_text() ) capture = captures[0] @@ -137,10 +136,10 @@ async def test_create_and_delete_solver_job( "x": 3.14, "n": 42, } - ).dict(), + ).model_dump(), ) assert resp.status_code == status.HTTP_201_CREATED - job = Job.parse_obj(resp.json()) + job = Job.model_validate(resp.json()) # Delete Job after creation resp = await client.delete( @@ -224,7 +223,7 @@ def create_project_side_effect(request: httpx.Request): "x": 3.14, "n": 42, } - ).dict(), + ).model_dump(), ) assert resp.status_code == status.HTTP_201_CREATED - job = Job.parse_obj(resp.json()) + job = Job.model_validate(resp.json()) diff --git a/services/api-server/tests/unit/api_solvers/test_api_routers_solvers_jobs_logs.py b/services/api-server/tests/unit/api_solvers/test_api_routers_solvers_jobs_logs.py index a30404606d7..eb821e46d01 100644 --- a/services/api-server/tests/unit/api_solvers/test_api_routers_solvers_jobs_logs.py +++ b/services/api-server/tests/unit/api_solvers/test_api_routers_solvers_jobs_logs.py @@ -76,7 +76,7 @@ def fake_project_for_streaming( assert isinstance(response_body := GET_PROJECT.response_body, dict) assert (data := response_body.get("data")) is not None - fake_project = ProjectGet.parse_obj(data) + fake_project = ProjectGet.model_validate(data) fake_project.workbench = {faker.uuid4(): faker.uuid4()} mocker.patch( "simcore_service_api_server.api.dependencies.webserver.AuthSession.get_project", @@ -113,8 +113,8 @@ async def test_log_streaming( response.raise_for_status() if not disconnect: async for line in response.aiter_lines(): - job_log = JobLog.parse_raw(line) - pprint(job_log.json()) + job_log = JobLog.model_validate_json(line) + pprint(job_log.model_dump()) collected_messages += job_log.messages assert fake_log_distributor.deregister_is_called @@ -160,12 +160,12 @@ async def test_logstreaming_job_not_found_exception( response.raise_for_status() async for line in response.aiter_lines(): try: - job_log = JobLog.parse_raw(line) - pprint(job_log.json()) + job_log = JobLog.model_validate_json(line) + pprint(job_log.model_dump()) except ValidationError: - error = ErrorGet.parse_raw(line) + error = ErrorGet.model_validate_json(line) _received_error = True - print(error.json()) + print(error.model_dump()) assert fake_log_distributor.deregister_is_called assert _received_error diff --git a/services/api-server/tests/unit/api_solvers/test_api_routers_solvers_jobs_metadata.py b/services/api-server/tests/unit/api_solvers/test_api_routers_solvers_jobs_metadata.py index ccf9b40b565..6b62c89b6b8 100644 --- a/services/api-server/tests/unit/api_solvers/test_api_routers_solvers_jobs_metadata.py +++ b/services/api-server/tests/unit/api_solvers/test_api_routers_solvers_jobs_metadata.py @@ -10,7 +10,7 @@ import pytest from faker import Faker from models_library.basic_regex import UUID_RE_BASE -from pydantic import parse_file_as +from pydantic import TypeAdapter from pytest_simcore.helpers.httpx_calls_capture_models import HttpApiCallCaptureModel from respx import MockRouter from simcore_service_api_server._meta import API_VTAG @@ -45,8 +45,8 @@ def mocked_backend( captures = { c.name: c - for c in parse_file_as( - list[HttpApiCallCaptureModel], project_tests_dir / "mocks" / mock_name + for c in TypeAdapter(list[HttpApiCallCaptureModel]).validate_json( + Path(project_tests_dir / "mocks" / mock_name).read_text() ) } @@ -112,10 +112,10 @@ async def test_get_and_update_job_metadata( "title": "Temperature", "enabled": True, } - ).dict(), + ).model_dump(), ) assert resp.status_code == status.HTTP_201_CREATED - job = Job.parse_obj(resp.json()) + job = Job.model_validate(resp.json()) # Get metadata resp = await client.get( @@ -123,7 +123,7 @@ async def test_get_and_update_job_metadata( auth=auth, ) assert resp.status_code == status.HTTP_200_OK - job_meta = JobMetadata.parse_obj(resp.json()) + job_meta = JobMetadata.model_validate(resp.json()) assert job_meta.metadata == {} @@ -132,11 +132,11 @@ async def test_get_and_update_job_metadata( resp = await client.patch( f"/{API_VTAG}/solvers/{solver_key}/releases/{solver_version}/jobs/{job.id}/metadata", auth=auth, - json=JobMetadataUpdate(metadata=my_metadata).dict(), + json=JobMetadataUpdate(metadata=my_metadata).model_dump(), ) assert resp.status_code == status.HTTP_200_OK - job_meta = JobMetadata.parse_obj(resp.json()) + job_meta = JobMetadata.model_validate(resp.json()) assert job_meta.metadata == my_metadata # Get metadata after update @@ -145,7 +145,7 @@ async def test_get_and_update_job_metadata( auth=auth, ) assert resp.status_code == status.HTTP_200_OK - job_meta = JobMetadata.parse_obj(resp.json()) + job_meta = JobMetadata.model_validate(resp.json()) assert job_meta.metadata == my_metadata diff --git a/services/api-server/tests/unit/api_solvers/test_api_routers_solvers_jobs_read.py b/services/api-server/tests/unit/api_solvers/test_api_routers_solvers_jobs_read.py index 1dbf8b3fa0f..b51c580eb82 100644 --- a/services/api-server/tests/unit/api_solvers/test_api_routers_solvers_jobs_read.py +++ b/services/api-server/tests/unit/api_solvers/test_api_routers_solvers_jobs_read.py @@ -7,7 +7,7 @@ import httpx import pytest -from pydantic import parse_file_as, parse_obj_as +from pydantic import TypeAdapter from pytest_simcore.helpers.httpx_calls_capture_models import HttpApiCallCaptureModel from respx import MockRouter from simcore_service_api_server._meta import API_VTAG @@ -28,9 +28,8 @@ def mocked_backend( project_tests_dir: Path, ) -> MockBackendRouters: mock_name = "on_list_jobs.json" - captures = parse_file_as( - list[HttpApiCallCaptureModel], - project_tests_dir / "mocks" / mock_name, + captures = TypeAdapter(list[HttpApiCallCaptureModel]).validate_json( + Path(project_tests_dir / "mocks" / mock_name).read_text() ) capture = captures[0] @@ -78,7 +77,7 @@ async def test_list_solver_jobs( f"/{API_VTAG}/solvers/{solver_key}/releases/{solver_version}/jobs", auth=auth ) assert resp.status_code == status.HTTP_200_OK - jobs = parse_obj_as(list[Job], resp.json()) + jobs = TypeAdapter(list[Job]).validate_python(resp.json()) # list jobs (w/ pagination) resp = await client.get( @@ -88,7 +87,7 @@ async def test_list_solver_jobs( ) assert resp.status_code == status.HTTP_200_OK - jobs_page = parse_obj_as(Page[Job], resp.json()) + jobs_page = TypeAdapter(Page[Job]).validate_python(resp.json()) assert jobs_page.items == jobs diff --git a/services/api-server/tests/unit/api_studies/test_api_routers_studies_jobs_metadata.py b/services/api-server/tests/unit/api_studies/test_api_routers_studies_jobs_metadata.py index 098718c3738..d1fae307589 100644 --- a/services/api-server/tests/unit/api_studies/test_api_routers_studies_jobs_metadata.py +++ b/services/api-server/tests/unit/api_studies/test_api_routers_studies_jobs_metadata.py @@ -12,7 +12,7 @@ import httpx import pytest from fastapi.encoders import jsonable_encoder -from pydantic import parse_file_as +from pydantic import TypeAdapter from pytest_simcore.helpers.httpx_calls_capture_models import HttpApiCallCaptureModel from pytest_simcore.helpers.httpx_calls_capture_parameters import PathDescription from respx import MockRouter @@ -38,9 +38,12 @@ def mocked_backend( # load captures = { c.name: c - for c in parse_file_as( - list[HttpApiCallCaptureModel], - project_tests_dir / "mocks" / "test_get_and_update_study_job_metadata.json", + for c in TypeAdapter(list[HttpApiCallCaptureModel]).validate_json( + Path( + project_tests_dir + / "mocks" + / "test_get_and_update_study_job_metadata.json" + ).read_text(), ) } diff --git a/services/api-server/tests/unit/api_studies/test_api_routes_studies.py b/services/api-server/tests/unit/api_studies/test_api_routes_studies.py index 1893e6e068e..d5369bb0314 100644 --- a/services/api-server/tests/unit/api_studies/test_api_routes_studies.py +++ b/services/api-server/tests/unit/api_studies/test_api_routes_studies.py @@ -12,7 +12,7 @@ import pytest from faker import Faker from fastapi import status -from pydantic import parse_file_as, parse_obj_as +from pydantic import TypeAdapter from pytest_simcore.helpers.httpx_calls_capture_models import HttpApiCallCaptureModel from respx import MockRouter from servicelib.common_headers import ( @@ -40,8 +40,8 @@ def mocked_backend( captures = { c.name: c - for c in parse_file_as( - list[HttpApiCallCaptureModel], project_tests_dir / "mocks" / mock_name + for c in TypeAdapter(list[HttpApiCallCaptureModel]).validate_json( + Path(project_tests_dir / "mocks" / mock_name).read_text() ) } @@ -84,7 +84,7 @@ async def test_studies_read_workflow( resp = await client.get(f"/{API_VTAG}/studies", auth=auth) assert resp.status_code == status.HTTP_200_OK - studies = parse_obj_as(list[Study], resp.json()["items"]) + studies = TypeAdapter(list[Study]).validate_python(resp.json()["items"]) assert len(studies) == 1 assert studies[0].uid == study_id @@ -96,28 +96,28 @@ async def test_studies_read_workflow( resp = await client.get(f"/{API_VTAG}/studies/{study_id}", auth=auth) assert resp.status_code == status.HTTP_200_OK - study = parse_obj_as(Study, resp.json()) + study = TypeAdapter(Study).validate_python(resp.json()) assert study.uid == study_id # get ports resp = await client.get(f"/{API_VTAG}/studies/{study_id}/ports", auth=auth) assert resp.status_code == status.HTTP_200_OK - ports = parse_obj_as(list[StudyPort], resp.json()["items"]) + ports = TypeAdapter(list[StudyPort]).validate_python(resp.json()["items"]) assert len(ports) == (resp.json()["total"]) # get_study with non-existing uuid inexistent_study_id = StudyID("15531b1a-2565-11ee-ab43-02420a000031") resp = await client.get(f"/{API_VTAG}/studies/{inexistent_study_id}", auth=auth) assert resp.status_code == status.HTTP_404_NOT_FOUND - error = parse_obj_as(ErrorGet, resp.json()) + error = TypeAdapter(ErrorGet).validate_python(resp.json()) assert f"{inexistent_study_id}" in error.errors[0] resp = await client.get( f"/{API_VTAG}/studies/{inexistent_study_id}/ports", auth=auth ) assert resp.status_code == status.HTTP_404_NOT_FOUND - error = parse_obj_as(ErrorGet, resp.json()) + error = TypeAdapter(ErrorGet).validate_python(resp.json()) assert f"{inexistent_study_id}" in error.errors[0] diff --git a/services/api-server/tests/unit/api_studies/test_api_routes_studies_jobs.py b/services/api-server/tests/unit/api_studies/test_api_routes_studies_jobs.py index 61d91fa9d94..ece3fcd1f57 100644 --- a/services/api-server/tests/unit/api_studies/test_api_routes_studies_jobs.py +++ b/services/api-server/tests/unit/api_studies/test_api_routes_studies_jobs.py @@ -358,7 +358,7 @@ async def test_get_job_logs( f"{API_VTAG}/studies/{_study_id}/jobs/{_job_id}/outputs/log-links", auth=auth ) assert response.status_code == status.HTTP_200_OK - _ = JobLogsMap.parse_obj(response.json()) + _ = JobLogsMap.model_validate(response.json()) async def test_get_study_outputs( @@ -394,17 +394,17 @@ async def test_get_study_outputs( }, ) assert response.status_code == status.HTTP_200_OK - _job = Job.parse_obj(response.json()) + _job = Job.model_validate(response.json()) _job_id = _job.id response = await client.post( f"/{API_VTAG}/studies/{_study_id}/jobs/{_job_id}:start", auth=auth ) assert response.status_code == status.HTTP_202_ACCEPTED - _ = JobStatus.parse_obj(response.json()) + _ = JobStatus.model_validate(response.json()) response = await client.post( f"/{API_VTAG}/studies/{_study_id}/jobs/{_job_id}/outputs", auth=auth ) assert response.status_code == status.HTTP_200_OK - _ = JobOutputs.parse_obj(response.json()) + _ = JobOutputs.model_validate(response.json()) diff --git a/services/api-server/tests/unit/captures/test__mocks_captures.py b/services/api-server/tests/unit/captures/test__mocks_captures.py index 4c04cca224d..81297e1bbe5 100644 --- a/services/api-server/tests/unit/captures/test__mocks_captures.py +++ b/services/api-server/tests/unit/captures/test__mocks_captures.py @@ -14,7 +14,7 @@ import jsonref import pytest import respx -from pydantic import parse_file_as +from pydantic import TypeAdapter from pytest_simcore.helpers.httpx_calls_capture_models import HttpApiCallCaptureModel from pytest_simcore.helpers.httpx_calls_capture_openapi import _determine_path from pytest_simcore.helpers.httpx_calls_capture_parameters import ( @@ -86,9 +86,9 @@ def test_openapion_capture_mock( assert mock_capture_path.exists() assert mock_capture_path.name.endswith(".json") - captures = parse_file_as( - list[HttpApiCallCaptureModel] | HttpApiCallCaptureModel, mock_capture_path - ) + captures = TypeAdapter( + list[HttpApiCallCaptureModel] | HttpApiCallCaptureModel + ).validate_json(mock_capture_path.read_text()) if not isinstance(captures, list): captures = [ diff --git a/services/api-server/tests/unit/conftest.py b/services/api-server/tests/unit/conftest.py index e8324bcc0b7..99d248783c2 100644 --- a/services/api-server/tests/unit/conftest.py +++ b/services/api-server/tests/unit/conftest.py @@ -511,7 +511,7 @@ def create_project_task(self, request: httpx.Request): if from_study := query.get("from_study"): return self.clone_project_task(request=request, project_id=from_study) project_create = json.loads(request.content) - project_get = ProjectGet.parse_obj( + project_get = ProjectGet.model_validate( { "creationDate": "2018-07-01T11:13:43Z", "lastChangeDate": "2018-07-01T11:13:43Z", @@ -525,7 +525,7 @@ def create_project_task(self, request: httpx.Request): def clone_project_task(self, request: httpx.Request, *, project_id: str): assert GET_PROJECT.response_body - project_get = ProjectGet.parse_obj( + project_get = ProjectGet.model_validate( { "creationDate": "2018-07-01T11:13:43Z", "lastChangeDate": "2018-07-01T11:13:43Z", diff --git a/services/api-server/tests/unit/test__fastapi.py b/services/api-server/tests/unit/test__fastapi.py index 6cf2e6f13c9..4eaddee4437 100644 --- a/services/api-server/tests/unit/test__fastapi.py +++ b/services/api-server/tests/unit/test__fastapi.py @@ -122,8 +122,8 @@ def test_fastapi_route_name_parsing(client: TestClient, app: FastAPI, faker: Fak # Ensures ':' is allowed in routes # SEE https://github.com/encode/starlette/pull/1657 - solver_key = Solver.Config.schema_extra["example"]["id"] - version = Solver.Config.schema_extra["example"]["version"] + solver_key = Solver.model_config["json_schema_extra"]["example"]["id"] + version = Solver.model_config["json_schema_extra"]["example"]["version"] job_id = faker.uuid4() # Checks whether parse correctly ":action" suffix diff --git a/services/api-server/tests/unit/test_api_files.py b/services/api-server/tests/unit/test_api_files.py index 4d45e0e5528..8c308bfa2f2 100644 --- a/services/api-server/tests/unit/test_api_files.py +++ b/services/api-server/tests/unit/test_api_files.py @@ -251,7 +251,9 @@ async def test_get_upload_links( payload: dict[str, str] = response.json() assert response.status_code == status.HTTP_200_OK - client_upload_schema: ClientFileUploadData = ClientFileUploadData.parse_obj(payload) + client_upload_schema: ClientFileUploadData = ClientFileUploadData.model_validate( + payload + ) if follow_up_request == "complete": body = { diff --git a/services/api-server/tests/unit/test_api_solver_jobs.py b/services/api-server/tests/unit/test_api_solver_jobs.py index 524adc7300c..0872b25b873 100644 --- a/services/api-server/tests/unit/test_api_solver_jobs.py +++ b/services/api-server/tests/unit/test_api_solver_jobs.py @@ -17,7 +17,7 @@ from models_library.api_schemas_webserver.resource_usage import PricingUnitGet from models_library.api_schemas_webserver.wallets import WalletGetWithAvailableCredits from models_library.generics import Envelope -from pydantic import parse_obj_as +from pydantic import TypeAdapter from pytest_simcore.helpers.httpx_calls_capture_models import ( CreateRespxMockCallback, HttpApiCallCaptureModel, @@ -182,7 +182,7 @@ def _get_pricing_unit_side_effect( ) if capture_file == "get_job_pricing_unit_success.json": assert response.status_code == status.HTTP_200_OK - _ = parse_obj_as(PricingUnitGet, response.json()) + _ = TypeAdapter(PricingUnitGet).validate_python(response.json()) elif capture_file == "get_job_pricing_unit_invalid_job.json": assert response.status_code == status.HTTP_404_NOT_FOUND elif capture_file == "get_job_pricing_unit_invalid_solver.json": @@ -342,7 +342,7 @@ async def test_start_solver_job_conflict( ) assert response.status_code == status.HTTP_200_OK - job_status = JobStatus.parse_obj(response.json()) + job_status = JobStatus.model_validate(response.json()) assert f"{job_status.job_id}" == _job_id @@ -364,7 +364,7 @@ def _stop_job_side_effect( path_params: dict[str, Any], capture: HttpApiCallCaptureModel, ) -> Any: - task = ComputationTaskGet.parse_obj(capture.response_body) + task = ComputationTaskGet.model_validate(capture.response_body) task.id = UUID(_job_id) return jsonable_encoder(task) @@ -384,7 +384,7 @@ def _stop_job_side_effect( ) assert response.status_code == status.HTTP_200_OK - status_ = JobStatus.parse_obj(response.json()) + status_ = JobStatus.model_validate(response.json()) assert status_.job_id == UUID(_job_id) @@ -416,7 +416,7 @@ def _wallet_side_effect( path_params: dict[str, Any], capture: HttpApiCallCaptureModel, ): - wallet = parse_obj_as( + wallet = TypeAdapter( Envelope[WalletGetWithAvailableCredits], capture.response_body ).data assert wallet is not None diff --git a/services/api-server/tests/unit/test_credits.py b/services/api-server/tests/unit/test_credits.py index 8c2dfd7dd74..3630e218754 100644 --- a/services/api-server/tests/unit/test_credits.py +++ b/services/api-server/tests/unit/test_credits.py @@ -23,4 +23,4 @@ async def test_get_credits_price( response = await client.get(f"{API_VTAG}/credits/price", auth=auth) assert response.status_code == status.HTTP_200_OK - _ = GetCreditPrice.parse_obj(response.json()) + _ = GetCreditPrice.model_validate(response.json()) diff --git a/services/api-server/tests/unit/test_models.py b/services/api-server/tests/unit/test_models.py index 06ee47d86c4..b3e1f48a57a 100644 --- a/services/api-server/tests/unit/test_models.py +++ b/services/api-server/tests/unit/test_models.py @@ -21,7 +21,7 @@ def test_api_server_model_examples( model_cls: type[BaseModel], example_name: int, example_data: Any ): - assert model_cls.parse_obj( + assert model_cls.model_validate( example_data ), f"Failed {example_name} : {json.dumps(example_data)}" diff --git a/services/api-server/tests/unit/test_models_schemas_files.py b/services/api-server/tests/unit/test_models_schemas_files.py index ded5c379b58..e4852afd238 100644 --- a/services/api-server/tests/unit/test_models_schemas_files.py +++ b/services/api-server/tests/unit/test_models_schemas_files.py @@ -81,7 +81,7 @@ async def test_create_filemetadata_from_starlette_uploadfile( def test_convert_between_file_models(): storage_file_meta = StorageFileMetaData( - **StorageFileMetaData.Config.schema_extra["examples"][1] + **StorageFileMetaData.model_config["json_schema_extra"]["examples"][1] ) storage_file_meta.file_id = parse_obj_as( StorageFileID, f"api/{uuid4()}/extensionless" diff --git a/services/api-server/tests/unit/test_models_schemas_jobs.py b/services/api-server/tests/unit/test_models_schemas_jobs.py index afb1d6e1966..b8c646feaf2 100644 --- a/services/api-server/tests/unit/test_models_schemas_jobs.py +++ b/services/api-server/tests/unit/test_models_schemas_jobs.py @@ -37,8 +37,8 @@ def _deepcopy_and_shuffle(src): return deepcopy(src) shuffled_raw = _deepcopy_and_shuffle(raw) - inputs1 = JobInputs.parse_obj(raw) - inputs2 = JobInputs.parse_obj(shuffled_raw) + inputs1 = JobInputs.model_validate(raw) + inputs2 = JobInputs.model_validate(shuffled_raw) print(inputs1) print(inputs2) diff --git a/services/api-server/tests/unit/test_models_schemas_solvers.py b/services/api-server/tests/unit/test_models_schemas_solvers.py index a8dd693622a..dbdd148be0b 100644 --- a/services/api-server/tests/unit/test_models_schemas_solvers.py +++ b/services/api-server/tests/unit/test_models_schemas_solvers.py @@ -12,7 +12,7 @@ def test_solvers_sorting_by_name_and_version(faker: Faker): # SEE https://packaging.pypa.io/en/latest/version.html # have a solver - one_solver = Solver(**Solver.Config.schema_extra["example"]) + one_solver = Solver(**Solver.model_config["json_schema_extra"]["example"]) assert isinstance(one_solver.pep404_version, Version) major, minor, micro = one_solver.pep404_version.release diff --git a/services/api-server/tests/unit/test_services_rabbitmq.py b/services/api-server/tests/unit/test_services_rabbitmq.py index ee68615c8f1..6f2f2ca546f 100644 --- a/services/api-server/tests/unit/test_services_rabbitmq.py +++ b/services/api-server/tests/unit/test_services_rabbitmq.py @@ -332,8 +332,8 @@ async def log_streamer_with_distributor( log_distributor: LogDistributor, ) -> AsyncIterable[LogStreamer]: def _get_computation(request: httpx.Request, **kwargs) -> httpx.Response: - task = ComputationTaskGet.parse_obj( - ComputationTaskGet.Config.schema_extra["examples"][0] + task = ComputationTaskGet.model_validate( + ComputationTaskGet.model_config["json_schema_extra"]["examples"][0] ) if computation_done(): task.state = RunningState.SUCCESS @@ -420,13 +420,13 @@ def routing_key(self) -> str: log_level=logging.INFO, ) with pytest.raises(ValidationError): - LoggerRabbitMessage.parse_obj(log_rabbit_message.dict()) + LoggerRabbitMessage.model_validate(log_rabbit_message.model_dump()) await produce_logs("expected", log_message=log_rabbit_message) ii: int = 0 async for log in log_streamer_with_distributor.log_generator(): - _ = JobLog.parse_raw(log) + _ = JobLog.model_validate_json(log) ii += 1 assert ii == 0 @@ -448,7 +448,9 @@ async def test_log_generator(mocker: MockFixture, faker: Faker): published_logs: list[str] = [] for _ in range(10): - job_log = JobLog.parse_obj(JobLog.Config.schema_extra["example"]) + job_log = JobLog.model_validate( + JobLog.model_config["json_schema_extra"]["example"] + ) msg = faker.text() published_logs.append(msg) job_log.messages = [msg] diff --git a/services/api-server/tests/unit/test_services_solver_job_models_converters.py b/services/api-server/tests/unit/test_services_solver_job_models_converters.py index 28f8be422f9..3141a3a9aee 100644 --- a/services/api-server/tests/unit/test_services_solver_job_models_converters.py +++ b/services/api-server/tests/unit/test_services_solver_job_models_converters.py @@ -6,7 +6,7 @@ from faker import Faker from models_library.projects import Project from models_library.projects_nodes import InputsDict, InputTypes, SimCoreFileLink -from pydantic import create_model, parse_obj_as +from pydantic import TypeAdapter, create_model from simcore_service_api_server.models.schemas.files import File from simcore_service_api_server.models.schemas.jobs import ArgumentTypes, Job, JobInputs from simcore_service_api_server.models.schemas.solvers import Solver @@ -20,7 +20,7 @@ def test_create_project_model_for_job(faker: Faker): - solver = Solver.parse_obj( + solver = Solver.model_validate( { "id": "simcore/services/comp/itis/sleeper", "version": "2.0.2", @@ -31,7 +31,7 @@ def test_create_project_model_for_job(faker: Faker): } ) - inputs = JobInputs.parse_obj( + inputs = JobInputs.model_validate( { "values": { "input_3": False, # Fail after sleep ? @@ -46,7 +46,7 @@ def test_create_project_model_for_job(faker: Faker): } ) - print(inputs.json(indent=2)) + print(inputs.model_dump_json(indent=2)) job = Job.create_solver_job(solver=solver, inputs=inputs) @@ -77,7 +77,7 @@ def test_job_to_node_inputs_conversion(): } ) for value in job_inputs.values.values(): - assert parse_obj_as(ArgumentTypes, value) == value + assert TypeAdapter(ArgumentTypes).validate_python(value) == value node_inputs: InputsDict = { "x": 4.33, @@ -94,14 +94,14 @@ def test_job_to_node_inputs_conversion(): } for value in node_inputs.values(): - assert parse_obj_as(InputTypes, value) == value + assert TypeAdapter(InputTypes).validate_python(value) == value # test transformations in both directions got_node_inputs = create_node_inputs_from_job_inputs(inputs=job_inputs) got_job_inputs = create_job_inputs_from_node_inputs(inputs=node_inputs) NodeInputs = create_model("NodeInputs", __root__=(dict[str, InputTypes], ...)) - print(NodeInputs.parse_obj(got_node_inputs).json(indent=2)) + print(NodeInputs.model_validate(got_node_inputs).model_dump_json(indent=2)) print(got_job_inputs.json(indent=2)) assert got_job_inputs == job_inputs @@ -109,7 +109,7 @@ def test_job_to_node_inputs_conversion(): def test_create_job_from_project(faker: Faker): - project = Project.parse_obj( + project = Project.model_validate( { "uuid": "f925e30f-19de-42dc-acab-3ce93ea0a0a7", "name": "simcore%2Fservices%2Fcomp%2Fitis%2Fsleeper/2.0.2/jobs/f925e30f-19de-42dc-acab-3ce93ea0a0a7", @@ -181,7 +181,7 @@ def test_create_job_from_project(faker: Faker): }, ) - expected_job = Job.parse_obj( + expected_job = Job.model_validate( { "id": "f925e30f-19de-42dc-acab-3ce93ea0a0a7", "name": "simcore%2Fservices%2Fcomp%2Fitis%2Fsleeper/2.0.2/jobs/f925e30f-19de-42dc-acab-3ce93ea0a0a7", @@ -207,12 +207,12 @@ def fake_url_for(*args, **kwargs): assert job.id == project.uuid assert job.name == project.name - url_field_names = {name for name in job.__fields__ if name.endswith("url")} + url_field_names = {name for name in job.model_fields if name.endswith("url")} assert all(getattr(job, _) for _ in url_field_names) # this tends to be a problem assert job.inputs_checksum == expected_job.inputs_checksum - assert job.dict(exclude=url_field_names) == expected_job.dict( + assert job.model_dump(exclude=url_field_names) == expected_job.model_dump( exclude=url_field_names ) @@ -222,7 +222,7 @@ def test_create_jobstatus_from_task(): from simcore_service_api_server.models.schemas.jobs import JobStatus from simcore_service_api_server.services.director_v2 import ComputationTaskGet - task = ComputationTaskGet.parse_obj({}) # TODO: + task = ComputationTaskGet.model_validate({}) # TODO: job_status: JobStatus = create_jobstatus_from_task(task) assert job_status.job_id == task.id From a7e72c2b03b50353183e8c5a257774aaacdf3bf7 Mon Sep 17 00:00:00 2001 From: Giancarlo Romeo Date: Thu, 10 Oct 2024 12:27:22 +0200 Subject: [PATCH 03/37] fix url type --- .../src/simcore_service_api_server/api/routes/files.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/api-server/src/simcore_service_api_server/api/routes/files.py b/services/api-server/src/simcore_service_api_server/api/routes/files.py index a89771dc490..a69eb43d08e 100644 --- a/services/api-server/src/simcore_service_api_server/api/routes/files.py +++ b/services/api-server/src/simcore_service_api_server/api/routes/files.py @@ -432,7 +432,7 @@ async def download_file( ) _logger.info("Downloading %s to %s ...", file_meta, presigned_download_link) - return RedirectResponse(presigned_download_link) + return RedirectResponse(f"{presigned_download_link}") async def files_upload_multiple_view(): From 9c1a49885e1c60001ca0aa3341ce1488543b71e6 Mon Sep 17 00:00:00 2001 From: Giancarlo Romeo Date: Thu, 10 Oct 2024 12:29:57 +0200 Subject: [PATCH 04/37] fix typeadapter --- .../src/simcore_service_api_server/api/routes/files.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/services/api-server/src/simcore_service_api_server/api/routes/files.py b/services/api-server/src/simcore_service_api_server/api/routes/files.py index a69eb43d08e..532839d5284 100644 --- a/services/api-server/src/simcore_service_api_server/api/routes/files.py +++ b/services/api-server/src/simcore_service_api_server/api/routes/files.py @@ -14,7 +14,7 @@ from fastapi_pagination.api import create_page from models_library.api_schemas_storage import ETag, FileUploadCompletionBody, LinkType from models_library.basic_types import SHA256Str -from pydantic import AnyUrl, ByteSize, PositiveInt, ValidationError, parse_obj_as +from pydantic import AnyUrl, ByteSize, PositiveInt, TypeAdapter, ValidationError from servicelib.fastapi.requests_decorators import cancel_on_disconnect from simcore_sdk.node_ports_common.constants import SIMCORE_LOCATION from simcore_sdk.node_ports_common.file_io_utils import UploadableFileObject @@ -360,7 +360,7 @@ async def abort_multipart_upload( abort_link: URL = await storage_client.create_abort_upload_link( file=file, query={"user_id": str(user_id)} ) - await abort_upload(abort_upload_link=parse_obj_as(AnyUrl, str(abort_link))) + await abort_upload(abort_upload_link=TypeAdapter(AnyUrl).validate_python(str(abort_link))) @router.post( @@ -392,7 +392,7 @@ async def complete_multipart_upload( e_tag: ETag = await complete_file_upload( uploaded_parts=uploaded_parts.parts, - upload_completion_link=parse_obj_as(AnyUrl, f"{complete_link}"), + upload_completion_link=TypeAdapter(AnyUrl).validate_python(f"{complete_link}"), ) file.e_tag = e_tag From 13502ac1dd36a777dbf59eaaab2ae8404ead78fc Mon Sep 17 00:00:00 2001 From: Giancarlo Romeo Date: Thu, 10 Oct 2024 12:33:19 +0200 Subject: [PATCH 05/37] fix download url type --- .../simcore_service_api_server/models/schemas/studies.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/services/api-server/src/simcore_service_api_server/models/schemas/studies.py b/services/api-server/src/simcore_service_api_server/models/schemas/studies.py index 806ec309017..a5f69a7ad08 100644 --- a/services/api-server/src/simcore_service_api_server/models/schemas/studies.py +++ b/services/api-server/src/simcore_service_api_server/models/schemas/studies.py @@ -1,17 +1,16 @@ -from typing import Annotated, TypeAlias +from typing import TypeAlias +from common_library.pydantic_networks_extension import AnyUrlLegacy from models_library import projects, projects_nodes_io from models_library.utils import pydantic_tools_extension -from pydantic import AnyUrl, BaseModel, BeforeValidator, Field, TypeAdapter +from pydantic import BaseModel, Field from .. import api_resources from . import solvers StudyID: TypeAlias = projects.ProjectID NodeName: TypeAlias = str -DownloadLink: TypeAlias = Annotated[ - str, BeforeValidator(lambda x: str(TypeAdapter(AnyUrl).validate_python(x))) -] +DownloadLink: TypeAlias = AnyUrlLegacy class Study(BaseModel): From 7346f8a9886bfc363f83250527458e0eb2e10915 Mon Sep 17 00:00:00 2001 From: Giancarlo Romeo Date: Thu, 10 Oct 2024 12:41:06 +0200 Subject: [PATCH 06/37] fix url type --- .../api/routes/solvers_jobs_getters.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/api-server/src/simcore_service_api_server/api/routes/solvers_jobs_getters.py b/services/api-server/src/simcore_service_api_server/api/routes/solvers_jobs_getters.py index 2be5ac934d1..eb5f1c81837 100644 --- a/services/api-server/src/simcore_service_api_server/api/routes/solvers_jobs_getters.py +++ b/services/api-server/src/simcore_service_api_server/api/routes/solvers_jobs_getters.py @@ -335,7 +335,7 @@ async def get_job_output_logfile( f"{solver_key}/releases/{version}/jobs/{job_id}/outputs/logfile", presigned_download_link, ) - return RedirectResponse(presigned_download_link) + return RedirectResponse(f"{presigned_download_link}") # No log found ! raise HTTPException( From 9294f6b9dadc4223aefcca343875ac4367c8aacb Mon Sep 17 00:00:00 2001 From: Giancarlo Romeo Date: Tue, 15 Oct 2024 13:18:09 +0200 Subject: [PATCH 07/37] fix typecheck --- .../exceptions/handlers/__init__.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/services/api-server/src/simcore_service_api_server/exceptions/handlers/__init__.py b/services/api-server/src/simcore_service_api_server/exceptions/handlers/__init__.py index d2779338980..239de8d7a92 100644 --- a/services/api-server/src/simcore_service_api_server/exceptions/handlers/__init__.py +++ b/services/api-server/src/simcore_service_api_server/exceptions/handlers/__init__.py @@ -18,12 +18,12 @@ def setup(app: FastAPI, *, is_debug: bool = False): - app.add_exception_handler(HTTPException, http_exception_handler) - app.add_exception_handler(HttpxException, handle_httpx_client_exceptions) - app.add_exception_handler(RequestValidationError, http422_error_handler) - app.add_exception_handler(LogStreamingBaseError, log_handling_error_handler) - app.add_exception_handler(CustomBaseError, custom_error_handler) - app.add_exception_handler(BaseBackEndError, backend_error_handler) + app.add_exception_handler(HTTPException, http_exception_handler) # type: ignore[arg-type] + app.add_exception_handler(HttpxException, handle_httpx_client_exceptions) # type: ignore[arg-type] + app.add_exception_handler(RequestValidationError, http422_error_handler) # type: ignore[arg-type] + app.add_exception_handler(LogStreamingBaseError, log_handling_error_handler) # type: ignore[arg-type] + app.add_exception_handler(CustomBaseError, custom_error_handler) # type: ignore[arg-type] + app.add_exception_handler(BaseBackEndError, backend_error_handler) # type: ignore[arg-type] # SEE https://docs.python.org/3/library/exceptions.html#exception-hierarchy app.add_exception_handler( From f592daaa26ece6d7a71d3073e28be89a549fe46c Mon Sep 17 00:00:00 2001 From: Giancarlo Romeo Date: Tue, 15 Oct 2024 13:33:38 +0200 Subject: [PATCH 08/37] fix typechecking --- .../api-server/src/simcore_service_api_server/core/settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/api-server/src/simcore_service_api_server/core/settings.py b/services/api-server/src/simcore_service_api_server/core/settings.py index 038c29f8b52..e6c88a10f17 100644 --- a/services/api-server/src/simcore_service_api_server/core/settings.py +++ b/services/api-server/src/simcore_service_api_server/core/settings.py @@ -110,7 +110,7 @@ class ApplicationSettings(BasicSettings): API_SERVER_PROMETHEUS_INSTRUMENTATION_COLLECT_SECONDS: PositiveInt = 5 API_SERVER_PROFILING: bool = False API_SERVER_TRACING: TracingSettings | None = Field( - auto_default_from_env=True, description="settings for opentelemetry tracing" + description="settings for opentelemetry tracing", json_schema_extra={"auto_default_from_env": True} ) @cached_property From 1d713bf8fb21e6439e24cb1203bfece26352853d Mon Sep 17 00:00:00 2001 From: Giancarlo Romeo Date: Tue, 15 Oct 2024 13:55:40 +0200 Subject: [PATCH 09/37] fix typecheck --- .../db/repositories/users.py | 8 ++- .../models/schemas/jobs.py | 2 +- .../models/schemas/solvers.py | 2 +- .../services/catalog.py | 2 +- .../services/log_streaming.py | 8 +-- .../services/solver_job_outputs.py | 4 +- .../services/study_job_models_converters.py | 4 +- .../services/webserver.py | 54 ++++++++++++------- .../test_api_routers_solvers_jobs.py | 8 +-- .../test_api_routes_studies_jobs.py | 5 +- services/api-server/tests/unit/conftest.py | 14 ++--- .../api-server/tests/unit/test_api_files.py | 11 ++-- .../api-server/tests/unit/test_api_health.py | 3 +- .../api-server/tests/unit/test_api_solvers.py | 3 +- .../api-server/tests/unit/test_api_wallets.py | 7 ++- .../tests/unit/test_models_schemas_files.py | 18 ++++--- 16 files changed, 87 insertions(+), 66 deletions(-) diff --git a/services/api-server/src/simcore_service_api_server/db/repositories/users.py b/services/api-server/src/simcore_service_api_server/db/repositories/users.py index 15ea74f083b..3ae1ce00184 100644 --- a/services/api-server/src/simcore_service_api_server/db/repositories/users.py +++ b/services/api-server/src/simcore_service_api_server/db/repositories/users.py @@ -1,6 +1,6 @@ import sqlalchemy as sa from models_library.emails import LowerCaseEmailStr -from pydantic import parse_obj_as +from pydantic import TypeAdapter from ..tables import UserStatus, users from ._base import BaseRepository @@ -14,4 +14,8 @@ async def get_active_user_email(self, user_id: int) -> LowerCaseEmailStr | None: (users.c.id == user_id) & (users.c.status == UserStatus.ACTIVE) ) ) - return parse_obj_as(LowerCaseEmailStr, email) if email is not None else None + return ( + TypeAdapter(LowerCaseEmailStr).validate_python(email) + if email is not None + else None + ) diff --git a/services/api-server/src/simcore_service_api_server/models/schemas/jobs.py b/services/api-server/src/simcore_service_api_server/models/schemas/jobs.py index f3c2c16672b..7cc16e6503e 100644 --- a/services/api-server/src/simcore_service_api_server/models/schemas/jobs.py +++ b/services/api-server/src/simcore_service_api_server/models/schemas/jobs.py @@ -46,7 +46,7 @@ def _compute_keyword_arguments_checksum(kwargs: KeywordArguments): for key in sorted(kwargs.keys()): value = kwargs[key] if isinstance(value, File): - value = _compute_keyword_arguments_checksum(value.dict()) + value = _compute_keyword_arguments_checksum(value.model_dump()) else: value = str(value) _dump_str += f"{key}:{value}" diff --git a/services/api-server/src/simcore_service_api_server/models/schemas/solvers.py b/services/api-server/src/simcore_service_api_server/models/schemas/solvers.py index f7531346e84..0e32f5343b5 100644 --- a/services/api-server/src/simcore_service_api_server/models/schemas/solvers.py +++ b/services/api-server/src/simcore_service_api_server/models/schemas/solvers.py @@ -69,7 +69,7 @@ class Solver(BaseModel): @classmethod def create_from_image(cls, image_meta: ServiceMetaDataPublished) -> "Solver": - data = image_meta.dict( + data = image_meta.model_dump( include={"name", "key", "version", "description", "contact"}, ) diff --git a/services/api-server/src/simcore_service_api_server/services/catalog.py b/services/api-server/src/simcore_service_api_server/services/catalog.py index 758fe44792a..d3ffad54be6 100644 --- a/services/api-server/src/simcore_service_api_server/services/catalog.py +++ b/services/api-server/src/simcore_service_api_server/services/catalog.py @@ -47,7 +47,7 @@ class TruncatedCatalogServiceOut(ServiceMetaDataPublished): # Converters def to_solver(self) -> Solver: - data = self.dict( + data = self.model_dump( include={"name", "key", "version", "description", "contact", "owner"}, ) diff --git a/services/api-server/src/simcore_service_api_server/services/log_streaming.py b/services/api-server/src/simcore_service_api_server/services/log_streaming.py index faefc5c905b..08459b55271 100644 --- a/services/api-server/src/simcore_service_api_server/services/log_streaming.py +++ b/services/api-server/src/simcore_service_api_server/services/log_streaming.py @@ -52,7 +52,7 @@ async def __aexit__(self, exc_type, exc, tb): async def _distribute_logs(self, data: bytes): with log_catch(_logger, reraise=False): - got = LoggerRabbitMessage.parse_raw(data) + got = LoggerRabbitMessage.model_validate_json(data) item = JobLog( job_id=got.project_id, node_id=got.node_id, @@ -121,12 +121,12 @@ async def log_generator(self) -> AsyncIterable[str]: log: JobLog = await asyncio.wait_for( self._queue.get(), timeout=self._log_check_timeout ) - yield log.json() + _NEW_LINE + yield log.model_dump_json() + _NEW_LINE except asyncio.TimeoutError: done = await self._project_done() except BaseBackEndError as exc: _logger.info("%s", f"{exc}") - yield ErrorGet(errors=[f"{exc}"]).json() + _NEW_LINE + yield ErrorGet(errors=[f"{exc}"]).model_dump_json() + _NEW_LINE except Exception as exc: # pylint: disable=W0718 error_code = create_error_code(exc) _logger.exception( @@ -139,6 +139,6 @@ async def log_generator(self) -> AsyncIterable[str]: errors=[ MSG_INTERNAL_ERROR_USER_FRIENDLY_TEMPLATE + f" (OEC: {error_code})" ] - ).json() + _NEW_LINE + ).model_dump_json() + _NEW_LINE finally: await self._log_distributor.deregister(self._job_id) diff --git a/services/api-server/src/simcore_service_api_server/services/solver_job_outputs.py b/services/api-server/src/simcore_service_api_server/services/solver_job_outputs.py index 27ce26bd8f0..dac7610b5a3 100644 --- a/services/api-server/src/simcore_service_api_server/services/solver_job_outputs.py +++ b/services/api-server/src/simcore_service_api_server/services/solver_job_outputs.py @@ -4,7 +4,7 @@ import aiopg from models_library.projects import ProjectID, ProjectIDStr from models_library.projects_nodes_io import BaseFileLink, NodeID, NodeIDStr -from pydantic import StrictBool, StrictFloat, StrictInt, parse_obj_as +from pydantic import StrictBool, StrictFloat, StrictInt, TypeAdapter from simcore_sdk import node_ports_v2 from simcore_sdk.node_ports_v2 import DBManager, Nodeports from simcore_service_api_server.exceptions.backend_errors import ( @@ -44,7 +44,7 @@ async def get_solver_output_results( port.property_type, port.value, ) - assert parse_obj_as(ResultsTypes, port.value) == port.value # type: ignore # nosec + assert TypeAdapter(ResultsTypes).validate_python(port.value) == port.value # type: ignore # nosec solver_output_results[port.key] = port.value diff --git a/services/api-server/src/simcore_service_api_server/services/study_job_models_converters.py b/services/api-server/src/simcore_service_api_server/services/study_job_models_converters.py index 8258e67129b..1ab18a85c0d 100644 --- a/services/api-server/src/simcore_service_api_server/services/study_job_models_converters.py +++ b/services/api-server/src/simcore_service_api_server/services/study_job_models_converters.py @@ -13,7 +13,7 @@ from models_library.projects import DateTimeStr from models_library.projects_nodes import InputID from models_library.projects_nodes_io import LinkToFileTypes, NodeID, SimcoreS3FileID -from pydantic import parse_obj_as +from pydantic import TypeAdapter from ..models.domain.projects import InputTypes, SimCoreFileLink from ..models.schemas.files import File @@ -107,7 +107,7 @@ async def create_job_outputs_from_project_outputs( and {"store", "path"}.issubset(value.keys()) ): assert ( # nosec - parse_obj_as(LinkToFileTypes, value) is not None # type: ignore[arg-type] + TypeAdapter(LinkToFileTypes).validate_python(value) is not None ) path = value["path"] diff --git a/services/api-server/src/simcore_service_api_server/services/webserver.py b/services/api-server/src/simcore_service_api_server/services/webserver.py index a6e71677950..d9448ded94f 100644 --- a/services/api-server/src/simcore_service_api_server/services/webserver.py +++ b/services/api-server/src/simcore_service_api_server/services/webserver.py @@ -234,7 +234,7 @@ async def _wait_for_long_running_task_results(self, lrt_response: httpx.Response f"{result_url}", cookies=self.session_cookies ) result_response.raise_for_status() - return Envelope.parse_raw(result_response.text).data + return Envelope.model_validate_json(result_response.text).data # PROFILE -------------------------------------------------- @@ -242,7 +242,9 @@ async def _wait_for_long_running_task_results(self, lrt_response: httpx.Response async def get_me(self) -> Profile: response = await self.client.get("/me", cookies=self.session_cookies) response.raise_for_status() - profile: Profile | None = Envelope[Profile].parse_raw(response.text).data + profile: Profile | None = ( + Envelope[Profile].model_validate_json(response.text).data + ) assert profile is not None # nosec return profile @@ -250,7 +252,7 @@ async def get_me(self) -> Profile: async def update_me(self, *, profile_update: ProfileUpdate) -> Profile: response = await self.client.put( "/me", - json=profile_update.dict(exclude_none=True), + json=profile_update.model_dump(exclude_none=True), cookies=self.session_cookies, ) response.raise_for_status() @@ -316,7 +318,7 @@ async def get_project(self, *, project_id: UUID) -> ProjectGet: cookies=self.session_cookies, ) response.raise_for_status() - data = Envelope[ProjectGet].parse_raw(response.text).data + data = Envelope[ProjectGet].model_validate_json(response.text).data assert data is not None # nosec return data @@ -360,7 +362,7 @@ async def get_project_metadata_ports( cookies=self.session_cookies, ) response.raise_for_status() - data = Envelope[list[StudyPort]].parse_raw(response.text).data + data = Envelope[list[StudyPort]].model_validate_json(response.text).data assert data is not None # nosec assert isinstance(data, list) # nosec return data @@ -374,7 +376,7 @@ async def get_project_metadata( cookies=self.session_cookies, ) response.raise_for_status() - data = Envelope[ProjectMetadataGet].parse_raw(response.text).data + data = Envelope[ProjectMetadataGet].model_validate_json(response.text).data assert data is not None # nosec return data @@ -397,7 +399,7 @@ async def update_project_metadata( json=jsonable_encoder(ProjectMetadataUpdate(custom=metadata)), ) response.raise_for_status() - data = Envelope[ProjectMetadataGet].parse_raw(response.text).data + data = Envelope[ProjectMetadataGet].model_validate_json(response.text).data assert data is not None # nosec return data @@ -411,7 +413,7 @@ async def get_project_node_pricing_unit( ) response.raise_for_status() - data = Envelope[PricingUnitGet].parse_raw(response.text).data + data = Envelope[PricingUnitGet].model_validate_json(response.text).data assert data is not None # nosec return data @@ -466,7 +468,9 @@ async def update_project_inputs( ) response.raise_for_status() data: dict[NodeID, ProjectInputGet] | None = ( - Envelope[dict[NodeID, ProjectInputGet]].parse_raw(response.text).data + Envelope[dict[NodeID, ProjectInputGet]] + .model_validate_json(response.text) + .data ) assert data is not None # nosec return data @@ -483,7 +487,9 @@ async def get_project_inputs( response.raise_for_status() data: dict[NodeID, ProjectInputGet] | None = ( - Envelope[dict[NodeID, ProjectInputGet]].parse_raw(response.text).data + Envelope[dict[NodeID, ProjectInputGet]] + .model_validate_json(response.text) + .data ) assert data is not None # nosec return data @@ -500,7 +506,9 @@ async def get_project_outputs( response.raise_for_status() data: dict[NodeID, dict[str, Any]] | None = ( - Envelope[dict[NodeID, dict[str, Any]]].parse_raw(response.text).data + Envelope[dict[NodeID, dict[str, Any]]] + .model_validate_json(response.text) + .data ) assert data is not None # nosec return data @@ -525,7 +533,11 @@ async def get_default_wallet(self) -> WalletGetWithAvailableCredits: cookies=self.session_cookies, ) response.raise_for_status() - data = Envelope[WalletGetWithAvailableCredits].parse_raw(response.text).data + data = ( + Envelope[WalletGetWithAvailableCredits] + .model_validate_json(response.text) + .data + ) assert data is not None # nosec return data @@ -536,7 +548,11 @@ async def get_wallet(self, *, wallet_id: int) -> WalletGetWithAvailableCredits: cookies=self.session_cookies, ) response.raise_for_status() - data = Envelope[WalletGetWithAvailableCredits].parse_raw(response.text).data + data = ( + Envelope[WalletGetWithAvailableCredits] + .model_validate_json(response.text) + .data + ) assert data is not None # nosec return data @@ -547,7 +563,7 @@ async def get_project_wallet(self, *, project_id: ProjectID) -> WalletGet | None cookies=self.session_cookies, ) response.raise_for_status() - data = Envelope[WalletGet].parse_raw(response.text).data + data = Envelope[WalletGet].model_validate_json(response.text).data assert data is not None # nosec return data @@ -560,7 +576,7 @@ async def get_product_price(self) -> GetCreditPrice: cookies=self.session_cookies, ) response.raise_for_status() - data = Envelope[GetCreditPrice].parse_raw(response.text).data + data = Envelope[GetCreditPrice].model_validate_json(response.text).data assert data is not None # nosec return data @@ -577,10 +593,12 @@ async def get_service_pricing_plan( cookies=self.session_cookies, ) response.raise_for_status() - pricing_plan_get = Envelope[PricingPlanGet].parse_raw(response.text).data + pricing_plan_get = ( + Envelope[PricingPlanGet].model_validate_json(response.text).data + ) if pricing_plan_get: - return ServicePricingPlanGet.construct( - **pricing_plan_get.dict(exclude={"is_active"}) + return ServicePricingPlanGet.model_construct( + **pricing_plan_get.model_dump(exclude={"is_active"}) ) return None diff --git a/services/api-server/tests/unit/api_solvers/test_api_routers_solvers_jobs.py b/services/api-server/tests/unit/api_solvers/test_api_routers_solvers_jobs.py index 4adc0e851ff..c9b9b8e9234 100644 --- a/services/api-server/tests/unit/api_solvers/test_api_routers_solvers_jobs.py +++ b/services/api-server/tests/unit/api_solvers/test_api_routers_solvers_jobs.py @@ -18,7 +18,7 @@ from fastapi import FastAPI from models_library.services import ServiceMetaDataPublished from models_library.utils.fastapi_encoders import jsonable_encoder -from pydantic import AnyUrl, HttpUrl, parse_obj_as +from pydantic import AnyUrl, HttpUrl, TypeAdapter from respx import MockRouter from simcore_service_api_server._meta import API_VTAG from simcore_service_api_server.core.settings import ApplicationSettings @@ -55,7 +55,7 @@ def presigned_download_link( ) -> Iterator[AnyUrl]: s3_client = boto3.client( "s3", - endpoint_url=mocked_s3_server_url, + endpoint_url=f"{mocked_s3_server_url}", # Some fake auth, otherwise botocore.exceptions.NoCredentialsError: Unable to locate credentials aws_secret_access_key="xxx", # noqa: S106 aws_access_key_id="xxx", @@ -79,7 +79,7 @@ def presigned_download_link( print("generated link", presigned_url) # SEE also https://gist.github.com/amarjandu/77a7d8e33623bae1e4e5ba40dc043cb9 - return parse_obj_as(AnyUrl, presigned_url) + return TypeAdapter(AnyUrl).validate_python(presigned_url) @pytest.fixture @@ -350,7 +350,7 @@ async def test_run_solver_job( # Tests https://github.com/ITISFoundation/osparc-issues/issues/948 "a_list": [1, 2, 3], } - ).dict(), + ).model_dump(), ) assert resp.status_code == status.HTTP_201_CREATED diff --git a/services/api-server/tests/unit/api_studies/test_api_routes_studies_jobs.py b/services/api-server/tests/unit/api_studies/test_api_routes_studies_jobs.py index ece3fcd1f57..811818a8939 100644 --- a/services/api-server/tests/unit/api_studies/test_api_routes_studies_jobs.py +++ b/services/api-server/tests/unit/api_studies/test_api_routes_studies_jobs.py @@ -14,7 +14,6 @@ import respx from faker import Faker from fastapi import status -from pydantic import parse_obj_as from pytest_simcore.helpers.httpx_calls_capture_models import ( CreateRespxMockCallback, HttpApiCallCaptureModel, @@ -45,7 +44,7 @@ async def test_studies_jobs_workflow( resp = await client.get("/v0/studies/{study_id}", auth=auth) assert resp.status_code == status.HTTP_200_OK - study = parse_obj_as(Study, resp.json()) + study = Study.model_validate(resp.json()) assert study.uid == study_id # Lists study jobs @@ -56,7 +55,7 @@ async def test_studies_jobs_workflow( resp = await client.post("/v0/studies/{study_id}/jobs", auth=auth) assert resp.status_code == status.HTTP_201_CREATED - job = parse_obj_as(Job, resp.json()) + job = Job.model_validate(resp.json()) job_id = job.id # Get Study Job diff --git a/services/api-server/tests/unit/conftest.py b/services/api-server/tests/unit/conftest.py index 99d248783c2..74ba73e2ce4 100644 --- a/services/api-server/tests/unit/conftest.py +++ b/services/api-server/tests/unit/conftest.py @@ -36,7 +36,7 @@ from models_library.users import UserID from moto.server import ThreadedMotoServer from packaging.version import Version -from pydantic import EmailStr, HttpUrl, parse_obj_as +from pydantic import EmailStr, HttpUrl, TypeAdapter from pytest_mock import MockerFixture from pytest_simcore.helpers.host import get_localhost_ip from pytest_simcore.helpers.monkeypatch_envs import EnvVarsDict, setenvs_from_dict @@ -72,7 +72,7 @@ def app_environment( ) # should be sufficient to create settings - print(ApplicationSettings.create_from_envs().json(indent=1)) + print(ApplicationSettings.create_from_envs().model_dump_json(indent=1)) return env_vars @@ -202,7 +202,9 @@ def mocked_s3_server_url() -> Iterator[HttpUrl]: ) # pylint: disable=protected-access - endpoint_url = parse_obj_as(HttpUrl, f"http://{server._ip_address}:{server._port}") + endpoint_url = TypeAdapter(HttpUrl).validate_python( + f"http://{server._ip_address}:{server._port}" + ) print(f"--> started mock S3 server on {endpoint_url}") server.start() @@ -363,7 +365,7 @@ def mocked_storage_service_api_base( "api_version": "1.0.0", "version": "1.0.0", }, - ).dict(), + ).model_dump(), ) assert openapi["paths"]["/v0/status"]["get"]["operationId"] == "get_status" @@ -376,7 +378,7 @@ def mocked_storage_service_api_base( "url": faker.url(), "diagnostics_url": faker.url(), } - ).dict(), + ).model_dump(), ) # SEE https://github.com/pcrespov/sandbox-python/blob/f650aad57aced304aac9d0ad56c00723d2274ad0/respx-lib/test_disable_mock.py @@ -497,7 +499,7 @@ def _set_result_and_get_reponse(self, result: Any): status_href=f"{settings.API_SERVER_WEBSERVER.api_base_url}/tasks/{task_id}", result_href=f"{settings.API_SERVER_WEBSERVER.api_base_url}/tasks/{task_id}/result", abort_href=f"{settings.API_SERVER_WEBSERVER.api_base_url}/tasks/{task_id}", - ).dict() + ).model_dump() }, ) diff --git a/services/api-server/tests/unit/test_api_files.py b/services/api-server/tests/unit/test_api_files.py index 8c308bfa2f2..bbbef802188 100644 --- a/services/api-server/tests/unit/test_api_files.py +++ b/services/api-server/tests/unit/test_api_files.py @@ -24,7 +24,7 @@ UploadedPart, ) from models_library.basic_types import SHA256Str -from pydantic import parse_obj_as +from pydantic import TypeAdapter from pytest_simcore.helpers.httpx_calls_capture_models import ( CreateRespxMockCallback, HttpApiCallCaptureModel, @@ -67,8 +67,7 @@ def file(cls) -> File: @classmethod def client_file(cls) -> ClientFile: - return parse_obj_as( - ClientFile, + return TypeAdapter(ClientFile).validate_python( { "filename": cls._file_name, "filesize": cls._file_size, @@ -103,7 +102,7 @@ async def test_list_files_legacy( assert response.status_code == status.HTTP_200_OK - parse_obj_as(File, response.json()) + TypeAdapter(File).validate_python(response.json()) assert response.json() == [ { @@ -269,7 +268,7 @@ async def test_get_upload_links( payload: dict[str, str] = response.json() assert response.status_code == status.HTTP_200_OK - file: File = parse_obj_as(File, payload) + file: File = File.model_validate(payload) assert file.sha256_checksum == DummyFileData.checksum() elif follow_up_request == "abort": body = { @@ -333,7 +332,7 @@ def side_effect_callback( response = await client.get(f"{API_VTAG}/files:search", auth=auth, params=query) assert response.status_code == status.HTTP_200_OK - page: Page[File] = parse_obj_as(Page[File], response.json()) + page: Page[File] = TypeAdapter(Page[File]).validate_python(response.json()) assert len(page.items) == page.total file = page.items[0] if "sha256_checksum" in query: diff --git a/services/api-server/tests/unit/test_api_health.py b/services/api-server/tests/unit/test_api_health.py index d548c525406..d421703b0f2 100644 --- a/services/api-server/tests/unit/test_api_health.py +++ b/services/api-server/tests/unit/test_api_health.py @@ -10,7 +10,6 @@ from fastapi import FastAPI, status from httpx import AsyncClient from models_library.app_diagnostics import AppStatusCheck -from pydantic import parse_obj_as from respx import MockRouter from simcore_service_api_server._meta import API_VTAG @@ -54,4 +53,4 @@ async def test_get_service_state( "url": "http://api.testserver.io/state", } - assert parse_obj_as(AppStatusCheck, response.json()) + assert AppStatusCheck.model_validate(response.json()) diff --git a/services/api-server/tests/unit/test_api_solvers.py b/services/api-server/tests/unit/test_api_solvers.py index dada48a762c..31e8ccb7f59 100644 --- a/services/api-server/tests/unit/test_api_solvers.py +++ b/services/api-server/tests/unit/test_api_solvers.py @@ -10,7 +10,6 @@ from fastapi import status from httpx import AsyncClient from models_library.api_schemas_api_server.pricing_plans import ServicePricingPlanGet -from pydantic import parse_obj_as from pytest_simcore.helpers.httpx_calls_capture_models import CreateRespxMockCallback from simcore_service_api_server._meta import API_VTAG @@ -50,4 +49,4 @@ async def test_get_solver_pricing_plan( ) assert expected_status_code == response.status_code if response.status_code == status.HTTP_200_OK: - _ = parse_obj_as(ServicePricingPlanGet, response.json()) + _ = ServicePricingPlanGet.model_validate(response.json()) diff --git a/services/api-server/tests/unit/test_api_wallets.py b/services/api-server/tests/unit/test_api_wallets.py index 0edf09e7f90..cad3bf5e285 100644 --- a/services/api-server/tests/unit/test_api_wallets.py +++ b/services/api-server/tests/unit/test_api_wallets.py @@ -11,7 +11,6 @@ from fastapi import status from httpx import AsyncClient from models_library.api_schemas_webserver.wallets import WalletGetWithAvailableCredits -from pydantic import parse_obj_as from pytest_simcore.helpers.httpx_calls_capture_models import ( CreateRespxMockCallback, HttpApiCallCaptureModel, @@ -53,8 +52,8 @@ def _get_wallet_side_effect( response = await client.get(f"{API_VTAG}/wallets/{wallet_id}", auth=auth) if "success" in capture: assert response.status_code == 200 - wallet: WalletGetWithAvailableCredits = parse_obj_as( - WalletGetWithAvailableCredits, response.json() + wallet: WalletGetWithAvailableCredits = ( + WalletGetWithAvailableCredits.model_validate(response.json()) ) assert wallet.wallet_id == wallet_id elif "failure" in capture: @@ -78,4 +77,4 @@ async def test_get_default_wallet( response = await client.get(f"{API_VTAG}/wallets/default", auth=auth) assert response.status_code == status.HTTP_200_OK - _ = parse_obj_as(WalletGetWithAvailableCredits, response.json()) + _ = WalletGetWithAvailableCredits.model_validate(response.json()) diff --git a/services/api-server/tests/unit/test_models_schemas_files.py b/services/api-server/tests/unit/test_models_schemas_files.py index e4852afd238..2ae9c4e5144 100644 --- a/services/api-server/tests/unit/test_models_schemas_files.py +++ b/services/api-server/tests/unit/test_models_schemas_files.py @@ -14,7 +14,7 @@ from models_library.api_schemas_storage import FileMetaDataGet as StorageFileMetaData from models_library.basic_types import SHA256Str from models_library.projects_nodes_io import StorageFileID -from pydantic import ValidationError, parse_obj_as +from pydantic import TypeAdapter, ValidationError from simcore_service_api_server.models.schemas.files import File from simcore_service_api_server.services.storage import to_file_api_model @@ -34,8 +34,8 @@ def expected_sha256sum() -> SHA256Str: # $ echo -n "This is a test" | md5sum - # ce114e4501d2f4e2dcea3e17b546f339 - # - _sha256sum: SHA256Str = parse_obj_as( - SHA256Str, "c7be1ed902fb8dd4d48997c6452f5d7e509fbcdbe2808b16bcf4edce4c07d14e" + _sha256sum: SHA256Str = TypeAdapter(SHA256Str).validate_python( + "c7be1ed902fb8dd4d48997c6452f5d7e509fbcdbe2808b16bcf4edce4c07d14e" ) assert hashlib.sha256(FILE_CONTENT.encode()).hexdigest() == _sha256sum return _sha256sum @@ -83,8 +83,8 @@ def test_convert_between_file_models(): storage_file_meta = StorageFileMetaData( **StorageFileMetaData.model_config["json_schema_extra"]["examples"][1] ) - storage_file_meta.file_id = parse_obj_as( - StorageFileID, f"api/{uuid4()}/extensionless" + storage_file_meta.file_id = TypeAdapter(StorageFileID).validate_python( + f"api/{uuid4()}/extensionless" ) apiserver_file_meta = to_file_api_model(storage_file_meta) @@ -94,11 +94,13 @@ def test_convert_between_file_models(): assert apiserver_file_meta.e_tag == storage_file_meta.entity_tag with pytest.raises(ValueError): - storage_file_meta.file_id = parse_obj_as( - StorageFileID, f"{uuid4()}/{uuid4()}/foo.txt" + storage_file_meta.file_id = TypeAdapter(StorageFileID).validate_python( + f"{uuid4()}/{uuid4()}/foo.txt" ) to_file_api_model(storage_file_meta) with pytest.raises(ValidationError): - storage_file_meta.file_id = parse_obj_as(StorageFileID, "api/NOTUUID/foo.txt") + storage_file_meta.file_id = TypeAdapter(StorageFileID).validate_python( + "api/NOTUUID/foo.txt" + ) to_file_api_model(storage_file_meta) From 7968bb3cd6f08ea8154b362ba6bff1f9d578a3b0 Mon Sep 17 00:00:00 2001 From: Giancarlo Romeo Date: Tue, 15 Oct 2024 14:36:25 +0200 Subject: [PATCH 10/37] continue migration --- .../simcore_service_api_server/services/director_v2.py | 8 ++++---- .../src/simcore_service_api_server/services/webserver.py | 8 +++++--- services/api-server/tests/unit/conftest.py | 2 +- services/api-server/tests/unit/test_cli.py | 2 +- services/api-server/tests/unit/test_exceptions.py | 6 +++--- services/api-server/tests/unit/test_services_rabbitmq.py | 4 ++-- .../tests/unit/test_utils_http_calls_capture.py | 4 ++-- 7 files changed, 18 insertions(+), 16 deletions(-) diff --git a/services/api-server/src/simcore_service_api_server/services/director_v2.py b/services/api-server/src/simcore_service_api_server/services/director_v2.py index 8d79ad66d75..6f072eb6657 100644 --- a/services/api-server/src/simcore_service_api_server/services/director_v2.py +++ b/services/api-server/src/simcore_service_api_server/services/director_v2.py @@ -93,7 +93,7 @@ async def create_computation( }, ) response.raise_for_status() - task: ComputationTaskGet = ComputationTaskGet.parse_raw(response.text) + task: ComputationTaskGet = ComputationTaskGet.model_validate_json(response.text) return task @_exception_mapper({}) @@ -129,7 +129,7 @@ async def start_computation( }, ) response.raise_for_status() - task: ComputationTaskGet = ComputationTaskGet.parse_raw(response.text) + task: ComputationTaskGet = ComputationTaskGet.model_validate_json(response.text) return task @_exception_mapper({status.HTTP_404_NOT_FOUND: JobNotFoundError}) @@ -143,7 +143,7 @@ async def get_computation( }, ) response.raise_for_status() - task: ComputationTaskGet = ComputationTaskGet.parse_raw(response.text) + task: ComputationTaskGet = ComputationTaskGet.model_validate_json(response.text) return task @_exception_mapper({status.HTTP_404_NOT_FOUND: JobNotFoundError}) @@ -157,7 +157,7 @@ async def stop_computation( }, ) response.raise_for_status() - task: ComputationTaskGet = ComputationTaskGet.parse_raw(response.text) + task: ComputationTaskGet = ComputationTaskGet.model_validate_json(response.text) return task @_exception_mapper({status.HTTP_404_NOT_FOUND: JobNotFoundError}) diff --git a/services/api-server/src/simcore_service_api_server/services/webserver.py b/services/api-server/src/simcore_service_api_server/services/webserver.py index d9448ded94f..5a2326258af 100644 --- a/services/api-server/src/simcore_service_api_server/services/webserver.py +++ b/services/api-server/src/simcore_service_api_server/services/webserver.py @@ -102,7 +102,7 @@ def _get_lrt_urls(lrt_response: httpx.Response): # WARNING: this function is patched in patch_lrt_response_urls fixture - data = Envelope[TaskGet].parse_raw(lrt_response.text).data + data = Envelope[TaskGet].model_validate_json(lrt_response.text).data assert data is not None # nosec return data.status_href, data.result_href @@ -207,7 +207,7 @@ async def _page_projects( ) resp.raise_for_status() - return Page[ProjectGet].parse_raw(resp.text) + return Page[ProjectGet].model_validate_json(resp.text) async def _wait_for_long_running_task_results(self, lrt_response: httpx.Response): status_url, result_url = _get_lrt_urls(lrt_response) @@ -224,7 +224,9 @@ async def _wait_for_long_running_task_results(self, lrt_response: httpx.Response url=status_url, cookies=self.session_cookies ) get_response.raise_for_status() - task_status = Envelope[TaskStatus].parse_raw(get_response.text).data + task_status = ( + Envelope[TaskStatus].model_validate_json(get_response.text).data + ) assert task_status is not None # nosec if not task_status.done: msg = "Timed out creating project. TIP: Try again, or contact oSparc support if this is happening repeatedly" diff --git a/services/api-server/tests/unit/conftest.py b/services/api-server/tests/unit/conftest.py index 74ba73e2ce4..7da1d115020 100644 --- a/services/api-server/tests/unit/conftest.py +++ b/services/api-server/tests/unit/conftest.py @@ -450,7 +450,7 @@ def patch_lrt_response_urls(mocker: MockerFixture): def _() -> MagicMock: def _get_lrt_urls(lrt_response: httpx.Response): # NOTE: this function is needed to mock - data = Envelope[TaskGet].parse_raw(lrt_response.text).data + data = Envelope[TaskGet].model_validate_json(lrt_response.text).data assert data is not None # nosec def _patch(href): diff --git a/services/api-server/tests/unit/test_cli.py b/services/api-server/tests/unit/test_cli.py index 5ae5ca4c10f..febeca14b1f 100644 --- a/services/api-server/tests/unit/test_cli.py +++ b/services/api-server/tests/unit/test_cli.py @@ -29,7 +29,7 @@ def test_cli_list_settings(cli_runner: CliRunner, app_environment: EnvVarsDict): assert result.exit_code == os.EX_OK, result.output print(result.output) - settings = ApplicationSettings.parse_raw(result.output) + settings = ApplicationSettings.model_validate_json(result.output) assert settings == ApplicationSettings.create_from_envs() diff --git a/services/api-server/tests/unit/test_exceptions.py b/services/api-server/tests/unit/test_exceptions.py index 48d75a38928..6949e72d088 100644 --- a/services/api-server/tests/unit/test_exceptions.py +++ b/services/api-server/tests/unit/test_exceptions.py @@ -67,7 +67,7 @@ async def test_raised_http_exception(client: httpx.AsyncClient): assert response.status_code == status.HTTP_503_SERVICE_UNAVAILABLE - got = ErrorGet.parse_raw(response.text) + got = ErrorGet.model_validate_json(response.text) assert got.errors == ["fail message"] @@ -78,7 +78,7 @@ async def test_fastapi_http_exception_respond_with_error_model( assert response.status_code == status.HTTP_404_NOT_FOUND - got = ErrorGet.parse_raw(response.text) + got = ErrorGet.model_validate_json(response.text) assert got.errors == [HTTPStatus(response.status_code).phrase] @@ -87,7 +87,7 @@ async def test_custom_error_handlers(client: httpx.AsyncClient): assert response.status_code == status.HTTP_424_FAILED_DEPENDENCY - got = ErrorGet.parse_raw(response.text) + got = ErrorGet.model_validate_json(response.text) assert got.errors == [f"{MissingWalletError(job_id=123)}"] diff --git a/services/api-server/tests/unit/test_services_rabbitmq.py b/services/api-server/tests/unit/test_services_rabbitmq.py index 6f2f2ca546f..77116e711eb 100644 --- a/services/api-server/tests/unit/test_services_rabbitmq.py +++ b/services/api-server/tests/unit/test_services_rabbitmq.py @@ -378,7 +378,7 @@ async def _log_publisher(): collected_messages: list[str] = [] async for log in log_streamer_with_distributor.log_generator(): - job_log: JobLog = JobLog.parse_raw(log) + job_log: JobLog = JobLog.model_validate_json(log) assert len(job_log.messages) == 1 assert job_log.job_id == project_id collected_messages.append(job_log.messages[0]) @@ -458,7 +458,7 @@ async def test_log_generator(mocker: MockFixture, faker: Faker): collected_logs: list[str] = [] async for log in log_streamer.log_generator(): - job_log = JobLog.parse_raw(log) + job_log = JobLog.model_validate_json(log) assert len(job_log.messages) == 1 collected_logs.append(job_log.messages[0]) diff --git a/services/api-server/tests/unit/test_utils_http_calls_capture.py b/services/api-server/tests/unit/test_utils_http_calls_capture.py index 536c42f36e5..64422f24f8a 100644 --- a/services/api-server/tests/unit/test_utils_http_calls_capture.py +++ b/services/api-server/tests/unit/test_utils_http_calls_capture.py @@ -89,7 +89,7 @@ async def test_capture_http_dynamic_call( assert found.groupdict() == {"resouce_uid": sample_uid} # subs_json = re.sub(f"{resource_uid}", pattern, captured.json()) - # new_capture = HttpApiCallCaptureModel.parse_raw(subs_json) + # new_capture = HttpApiCallCaptureModel.model_validate_json(subs_json) # MOCK with respx.mock( @@ -140,6 +140,6 @@ def test_template_capture(project_tests_dir: Path, faker: Faker): # loads parametrized capture # replace in response and solve - capture = HttpApiCallCaptureModel.parse_raw(template.render(context)) + capture = HttpApiCallCaptureModel.model_validate_json(template.render(context)) print(capture.json(indent=1)) assert capture.path == url_path From 6c2c04473586bc617f2808ee3236179e3eff5cf6 Mon Sep 17 00:00:00 2001 From: Giancarlo Romeo Date: Tue, 15 Oct 2024 15:11:29 +0200 Subject: [PATCH 11/37] continue fixing --- .../src/simcore_service_api_server/api/routes/studies.py | 2 +- .../src/simcore_service_api_server/models/basic_types.py | 1 - .../tests/unit/_with_db/test_core_settings__with_db.py | 2 +- .../tests/unit/api_solvers/test_api_routers_solvers.py | 2 +- services/api-server/tests/unit/test_core_settings.py | 2 +- .../tests/unit/test_services_solver_job_models_converters.py | 2 +- .../api-server/tests/unit/test_utils_http_calls_capture.py | 4 ++-- 7 files changed, 7 insertions(+), 8 deletions(-) diff --git a/services/api-server/src/simcore_service_api_server/api/routes/studies.py b/services/api-server/src/simcore_service_api_server/api/routes/studies.py index c5e9c010368..392acd8c72a 100644 --- a/services/api-server/src/simcore_service_api_server/api/routes/studies.py +++ b/services/api-server/src/simcore_service_api_server/api/routes/studies.py @@ -29,7 +29,7 @@ def _create_study_from_project(project: ProjectGet) -> Study: assert isinstance(project, ProjectGet) # nosec - return Study.construct( + return Study.model_construct( uid=project.uuid, title=project.name, description=project.description, diff --git a/services/api-server/src/simcore_service_api_server/models/basic_types.py b/services/api-server/src/simcore_service_api_server/models/basic_types.py index 2331df0d300..8e0c4c79af2 100644 --- a/services/api-server/src/simcore_service_api_server/models/basic_types.py +++ b/services/api-server/src/simcore_service_api_server/models/basic_types.py @@ -1,6 +1,5 @@ from typing import Annotated, TypeAlias -from common_library.pydantic_basic_types import ConstrainedStr from fastapi.responses import StreamingResponse from models_library.basic_regex import SIMPLE_VERSION_RE from pydantic import StringConstraints diff --git a/services/api-server/tests/unit/_with_db/test_core_settings__with_db.py b/services/api-server/tests/unit/_with_db/test_core_settings__with_db.py index f61c1ae4153..78b9ae20b7b 100644 --- a/services/api-server/tests/unit/_with_db/test_core_settings__with_db.py +++ b/services/api-server/tests/unit/_with_db/test_core_settings__with_db.py @@ -12,7 +12,7 @@ def test_unit_with_db_app_environment(app_environment: EnvVarsDict): settings = ApplicationSettings.create_from_envs() - print("captured settings: \n", settings.json(indent=2)) + print("captured settings: \n", settings.model_dump_json(indent=2)) assert settings.SC_BOOT_MODE == BootModeEnum.PRODUCTION assert settings.log_level == logging.DEBUG diff --git a/services/api-server/tests/unit/api_solvers/test_api_routers_solvers.py b/services/api-server/tests/unit/api_solvers/test_api_routers_solvers.py index ebdcfc59950..d4a6cf80a76 100644 --- a/services/api-server/tests/unit/api_solvers/test_api_routers_solvers.py +++ b/services/api-server/tests/unit/api_solvers/test_api_routers_solvers.py @@ -39,7 +39,7 @@ async def test_list_solvers( for item in data: solver = Solver(**item) - print(solver.json(indent=1, exclude_unset=True)) + print(solver.model_dump_json(indent=1, exclude_unset=True)) # use link to get the same solver assert solver.url diff --git a/services/api-server/tests/unit/test_core_settings.py b/services/api-server/tests/unit/test_core_settings.py index fbb9f875b65..feb5052ab0f 100644 --- a/services/api-server/tests/unit/test_core_settings.py +++ b/services/api-server/tests/unit/test_core_settings.py @@ -37,4 +37,4 @@ def app_environment( def test_unit_app_environment(app_environment: EnvVarsDict): assert app_environment settings = ApplicationSettings.create_from_envs() - print("captured settings: \n", settings.json(indent=2)) + print("captured settings: \n", settings.model_dump_json(indent=2)) diff --git a/services/api-server/tests/unit/test_services_solver_job_models_converters.py b/services/api-server/tests/unit/test_services_solver_job_models_converters.py index 3141a3a9aee..892bb0fcf24 100644 --- a/services/api-server/tests/unit/test_services_solver_job_models_converters.py +++ b/services/api-server/tests/unit/test_services_solver_job_models_converters.py @@ -102,7 +102,7 @@ def test_job_to_node_inputs_conversion(): NodeInputs = create_model("NodeInputs", __root__=(dict[str, InputTypes], ...)) print(NodeInputs.model_validate(got_node_inputs).model_dump_json(indent=2)) - print(got_job_inputs.json(indent=2)) + print(got_job_inputs.model_dump_json(indent=2)) assert got_job_inputs == job_inputs assert got_node_inputs == node_inputs diff --git a/services/api-server/tests/unit/test_utils_http_calls_capture.py b/services/api-server/tests/unit/test_utils_http_calls_capture.py index 64422f24f8a..c11ec04411d 100644 --- a/services/api-server/tests/unit/test_utils_http_calls_capture.py +++ b/services/api-server/tests/unit/test_utils_http_calls_capture.py @@ -32,7 +32,7 @@ async def test_capture_http_call( response, name="get_json", enhance_from_openapi_specs=False ) - print(captured.json(indent=1)) + print(captured.model_dump_json(indent=1)) # MOCK with respx.mock( @@ -141,5 +141,5 @@ def test_template_capture(project_tests_dir: Path, faker: Faker): # loads parametrized capture # replace in response and solve capture = HttpApiCallCaptureModel.model_validate_json(template.render(context)) - print(capture.json(indent=1)) + print(capture.model_dump_json(indent=1)) assert capture.path == url_path From 21d5906749f8231f01a3529b723bdd6ab45eb89e Mon Sep 17 00:00:00 2001 From: Giancarlo Romeo Date: Tue, 15 Oct 2024 16:50:44 +0200 Subject: [PATCH 12/37] fix url type --- .../tests/unit/api_solvers/test_api_routers_solvers_jobs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/api-server/tests/unit/api_solvers/test_api_routers_solvers_jobs.py b/services/api-server/tests/unit/api_solvers/test_api_routers_solvers_jobs.py index c9b9b8e9234..1bb9f077954 100644 --- a/services/api-server/tests/unit/api_solvers/test_api_routers_solvers_jobs.py +++ b/services/api-server/tests/unit/api_solvers/test_api_routers_solvers_jobs.py @@ -131,7 +131,7 @@ def test_download_presigned_link( presigned_download_link: AnyUrl, tmp_path: Path, project_id: str, node_id: str ): """Cheks that the generation of presigned_download_link works as expected""" - r = httpx.get(presigned_download_link) + r = httpx.get(f"{presigned_download_link}") ## pprint(dict(r.headers)) # r.headers looks like: # { From 04cd72836edb554aabe5b9c026fd5b3bbd3f48ab Mon Sep 17 00:00:00 2001 From: Giancarlo Romeo Date: Wed, 16 Oct 2024 10:42:51 +0200 Subject: [PATCH 13/37] continue upgrade --- .../src/simcore_service_api_server/models/schemas/jobs.py | 5 +++-- .../tests/unit/test_services_solver_job_models_converters.py | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/services/api-server/src/simcore_service_api_server/models/schemas/jobs.py b/services/api-server/src/simcore_service_api_server/models/schemas/jobs.py index 7cc16e6503e..eff1161cb75 100644 --- a/services/api-server/src/simcore_service_api_server/models/schemas/jobs.py +++ b/services/api-server/src/simcore_service_api_server/models/schemas/jobs.py @@ -18,6 +18,7 @@ StrictInt, TypeAdapter, ValidationError, + ValidationInfo, field_validator, ) from servicelib.logging_utils import LogLevelInt, LogMessageStr @@ -194,8 +195,8 @@ class Job(BaseModel): @field_validator("name", mode="before") @classmethod - def check_name(cls, v, values): - _id = str(values["id"]) + def check_name(cls, v, info: ValidationInfo): + _id = str(info.data["id"]) if not v.endswith(f"/{_id}"): msg = f"Resource name [{v}] and id [{_id}] do not match" raise ValueError(msg) diff --git a/services/api-server/tests/unit/test_services_solver_job_models_converters.py b/services/api-server/tests/unit/test_services_solver_job_models_converters.py index 892bb0fcf24..1016096dce5 100644 --- a/services/api-server/tests/unit/test_services_solver_job_models_converters.py +++ b/services/api-server/tests/unit/test_services_solver_job_models_converters.py @@ -6,7 +6,7 @@ from faker import Faker from models_library.projects import Project from models_library.projects_nodes import InputsDict, InputTypes, SimCoreFileLink -from pydantic import TypeAdapter, create_model +from pydantic import RootModel, TypeAdapter, create_model from simcore_service_api_server.models.schemas.files import File from simcore_service_api_server.models.schemas.jobs import ArgumentTypes, Job, JobInputs from simcore_service_api_server.models.schemas.solvers import Solver @@ -100,7 +100,7 @@ def test_job_to_node_inputs_conversion(): got_node_inputs = create_node_inputs_from_job_inputs(inputs=job_inputs) got_job_inputs = create_job_inputs_from_node_inputs(inputs=node_inputs) - NodeInputs = create_model("NodeInputs", __root__=(dict[str, InputTypes], ...)) + NodeInputs = create_model("NodeInputs", __base__=RootModel[dict[str, InputTypes]]) print(NodeInputs.model_validate(got_node_inputs).model_dump_json(indent=2)) print(got_job_inputs.model_dump_json(indent=2)) From ba3b868abcf7cfc32b72eaf017e37c147a28ceba Mon Sep 17 00:00:00 2001 From: Pedro Crespo-Valero <32402063+pcrespov@users.noreply.github.com> Date: Wed, 16 Oct 2024 14:51:40 +0200 Subject: [PATCH 14/37] =?UTF-8?q?=E2=AC=86=EF=B8=8F=20=E2=99=BB=EF=B8=8F?= =?UTF-8?q?=20Upgrade=20pagination=20customisation=20in=20api-server=20(#6?= =?UTF-8?q?545)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- services/api-server/requirements/_base.txt | 7 ++-- .../api-server/requirements/constraints.txt | 28 --------------- .../models/pagination.py | 36 +++++++++++-------- 3 files changed, 23 insertions(+), 48 deletions(-) diff --git a/services/api-server/requirements/_base.txt b/services/api-server/requirements/_base.txt index cfdf6a1a2fc..f57181ef299 100644 --- a/services/api-server/requirements/_base.txt +++ b/services/api-server/requirements/_base.txt @@ -156,14 +156,11 @@ fastapi==0.114.2 # -c requirements/../../../requirements/constraints.txt # -r requirements/../../../packages/service-library/requirements/_fastapi.in # -r requirements/_base.in - # fastapi-pagination # prometheus-fastapi-instrumentator fastapi-cli==0.0.5 # via fastapi -fastapi-pagination==0.12.17 - # via - # -c requirements/./constraints.txt - # -r requirements/_base.in +fastapi-pagination==0.12.31 + # via -r requirements/_base.in faststream==0.5.10 # via # -r requirements/../../../packages/service-library/requirements/_base.in diff --git a/services/api-server/requirements/constraints.txt b/services/api-server/requirements/constraints.txt index cfbd5e8be2a..6247b000156 100644 --- a/services/api-server/requirements/constraints.txt +++ b/services/api-server/requirements/constraints.txt @@ -40,31 +40,3 @@ aws-sam-translator<1.56.0 # # aws-sam-translator<1.55.0 (from -c ./constraints.txt (line 32)) # # aws-sam-translator>=1.57.0 (from cfn-lint==0.72.10->-c ./constraints.txt (line 33)) cfn-lint<0.72.1 - - - -# -# .venv/lib/python3.10/site-packages/fastapi_pagination/api.py:352: in _update_route -# get_parameterless_sub_dependant( -# .venv/lib/python3.10/site-packages/fastapi/dependencies/utils.py:136: in get_parameterless_sub_dependant -# return get_sub_dependant(depends=depends, dependency=depends.dependency, path=path) -# .venv/lib/python3.10/site-packages/fastapi/dependencies/utils.py:159: in get_sub_dependant -# sub_dependant = get_dependant( -# .venv/lib/python3.10/site-packages/fastapi/dependencies/utils.py:310: in get_dependant -# sub_dependant = get_param_sub_dependant( -# .venv/lib/python3.10/site-packages/fastapi/dependencies/utils.py:123: in get_param_sub_dependant -# return get_sub_dependant( -# .venv/lib/python3.10/site-packages/fastapi/dependencies/utils.py:159: in get_sub_dependant -# sub_dependant = get_dependant( -# .venv/lib/python3.10/site-packages/fastapi/dependencies/utils.py:331: in get_dependant -# add_param_to_fields(field=param_field, dependant=dependant) -# _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ - -# def add_param_to_fields(*, field: ModelField, dependant: Dependant) -> None: -# field_info = cast(params.Param, field.field_info) -# > if field_info.in_ == params.ParamTypes.path: -# E AttributeError: 'FieldInfo' object has no attribute 'in_' - -# .venv/lib/python3.10/site-packages/fastapi/dependencies/utils.py:500: AttributeError - -fastapi-pagination<=0.12.17 diff --git a/services/api-server/src/simcore_service_api_server/models/pagination.py b/services/api-server/src/simcore_service_api_server/models/pagination.py index f35969592cc..8fdf0b985dc 100644 --- a/services/api-server/src/simcore_service_api_server/models/pagination.py +++ b/services/api-server/src/simcore_service_api_server/models/pagination.py @@ -9,29 +9,35 @@ from collections.abc import Sequence from typing import Generic, TypeAlias, TypeVar -from fastapi_pagination.limit_offset import LimitOffsetParams -from fastapi_pagination.links.limit_offset import ( - LimitOffsetPage as _FastApiLimitOffsetPage, -) +from fastapi import Query +from fastapi_pagination.customization import CustomizedPage, UseName, UseParamsFields +from fastapi_pagination.limit_offset import LimitOffsetParams as _LimitOffsetParams +from fastapi_pagination.links import LimitOffsetPage as _LimitOffsetPage from models_library.rest_pagination import ( DEFAULT_NUMBER_OF_ITEMS_PER_PAGE, MAXIMUM_NUMBER_OF_ITEMS_PER_PAGE, ) from models_library.utils.pydantic_tools_extension import FieldNotRequired -from pydantic import BaseModel, ConfigDict, Field, NonNegativeInt, field_validator +from pydantic import BaseModel, ConfigDict, NonNegativeInt, field_validator T = TypeVar("T") -# NOTE: same pagination limits and defaults as web-server -Page = _FastApiLimitOffsetPage.with_custom_options( - limit=Field( - DEFAULT_NUMBER_OF_ITEMS_PER_PAGE, ge=1, le=MAXIMUM_NUMBER_OF_ITEMS_PER_PAGE - ) -) -# NOTE: Renamed to make shorter clients name models -Page.__name__ = "Page" - -PaginationParams: TypeAlias = LimitOffsetParams +Page = CustomizedPage[ + _LimitOffsetPage[T], + # Customizes the default and maximum to fit those of the web-server. It simplifies interconnection + UseParamsFields( + limit=Query( + DEFAULT_NUMBER_OF_ITEMS_PER_PAGE, + ge=1, + le=MAXIMUM_NUMBER_OF_ITEMS_PER_PAGE, + description="Page size limit", + ) + ), + # Renames class for the openapi.json to make the python-client's name models shorter + UseName(name="Page"), +] + +PaginationParams: TypeAlias = _LimitOffsetParams class OnePage(BaseModel, Generic[T]): From 29f67ff845289026f7f16c97255825453672539f Mon Sep 17 00:00:00 2001 From: Giancarlo Romeo Date: Mon, 21 Oct 2024 13:21:39 +0200 Subject: [PATCH 15/37] fix tests --- .../services/catalog.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/services/api-server/src/simcore_service_api_server/services/catalog.py b/services/api-server/src/simcore_service_api_server/services/catalog.py index d3ffad54be6..0a52d65c486 100644 --- a/services/api-server/src/simcore_service_api_server/services/catalog.py +++ b/services/api-server/src/simcore_service_api_server/services/catalog.py @@ -5,6 +5,7 @@ from dataclasses import dataclass from functools import partial from operator import attrgetter +from typing import Final from fastapi import FastAPI, status from models_library.emails import LowerCaseEmailStr @@ -68,11 +69,11 @@ def to_solver(self) -> Solver: _exception_mapper = partial(service_exception_mapper, "Catalog") -_TRUNCATED_CATALOG_SERVICE_OUT_ADAPTER: TypeAdapter[ - TruncatedCatalogServiceOut +TruncatedCatalogServiceOutAdapter: Final[ + TypeAdapter[TruncatedCatalogServiceOut] ] = TypeAdapter(TruncatedCatalogServiceOut) -_LIST_OF_TRUNCATED_CATALOG_SERVICE_OUT_ADAPTER: TypeAdapter[ - list[TruncatedCatalogServiceOut] +TruncatedCatalogServiceOutListAdapter: Final[ + TypeAdapter[list[TruncatedCatalogServiceOut]] ] = TypeAdapter(list[TruncatedCatalogServiceOut]) @@ -110,8 +111,8 @@ async def list_solvers( ] = await asyncio.get_event_loop().run_in_executor( None, _parse_response, - _LIST_OF_TRUNCATED_CATALOG_SERVICE_OUT_ADAPTER, - response.text, + TruncatedCatalogServiceOutListAdapter, + response, ) solvers = [] for service in services: @@ -152,7 +153,7 @@ async def get_service( service: ( TruncatedCatalogServiceOut ) = await asyncio.get_event_loop().run_in_executor( - None, _parse_response, _TRUNCATED_CATALOG_SERVICE_OUT_ADAPTER, response.text + None, _parse_response, TruncatedCatalogServiceOutAdapter, response ) assert ( # nosec service.service_type == ServiceType.COMPUTATIONAL From b06e1711c69c4855cc150d700877c4a4475fcc05 Mon Sep 17 00:00:00 2001 From: Giancarlo Romeo Date: Mon, 21 Oct 2024 14:21:19 +0200 Subject: [PATCH 16/37] fix pagination --- .../src/simcore_service_api_server/api/routes/solvers.py | 2 +- .../src/simcore_service_api_server/models/pagination.py | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/services/api-server/src/simcore_service_api_server/api/routes/solvers.py b/services/api-server/src/simcore_service_api_server/api/routes/solvers.py index 926b4b10b50..c172000bd9e 100644 --- a/services/api-server/src/simcore_service_api_server/api/routes/solvers.py +++ b/services/api-server/src/simcore_service_api_server/api/routes/solvers.py @@ -257,7 +257,7 @@ async def list_solver_ports( product_name=product_name, ) - return OnePage[SolverPort](items=ports) + return OnePage[SolverPort].model_validate(dict(items=ports)) @router.get( diff --git a/services/api-server/src/simcore_service_api_server/models/pagination.py b/services/api-server/src/simcore_service_api_server/models/pagination.py index 8fdf0b985dc..5ce4f0d688c 100644 --- a/services/api-server/src/simcore_service_api_server/models/pagination.py +++ b/services/api-server/src/simcore_service_api_server/models/pagination.py @@ -18,7 +18,7 @@ MAXIMUM_NUMBER_OF_ITEMS_PER_PAGE, ) from models_library.utils.pydantic_tools_extension import FieldNotRequired -from pydantic import BaseModel, ConfigDict, NonNegativeInt, field_validator +from pydantic import BaseModel, ConfigDict, NonNegativeInt, ValidationInfo, field_validator T = TypeVar("T") @@ -50,12 +50,12 @@ class OnePage(BaseModel, Generic[T]): """ items: Sequence[T] - total: NonNegativeInt = FieldNotRequired() + total: NonNegativeInt = FieldNotRequired(validate_default=True) @field_validator("total", mode="before") @classmethod - def check_total(cls, v, values): - items = values["items"] + def _check_total(cls, v, info: ValidationInfo): + items = info.data.get("items", []) if v is None: return len(items) From a974048b2fe03b7c4ec5de3e77efb2316b20943c Mon Sep 17 00:00:00 2001 From: Giancarlo Romeo Date: Mon, 21 Oct 2024 14:59:24 +0200 Subject: [PATCH 17/37] fix url --- .../tests/unit/api_solvers/test_api_routers_solvers_jobs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/api-server/tests/unit/api_solvers/test_api_routers_solvers_jobs.py b/services/api-server/tests/unit/api_solvers/test_api_routers_solvers_jobs.py index 1bb9f077954..4901359b91f 100644 --- a/services/api-server/tests/unit/api_solvers/test_api_routers_solvers_jobs.py +++ b/services/api-server/tests/unit/api_solvers/test_api_routers_solvers_jobs.py @@ -119,7 +119,7 @@ def mocked_directorv2_service_api( json=[ { "task_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "download_link": presigned_download_link, + "download_link": f"{presigned_download_link}", } ], ) From df114891175cfaefd41bc2235a87aece3087e99c Mon Sep 17 00:00:00 2001 From: Giancarlo Romeo Date: Mon, 21 Oct 2024 15:25:03 +0200 Subject: [PATCH 18/37] fix validation --- .../src/simcore_service_api_server/services/director_v2.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/api-server/src/simcore_service_api_server/services/director_v2.py b/services/api-server/src/simcore_service_api_server/services/director_v2.py index 6f072eb6657..65ee00bfe14 100644 --- a/services/api-server/src/simcore_service_api_server/services/director_v2.py +++ b/services/api-server/src/simcore_service_api_server/services/director_v2.py @@ -187,7 +187,7 @@ async def get_computation_logs( response.raise_for_status() log_links: list[LogLink] = [] - for r in TypeAdapter(list[TaskLogFileGet]).validate_python( + for r in TypeAdapter(list[TaskLogFileGet]).validate_json( response.text or "[]" ): if r.download_link: From 8dd57a7d4c12ed05eb91747ea2820b1dd5e479c9 Mon Sep 17 00:00:00 2001 From: Giancarlo Romeo Date: Mon, 21 Oct 2024 15:35:36 +0200 Subject: [PATCH 19/37] fix frozen field --- .../src/models_library/api_schemas_webserver/projects.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/models-library/src/models_library/api_schemas_webserver/projects.py b/packages/models-library/src/models_library/api_schemas_webserver/projects.py index 9066d0f6f6d..92fdf37317f 100644 --- a/packages/models-library/src/models_library/api_schemas_webserver/projects.py +++ b/packages/models-library/src/models_library/api_schemas_webserver/projects.py @@ -10,7 +10,7 @@ from common_library.pydantic_basic_types import LongTruncatedStr, ShortTruncatedStr from models_library.folders import FolderID from models_library.workspaces import WorkspaceID -from pydantic import Field, HttpUrl, field_validator +from pydantic import ConfigDict, Field, HttpUrl, field_validator from ..api_schemas_long_running_tasks.tasks import TaskGet from ..emails import LowerCaseEmailStr @@ -82,6 +82,10 @@ class ProjectGet(OutputSchema): workspace_id: WorkspaceID | None folder_id: FolderID | None + model_config = ConfigDict( + frozen=False + ) + _empty_description = field_validator("description", mode="before")( none_to_empty_str_pre_validator ) From e01f8c121fdcd7cb271e9e46b4e32607e6452f2f Mon Sep 17 00:00:00 2001 From: Giancarlo Romeo Date: Mon, 21 Oct 2024 15:54:43 +0200 Subject: [PATCH 20/37] fix url --- .../tests/unit/api_solvers/test_api_routers_solvers_jobs.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/services/api-server/tests/unit/api_solvers/test_api_routers_solvers_jobs.py b/services/api-server/tests/unit/api_solvers/test_api_routers_solvers_jobs.py index 4901359b91f..a4bd5c9b49b 100644 --- a/services/api-server/tests/unit/api_solvers/test_api_routers_solvers_jobs.py +++ b/services/api-server/tests/unit/api_solvers/test_api_routers_solvers_jobs.py @@ -191,9 +191,9 @@ async def test_solver_logs( # was a re-direction resp0 = resp.history[0] assert resp0.status_code == status.HTTP_307_TEMPORARY_REDIRECT - assert resp0.headers["location"] == presigned_download_link + assert resp0.headers["location"] == f"{presigned_download_link}" - assert resp.url == presigned_download_link + assert f"{resp.url}" == f"{presigned_download_link}" pprint(dict(resp.headers)) # noqa: T203 From 4aae323df5b50b47bb0423076fdce776918b4b79 Mon Sep 17 00:00:00 2001 From: Giancarlo Romeo Date: Mon, 21 Oct 2024 16:15:19 +0200 Subject: [PATCH 21/37] continue fixing --- .../src/models_library/api_schemas_webserver/projects.py | 6 +++--- .../src/simcore_service_api_server/services/catalog.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/models-library/src/models_library/api_schemas_webserver/projects.py b/packages/models-library/src/models_library/api_schemas_webserver/projects.py index 92fdf37317f..82059cc4b48 100644 --- a/packages/models-library/src/models_library/api_schemas_webserver/projects.py +++ b/packages/models-library/src/models_library/api_schemas_webserver/projects.py @@ -78,9 +78,9 @@ class ProjectGet(OutputSchema): ui: EmptyModel | StudyUI | None = None quality: dict[str, Any] = {} dev: dict | None = None - permalink: ProjectPermalink = FieldNotRequired() - workspace_id: WorkspaceID | None - folder_id: FolderID | None + permalink: ProjectPermalink | None = FieldNotRequired() + workspace_id: WorkspaceID | None = None + folder_id: FolderID | None = None model_config = ConfigDict( frozen=False diff --git a/services/api-server/src/simcore_service_api_server/services/catalog.py b/services/api-server/src/simcore_service_api_server/services/catalog.py index 0a52d65c486..2bbc741b5f2 100644 --- a/services/api-server/src/simcore_service_api_server/services/catalog.py +++ b/services/api-server/src/simcore_service_api_server/services/catalog.py @@ -43,7 +43,7 @@ class TruncatedCatalogServiceOut(ServiceMetaDataPublished): that asks only what is needed. """ - owner: LowerCaseEmailStr | None + owner: LowerCaseEmailStr | None = None model_config = ConfigDict(extra="ignore") # Converters From 00c41649a532bc043048c5623c6bf3e740d80521 Mon Sep 17 00:00:00 2001 From: Giancarlo Romeo Date: Tue, 22 Oct 2024 09:45:06 +0200 Subject: [PATCH 22/37] continue fixing --- .../helpers/httpx_calls_capture_parameters.py | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/pytest-simcore/src/pytest_simcore/helpers/httpx_calls_capture_parameters.py b/packages/pytest-simcore/src/pytest_simcore/helpers/httpx_calls_capture_parameters.py index 25f2abc8cd0..89c5c20846c 100644 --- a/packages/pytest-simcore/src/pytest_simcore/helpers/httpx_calls_capture_parameters.py +++ b/packages/pytest-simcore/src/pytest_simcore/helpers/httpx_calls_capture_parameters.py @@ -8,13 +8,13 @@ class CapturedParameterSchema(BaseModel): title: str | None = None type_: Literal["str", "int", "float", "bool"] | None = Field(None, alias="type") - pattern: str | None + pattern: str | None = None format_: Literal["uuid"] | None = Field(None, alias="format") - exclusiveMinimum: bool | None - minimum: int | None - anyOf: list["CapturedParameterSchema"] | None - allOf: list["CapturedParameterSchema"] | None - oneOf: list["CapturedParameterSchema"] | None + exclusiveMinimum: bool | None = None + minimum: int | None = None + anyOf: list["CapturedParameterSchema"] | None = None + allOf: list["CapturedParameterSchema"] | None = None + oneOf: list["CapturedParameterSchema"] | None = None class Config: validate_always = True @@ -34,12 +34,12 @@ def preprocess_type_(cls, val): @model_validator(mode="after") @classmethod def check_compatibility(cls, values): - type_ = values.get("type_") - pattern = values.get("pattern") - format_ = values.get("format_") - anyOf = values.get("anyOf") - allOf = values.get("allOf") - oneOf = values.get("oneOf") + type_ = values.type_ + pattern = values.pattern + format_ = values.format_ + anyOf = values.anyOf + allOf = values.allOf + oneOf = values.oneOf if not any([type_, oneOf, anyOf, allOf]): type_ = "str" # this default is introduced because we have started using json query params in the webserver values["type_"] = type_ From 2331b89b0c7ca47db001110038554efda90ba013 Mon Sep 17 00:00:00 2001 From: Giancarlo Romeo Date: Tue, 22 Oct 2024 11:02:22 +0200 Subject: [PATCH 23/37] continue fixing --- .../models-library/src/models_library/app_diagnostics.py | 8 ++++---- .../helpers/httpx_calls_capture_parameters.py | 4 ++-- .../src/simcore_service_api_server/core/settings.py | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/models-library/src/models_library/app_diagnostics.py b/packages/models-library/src/models_library/app_diagnostics.py index ce8c9331eae..b1d19f49f72 100644 --- a/packages/models-library/src/models_library/app_diagnostics.py +++ b/packages/models-library/src/models_library/app_diagnostics.py @@ -1,6 +1,6 @@ -from typing import Any +from typing import Annotated, Any -from pydantic import AnyUrl, BaseModel, Field +from pydantic import AfterValidator, AnyUrl, BaseModel, Field class AppStatusCheck(BaseModel): @@ -15,11 +15,11 @@ class AppStatusCheck(BaseModel): description="Client sessions info. If single session per app, then is denoted as main", ) - url: AnyUrl | None = Field( + url: Annotated[AnyUrl, AfterValidator(str)] | None = Field( default=None, description="Link to current resource", ) - diagnostics_url: AnyUrl | None = Field( + diagnostics_url: Annotated[AnyUrl, AfterValidator(str)] | None = Field( default=None, description="Link to diagnostics report sub-resource. This MIGHT take some time to compute", ) diff --git a/packages/pytest-simcore/src/pytest_simcore/helpers/httpx_calls_capture_parameters.py b/packages/pytest-simcore/src/pytest_simcore/helpers/httpx_calls_capture_parameters.py index 89c5c20846c..5ebde2fb9d5 100644 --- a/packages/pytest-simcore/src/pytest_simcore/helpers/httpx_calls_capture_parameters.py +++ b/packages/pytest-simcore/src/pytest_simcore/helpers/httpx_calls_capture_parameters.py @@ -11,7 +11,7 @@ class CapturedParameterSchema(BaseModel): pattern: str | None = None format_: Literal["uuid"] | None = Field(None, alias="format") exclusiveMinimum: bool | None = None - minimum: int | None = None + minimum: int | float | None = None anyOf: list["CapturedParameterSchema"] | None = None allOf: list["CapturedParameterSchema"] | None = None oneOf: list["CapturedParameterSchema"] | None = None @@ -42,7 +42,7 @@ def check_compatibility(cls, values): oneOf = values.oneOf if not any([type_, oneOf, anyOf, allOf]): type_ = "str" # this default is introduced because we have started using json query params in the webserver - values["type_"] = type_ + values.type_ = type_ if type_ != "str" and any([pattern, format_]): msg = f"For {type_=} both {pattern=} and {format_=} must be None" raise ValueError(msg) diff --git a/services/api-server/src/simcore_service_api_server/core/settings.py b/services/api-server/src/simcore_service_api_server/core/settings.py index e6c88a10f17..0c03b0160c3 100644 --- a/services/api-server/src/simcore_service_api_server/core/settings.py +++ b/services/api-server/src/simcore_service_api_server/core/settings.py @@ -78,7 +78,7 @@ def _validate_loglevel(cls, value) -> str: class ApplicationSettings(BasicSettings): # DOCKER BOOT - SC_BOOT_MODE: BootModeEnum | None + SC_BOOT_MODE: BootModeEnum | None = None API_SERVER_POSTGRES: PostgresSettings | None = Field( json_schema_extra={"auto_default_from_env": True} From f8ac22bf94975e894c5b433055e8711874f584e0 Mon Sep 17 00:00:00 2001 From: Giancarlo Romeo Date: Tue, 22 Oct 2024 11:28:25 +0200 Subject: [PATCH 24/37] fix test --- services/api-server/openapi.json | 2081 ++++++++++------- .../tests/unit/test_api_solver_jobs.py | 3 +- 2 files changed, 1238 insertions(+), 846 deletions(-) diff --git a/services/api-server/openapi.json b/services/api-server/openapi.json index 7965ae507f2..d2e7c528f95 100644 --- a/services/api-server/openapi.json +++ b/services/api-server/openapi.json @@ -316,26 +316,38 @@ "summary": "Upload File", "description": "Uploads a single file to the system", "operationId": "upload_file", + "security": [ + { + "HTTPBasic": [] + } + ], "parameters": [ { + "name": "content-length", + "in": "header", "required": false, "schema": { - "type": "string", + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], "title": "Content-Length" - }, - "name": "content-length", - "in": "header" + } } ], "requestBody": { + "required": true, "content": { "multipart/form-data": { "schema": { "$ref": "#/components/schemas/Body_upload_file_v0_files_content_put" } } - }, - "required": true + } }, "responses": { "200": { @@ -418,12 +430,7 @@ } } } - }, - "security": [ - { - "HTTPBasic": [] - } - ] + } }, "post": { "tags": [ @@ -432,15 +439,20 @@ "summary": "Get Upload Links", "description": "Get upload links for uploading a file to storage", "operationId": "get_upload_links", + "security": [ + { + "HTTPBasic": [] + } + ], "requestBody": { + "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ClientFile" } } - }, - "required": true + } }, "responses": { "200": { @@ -523,12 +535,7 @@ } } } - }, - "security": [ - { - "HTTPBasic": [] - } - ] + } } }, "/v0/files/{file_id}": { @@ -539,16 +546,21 @@ "summary": "Get File", "description": "Gets metadata for a given file resource", "operationId": "get_file", + "security": [ + { + "HTTPBasic": [] + } + ], "parameters": [ { + "name": "file_id", + "in": "path", "required": true, "schema": { "type": "string", "format": "uuid", "title": "File Id" - }, - "name": "file_id", - "in": "path" + } } ], "responses": { @@ -632,12 +644,7 @@ } } } - }, - "security": [ - { - "HTTPBasic": [] - } - ] + } }, "delete": { "tags": [ @@ -645,16 +652,21 @@ ], "summary": "Delete File", "operationId": "delete_file", + "security": [ + { + "HTTPBasic": [] + } + ], "parameters": [ { + "name": "file_id", + "in": "path", "required": true, "schema": { "type": "string", "format": "uuid", "title": "File Id" - }, - "name": "file_id", - "in": "path" + } } ], "responses": { @@ -736,12 +748,7 @@ } } } - }, - "security": [ - { - "HTTPBasic": [] - } - ] + } } }, "/v0/files:search": { @@ -752,49 +759,68 @@ "summary": "Search Files Page", "description": "Search files", "operationId": "search_files_page", + "security": [ + { + "HTTPBasic": [] + } + ], "parameters": [ { + "name": "sha256_checksum", + "in": "query", "required": false, "schema": { - "type": "string", - "pattern": "^[a-fA-F0-9]{64}$", + "anyOf": [ + { + "type": "string", + "pattern": "^[a-fA-F0-9]{64}$" + }, + { + "type": "null" + } + ], "title": "Sha256 Checksum" - }, - "name": "sha256_checksum", - "in": "query" + } }, { + "name": "file_id", + "in": "query", "required": false, "schema": { - "type": "string", - "format": "uuid", + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], "title": "File Id" - }, - "name": "file_id", - "in": "query" + } }, { + "name": "limit", + "in": "query", "required": false, "schema": { "type": "integer", "maximum": 100, "minimum": 1, - "title": "Limit", - "default": 50 - }, - "name": "limit", - "in": "query" + "default": 50, + "title": "Limit" + } }, { + "name": "offset", + "in": "query", "required": false, "schema": { "type": "integer", "minimum": 0, - "title": "Offset", - "default": 0 - }, - "name": "offset", - "in": "query" + "default": 0, + "title": "Offset" + } } ], "responses": { @@ -878,12 +904,7 @@ } } } - }, - "security": [ - { - "HTTPBasic": [] - } - ] + } } }, "/v0/files/{file_id}:abort": { @@ -893,27 +914,32 @@ ], "summary": "Abort Multipart Upload", "operationId": "abort_multipart_upload", + "security": [ + { + "HTTPBasic": [] + } + ], "parameters": [ { + "name": "file_id", + "in": "path", "required": true, "schema": { "type": "string", "format": "uuid", "title": "File Id" - }, - "name": "file_id", - "in": "path" + } } ], "requestBody": { + "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Body_abort_multipart_upload_v0_files__file_id__abort_post" } } - }, - "required": true + } }, "responses": { "200": { @@ -984,12 +1010,7 @@ } } } - }, - "security": [ - { - "HTTPBasic": [] - } - ] + } } }, "/v0/files/{file_id}:complete": { @@ -999,27 +1020,32 @@ ], "summary": "Complete Multipart Upload", "operationId": "complete_multipart_upload", + "security": [ + { + "HTTPBasic": [] + } + ], "parameters": [ { + "name": "file_id", + "in": "path", "required": true, "schema": { "type": "string", "format": "uuid", "title": "File Id" - }, - "name": "file_id", - "in": "path" + } } ], "requestBody": { + "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Body_complete_multipart_upload_v0_files__file_id__complete_post" } } - }, - "required": true + } }, "responses": { "200": { @@ -1102,12 +1128,7 @@ } } } - }, - "security": [ - { - "HTTPBasic": [] - } - ] + } } }, "/v0/files/{file_id}/content": { @@ -1117,16 +1138,21 @@ ], "summary": "Download File", "operationId": "download_file", + "security": [ + { + "HTTPBasic": [] + } + ], "parameters": [ { + "name": "file_id", + "in": "path", "required": true, "schema": { "type": "string", "format": "uuid", "title": "File Id" - }, - "name": "file_id", - "in": "path" + } } ], "responses": { @@ -1194,7 +1220,6 @@ } }, "200": { - "description": "Returns a arbitrary binary data", "content": { "application/octet-stream": { "schema": { @@ -1207,7 +1232,8 @@ "type": "string" } } - } + }, + "description": "Returns a arbitrary binary data" }, "422": { "description": "Validation Error", @@ -1219,12 +1245,7 @@ } } } - }, - "security": [ - { - "HTTPBasic": [] - } - ] + } } }, "/v0/solvers": { @@ -1417,16 +1438,21 @@ "summary": "Get Latest Release of a Solver", "description": "Gets latest release of a solver", "operationId": "get_solver", + "security": [ + { + "HTTPBasic": [] + } + ], "parameters": [ { + "name": "solver_key", + "in": "path", "required": true, "schema": { "type": "string", "pattern": "^simcore/services/comp/([a-z0-9][a-z0-9_.-]*/)*([a-z0-9-_]+[a-z0-9])$", "title": "Solver Key" - }, - "name": "solver_key", - "in": "path" + } } ], "responses": { @@ -1510,12 +1536,7 @@ } } } - }, - "security": [ - { - "HTTPBasic": [] - } - ] + } } }, "/v0/solvers/{solver_key}/releases": { @@ -1526,16 +1547,21 @@ "summary": "List Solver Releases", "description": "Lists all releases of a given (one) solver\n\nSEE get_solver_releases_page for a paginated version of this function", "operationId": "list_solver_releases", + "security": [ + { + "HTTPBasic": [] + } + ], "parameters": [ { + "name": "solver_key", + "in": "path", "required": true, "schema": { "type": "string", "pattern": "^simcore/services/comp/([a-z0-9][a-z0-9_.-]*/)*([a-z0-9-_]+[a-z0-9])$", "title": "Solver Key" - }, - "name": "solver_key", - "in": "path" + } } ], "responses": { @@ -1544,10 +1570,10 @@ "content": { "application/json": { "schema": { + "type": "array", "items": { "$ref": "#/components/schemas/Solver" }, - "type": "array", "title": "Response List Solver Releases V0 Solvers Solver Key Releases Get" } } @@ -1623,12 +1649,7 @@ } } } - }, - "security": [ - { - "HTTPBasic": [] - } - ] + } } }, "/v0/solvers/{solver_key}/releases/{version}": { @@ -1639,26 +1660,31 @@ "summary": "Get Solver Release", "description": "Gets a specific release of a solver", "operationId": "get_solver_release", + "security": [ + { + "HTTPBasic": [] + } + ], "parameters": [ { + "name": "solver_key", + "in": "path", "required": true, "schema": { "type": "string", "pattern": "^simcore/services/comp/([a-z0-9][a-z0-9_.-]*/)*([a-z0-9-_]+[a-z0-9])$", "title": "Solver Key" - }, - "name": "solver_key", - "in": "path" + } }, { + "name": "version", + "in": "path", "required": true, "schema": { "type": "string", "pattern": "^(0|[1-9]\\d*)(\\.(0|[1-9]\\d*)){2}(-(0|[1-9]\\d*|\\d*[-a-zA-Z][-\\da-zA-Z]*)(\\.(0|[1-9]\\d*|\\d*[-a-zA-Z][-\\da-zA-Z]*))*)?(\\+[-\\da-zA-Z]+(\\.[-\\da-zA-Z-]+)*)?$", "title": "Version" - }, - "name": "version", - "in": "path" + } } ], "responses": { @@ -1742,12 +1768,7 @@ } } } - }, - "security": [ - { - "HTTPBasic": [] - } - ] + } } }, "/v0/solvers/{solver_key}/releases/{version}/ports": { @@ -1758,26 +1779,31 @@ "summary": "List Solver Ports", "description": "Lists inputs and outputs of a given solver\n\nNew in *version 0.5.0*", "operationId": "list_solver_ports", + "security": [ + { + "HTTPBasic": [] + } + ], "parameters": [ { + "name": "solver_key", + "in": "path", "required": true, "schema": { "type": "string", "pattern": "^simcore/services/comp/([a-z0-9][a-z0-9_.-]*/)*([a-z0-9-_]+[a-z0-9])$", "title": "Solver Key" - }, - "name": "solver_key", - "in": "path" + } }, { + "name": "version", + "in": "path", "required": true, "schema": { "type": "string", "pattern": "^(0|[1-9]\\d*)(\\.(0|[1-9]\\d*)){2}(-(0|[1-9]\\d*|\\d*[-a-zA-Z][-\\da-zA-Z]*)(\\.(0|[1-9]\\d*|\\d*[-a-zA-Z][-\\da-zA-Z]*))*)?(\\+[-\\da-zA-Z]+(\\.[-\\da-zA-Z-]+)*)?$", "title": "Version" - }, - "name": "version", - "in": "path" + } } ], "responses": { @@ -1861,12 +1887,7 @@ } } } - }, - "security": [ - { - "HTTPBasic": [] - } - ] + } } }, "/v0/solvers/{solver_key}/releases/{version}/pricing_plan": { @@ -1877,26 +1898,31 @@ "summary": "Get Solver Pricing Plan", "description": "Gets solver pricing plan\n\nNew in *version 0.7*", "operationId": "get_solver_pricing_plan", + "security": [ + { + "HTTPBasic": [] + } + ], "parameters": [ { + "name": "solver_key", + "in": "path", "required": true, "schema": { "type": "string", "pattern": "^simcore/services/comp/([a-z0-9][a-z0-9_.-]*/)*([a-z0-9-_]+[a-z0-9])$", "title": "Solver Key" - }, - "name": "solver_key", - "in": "path" + } }, { + "name": "version", + "in": "path", "required": true, "schema": { "type": "string", "pattern": "^(0|[1-9]\\d*)(\\.(0|[1-9]\\d*)){2}(-(0|[1-9]\\d*|\\d*[-a-zA-Z][-\\da-zA-Z]*)(\\.(0|[1-9]\\d*|\\d*[-a-zA-Z][-\\da-zA-Z]*))*)?(\\+[-\\da-zA-Z]+(\\.[-\\da-zA-Z-]+)*)?$", "title": "Version" - }, - "name": "version", - "in": "path" + } } ], "responses": { @@ -1980,55 +2006,105 @@ } } } - }, - "security": [ - { - "HTTPBasic": [] - } - ] + } } }, "/v0/solvers/{solver_key}/releases/{version}/jobs": { - "get": { + "post": { "tags": [ "solvers" ], - "summary": "List Jobs", - "description": "List of jobs in a specific released solver (limited to 20 jobs)\n\n- DEPRECATION: This implementation and returned values are deprecated and the will be replaced by that of get_jobs_page\n- SEE `get_jobs_page` for paginated version of this function", - "operationId": "list_jobs", + "summary": "Create Job", + "description": "Creates a job in a specific release with given inputs.\n\nNOTE: This operation does **not** start the job", + "operationId": "create_job", + "security": [ + { + "HTTPBasic": [] + } + ], "parameters": [ { + "name": "solver_key", + "in": "path", "required": true, "schema": { "type": "string", "pattern": "^simcore/services/comp/([a-z0-9][a-z0-9_.-]*/)*([a-z0-9-_]+[a-z0-9])$", "title": "Solver Key" - }, - "name": "solver_key", - "in": "path" + } }, { + "name": "version", + "in": "path", "required": true, "schema": { "type": "string", "pattern": "^(0|[1-9]\\d*)(\\.(0|[1-9]\\d*)){2}(-(0|[1-9]\\d*|\\d*[-a-zA-Z][-\\da-zA-Z]*)(\\.(0|[1-9]\\d*|\\d*[-a-zA-Z][-\\da-zA-Z]*))*)?(\\+[-\\da-zA-Z]+(\\.[-\\da-zA-Z-]+)*)?$", "title": "Version" - }, - "name": "version", - "in": "path" + } + }, + { + "name": "hidden", + "in": "query", + "required": false, + "schema": { + "type": "boolean", + "default": true, + "title": "Hidden" + } + }, + { + "name": "x-simcore-parent-project-uuid", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "X-Simcore-Parent-Project-Uuid" + } + }, + { + "name": "x-simcore-parent-node-id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "X-Simcore-Parent-Node-Id" + } } ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/JobInputs" + } + } + } + }, "responses": { - "200": { + "201": { "description": "Successful Response", "content": { "application/json": { "schema": { - "items": { - "$ref": "#/components/schemas/Job" - }, - "type": "array", - "title": "Response List Jobs V0 Solvers Solver Key Releases Version Jobs Get" + "$ref": "#/components/schemas/Job" } } } @@ -2113,89 +2189,53 @@ } } } - }, + } + }, + "get": { + "tags": [ + "solvers" + ], + "summary": "List Jobs", + "description": "List of jobs in a specific released solver (limited to 20 jobs)\n\n- DEPRECATION: This implementation and returned values are deprecated and the will be replaced by that of get_jobs_page\n- SEE `get_jobs_page` for paginated version of this function", + "operationId": "list_jobs", "security": [ { "HTTPBasic": [] } - ] - }, - "post": { - "tags": [ - "solvers" ], - "summary": "Create Job", - "description": "Creates a job in a specific release with given inputs.\n\nNOTE: This operation does **not** start the job", - "operationId": "create_job", "parameters": [ { + "name": "solver_key", + "in": "path", "required": true, "schema": { "type": "string", "pattern": "^simcore/services/comp/([a-z0-9][a-z0-9_.-]*/)*([a-z0-9-_]+[a-z0-9])$", "title": "Solver Key" - }, - "name": "solver_key", - "in": "path" + } }, { + "name": "version", + "in": "path", "required": true, "schema": { "type": "string", "pattern": "^(0|[1-9]\\d*)(\\.(0|[1-9]\\d*)){2}(-(0|[1-9]\\d*|\\d*[-a-zA-Z][-\\da-zA-Z]*)(\\.(0|[1-9]\\d*|\\d*[-a-zA-Z][-\\da-zA-Z]*))*)?(\\+[-\\da-zA-Z]+(\\.[-\\da-zA-Z-]+)*)?$", "title": "Version" - }, - "name": "version", - "in": "path" - }, - { - "required": false, - "schema": { - "type": "boolean", - "title": "Hidden", - "default": true - }, - "name": "hidden", - "in": "query" - }, - { - "required": false, - "schema": { - "type": "string", - "format": "uuid", - "title": "X-Simcore-Parent-Project-Uuid" - }, - "name": "x-simcore-parent-project-uuid", - "in": "header" - }, - { - "required": false, - "schema": { - "type": "string", - "format": "uuid", - "title": "X-Simcore-Parent-Node-Id" - }, - "name": "x-simcore-parent-node-id", - "in": "header" + } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/JobInputs" - } - } - }, - "required": true - }, "responses": { - "201": { + "200": { "description": "Successful Response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Job" + "type": "array", + "items": { + "$ref": "#/components/schemas/Job" + }, + "title": "Response List Jobs V0 Solvers Solver Key Releases Version Jobs Get" } } } @@ -2280,64 +2320,57 @@ } } } - }, - "security": [ - { - "HTTPBasic": [] - } - ] + } } }, "/v0/solvers/{solver_key}/releases/{version}/jobs/{job_id}": { - "get": { + "delete": { "tags": [ "solvers" ], - "summary": "Get Job", - "description": "Gets job of a given solver", - "operationId": "get_job", + "summary": "Delete Job", + "description": "Deletes an existing solver job\n\nNew in *version 0.7*", + "operationId": "delete_job", + "security": [ + { + "HTTPBasic": [] + } + ], "parameters": [ { + "name": "solver_key", + "in": "path", "required": true, "schema": { "type": "string", "pattern": "^simcore/services/comp/([a-z0-9][a-z0-9_.-]*/)*([a-z0-9-_]+[a-z0-9])$", "title": "Solver Key" - }, - "name": "solver_key", - "in": "path" + } }, { + "name": "version", + "in": "path", "required": true, "schema": { "type": "string", "pattern": "^(0|[1-9]\\d*)(\\.(0|[1-9]\\d*)){2}(-(0|[1-9]\\d*|\\d*[-a-zA-Z][-\\da-zA-Z]*)(\\.(0|[1-9]\\d*|\\d*[-a-zA-Z][-\\da-zA-Z]*))*)?(\\+[-\\da-zA-Z]+(\\.[-\\da-zA-Z-]+)*)?$", "title": "Version" - }, - "name": "version", - "in": "path" + } }, { + "name": "job_id", + "in": "path", "required": true, "schema": { "type": "string", "format": "uuid", "title": "Job Id" - }, - "name": "job_id", - "in": "path" + } } ], "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Job" - } - } - } + "204": { + "description": "Successful Response" }, "402": { "description": "Payment required", @@ -2419,55 +2452,62 @@ } } } - }, + } + }, + "get": { + "tags": [ + "solvers" + ], + "summary": "Get Job", + "description": "Gets job of a given solver", + "operationId": "get_job", "security": [ { "HTTPBasic": [] } - ] - }, - "delete": { - "tags": [ - "solvers" ], - "summary": "Delete Job", - "description": "Deletes an existing solver job\n\nNew in *version 0.7*", - "operationId": "delete_job", "parameters": [ { + "name": "solver_key", + "in": "path", "required": true, "schema": { "type": "string", "pattern": "^simcore/services/comp/([a-z0-9][a-z0-9_.-]*/)*([a-z0-9-_]+[a-z0-9])$", "title": "Solver Key" - }, - "name": "solver_key", - "in": "path" + } }, { + "name": "version", + "in": "path", "required": true, "schema": { "type": "string", "pattern": "^(0|[1-9]\\d*)(\\.(0|[1-9]\\d*)){2}(-(0|[1-9]\\d*|\\d*[-a-zA-Z][-\\da-zA-Z]*)(\\.(0|[1-9]\\d*|\\d*[-a-zA-Z][-\\da-zA-Z]*))*)?(\\+[-\\da-zA-Z]+(\\.[-\\da-zA-Z-]+)*)?$", "title": "Version" - }, - "name": "version", - "in": "path" + } }, { + "name": "job_id", + "in": "path", "required": true, "schema": { "type": "string", "format": "uuid", "title": "Job Id" - }, - "name": "job_id", - "in": "path" + } } ], "responses": { - "204": { - "description": "Successful Response" + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Job" + } + } + } }, "402": { "description": "Payment required", @@ -2549,12 +2589,7 @@ } } } - }, - "security": [ - { - "HTTPBasic": [] - } - ] + } } }, "/v0/solvers/{solver_key}/releases/{version}/jobs/{job_id}:start": { @@ -2565,46 +2600,58 @@ "summary": "Start Job", "description": "Starts job job_id created with the solver solver_key:version\n\nAdded in *version 0.4.3*: query parameter `cluster_id`\nAdded in *version 0.6*: responds with a 202 when successfully starting a computation", "operationId": "start_job", + "security": [ + { + "HTTPBasic": [] + } + ], "parameters": [ { + "name": "solver_key", + "in": "path", "required": true, "schema": { "type": "string", "pattern": "^simcore/services/comp/([a-z0-9][a-z0-9_.-]*/)*([a-z0-9-_]+[a-z0-9])$", "title": "Solver Key" - }, - "name": "solver_key", - "in": "path" + } }, { + "name": "version", + "in": "path", "required": true, "schema": { "type": "string", "pattern": "^(0|[1-9]\\d*)(\\.(0|[1-9]\\d*)){2}(-(0|[1-9]\\d*|\\d*[-a-zA-Z][-\\da-zA-Z]*)(\\.(0|[1-9]\\d*|\\d*[-a-zA-Z][-\\da-zA-Z]*))*)?(\\+[-\\da-zA-Z]+(\\.[-\\da-zA-Z-]+)*)?$", "title": "Version" - }, - "name": "version", - "in": "path" + } }, { + "name": "job_id", + "in": "path", "required": true, "schema": { "type": "string", "format": "uuid", "title": "Job Id" - }, - "name": "job_id", - "in": "path" + } }, { + "name": "cluster_id", + "in": "query", "required": false, "schema": { - "type": "integer", - "minimum": 0, + "anyOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "null" + } + ], "title": "Cluster Id" - }, - "name": "cluster_id", - "in": "query" + } } ], "responses": { @@ -2718,12 +2765,7 @@ } } } - }, - "security": [ - { - "HTTPBasic": [] - } - ] + } } }, "/v0/solvers/{solver_key}/releases/{version}/jobs/{job_id}:stop": { @@ -2733,36 +2775,41 @@ ], "summary": "Stop Job", "operationId": "stop_job", + "security": [ + { + "HTTPBasic": [] + } + ], "parameters": [ { + "name": "solver_key", + "in": "path", "required": true, "schema": { "type": "string", "pattern": "^simcore/services/comp/([a-z0-9][a-z0-9_.-]*/)*([a-z0-9-_]+[a-z0-9])$", "title": "Solver Key" - }, - "name": "solver_key", - "in": "path" + } }, { + "name": "version", + "in": "path", "required": true, "schema": { "type": "string", "pattern": "^(0|[1-9]\\d*)(\\.(0|[1-9]\\d*)){2}(-(0|[1-9]\\d*|\\d*[-a-zA-Z][-\\da-zA-Z]*)(\\.(0|[1-9]\\d*|\\d*[-a-zA-Z][-\\da-zA-Z]*))*)?(\\+[-\\da-zA-Z]+(\\.[-\\da-zA-Z-]+)*)?$", "title": "Version" - }, - "name": "version", - "in": "path" + } }, { + "name": "job_id", + "in": "path", "required": true, "schema": { "type": "string", "format": "uuid", "title": "Job Id" - }, - "name": "job_id", - "in": "path" + } } ], "responses": { @@ -2856,12 +2903,7 @@ } } } - }, - "security": [ - { - "HTTPBasic": [] - } - ] + } } }, "/v0/solvers/{solver_key}/releases/{version}/jobs/{job_id}:inspect": { @@ -2871,36 +2913,41 @@ ], "summary": "Inspect Job", "operationId": "inspect_job", + "security": [ + { + "HTTPBasic": [] + } + ], "parameters": [ { + "name": "solver_key", + "in": "path", "required": true, "schema": { "type": "string", "pattern": "^simcore/services/comp/([a-z0-9][a-z0-9_.-]*/)*([a-z0-9-_]+[a-z0-9])$", "title": "Solver Key" - }, - "name": "solver_key", - "in": "path" + } }, { + "name": "version", + "in": "path", "required": true, "schema": { "type": "string", "pattern": "^(0|[1-9]\\d*)(\\.(0|[1-9]\\d*)){2}(-(0|[1-9]\\d*|\\d*[-a-zA-Z][-\\da-zA-Z]*)(\\.(0|[1-9]\\d*|\\d*[-a-zA-Z][-\\da-zA-Z]*))*)?(\\+[-\\da-zA-Z]+(\\.[-\\da-zA-Z-]+)*)?$", "title": "Version" - }, - "name": "version", - "in": "path" + } }, { + "name": "job_id", + "in": "path", "required": true, "schema": { "type": "string", "format": "uuid", "title": "Job Id" - }, - "name": "job_id", - "in": "path" + } } ], "responses": { @@ -2994,54 +3041,64 @@ } } } - }, - "security": [ - { - "HTTPBasic": [] - } - ] + } } }, "/v0/solvers/{solver_key}/releases/{version}/jobs/{job_id}/metadata": { - "get": { + "patch": { "tags": [ "solvers" ], - "summary": "Get Job Custom Metadata", - "description": "Gets custom metadata from a job\n\nNew in *version 0.7*", - "operationId": "get_job_custom_metadata", + "summary": "Replace Job Custom Metadata", + "description": "Updates custom metadata from a job\n\nNew in *version 0.7*", + "operationId": "replace_job_custom_metadata", + "security": [ + { + "HTTPBasic": [] + } + ], "parameters": [ { + "name": "solver_key", + "in": "path", "required": true, "schema": { "type": "string", "pattern": "^simcore/services/comp/([a-z0-9][a-z0-9_.-]*/)*([a-z0-9-_]+[a-z0-9])$", "title": "Solver Key" - }, - "name": "solver_key", - "in": "path" + } }, { + "name": "version", + "in": "path", "required": true, "schema": { "type": "string", "pattern": "^(0|[1-9]\\d*)(\\.(0|[1-9]\\d*)){2}(-(0|[1-9]\\d*|\\d*[-a-zA-Z][-\\da-zA-Z]*)(\\.(0|[1-9]\\d*|\\d*[-a-zA-Z][-\\da-zA-Z]*))*)?(\\+[-\\da-zA-Z]+(\\.[-\\da-zA-Z-]+)*)?$", "title": "Version" - }, - "name": "version", - "in": "path" + } }, { + "name": "job_id", + "in": "path", "required": true, "schema": { "type": "string", "format": "uuid", "title": "Job Id" - }, - "name": "job_id", - "in": "path" + } } ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/JobMetadataUpdate" + } + } + } + }, "responses": { "200": { "description": "Successful Response", @@ -3123,62 +3180,52 @@ } } } - }, + } + }, + "get": { + "tags": [ + "solvers" + ], + "summary": "Get Job Custom Metadata", + "description": "Gets custom metadata from a job\n\nNew in *version 0.7*", + "operationId": "get_job_custom_metadata", "security": [ { "HTTPBasic": [] } - ] - }, - "patch": { - "tags": [ - "solvers" ], - "summary": "Replace Job Custom Metadata", - "description": "Updates custom metadata from a job\n\nNew in *version 0.7*", - "operationId": "replace_job_custom_metadata", "parameters": [ { + "name": "solver_key", + "in": "path", "required": true, "schema": { "type": "string", "pattern": "^simcore/services/comp/([a-z0-9][a-z0-9_.-]*/)*([a-z0-9-_]+[a-z0-9])$", "title": "Solver Key" - }, - "name": "solver_key", - "in": "path" + } }, { + "name": "version", + "in": "path", "required": true, "schema": { "type": "string", "pattern": "^(0|[1-9]\\d*)(\\.(0|[1-9]\\d*)){2}(-(0|[1-9]\\d*|\\d*[-a-zA-Z][-\\da-zA-Z]*)(\\.(0|[1-9]\\d*|\\d*[-a-zA-Z][-\\da-zA-Z]*))*)?(\\+[-\\da-zA-Z]+(\\.[-\\da-zA-Z-]+)*)?$", "title": "Version" - }, - "name": "version", - "in": "path" + } }, { + "name": "job_id", + "in": "path", "required": true, "schema": { "type": "string", "format": "uuid", "title": "Job Id" - }, - "name": "job_id", - "in": "path" + } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/JobMetadataUpdate" - } - } - }, - "required": true - }, "responses": { "200": { "description": "Successful Response", @@ -3260,12 +3307,7 @@ } } } - }, - "security": [ - { - "HTTPBasic": [] - } - ] + } } }, "/v0/solvers/{solver_key}/releases/{version}/jobs/page": { @@ -3276,49 +3318,54 @@ "summary": "Get Jobs Page", "description": "List of jobs on a specific released solver (includes pagination)\n\nNew in *version 0.7*", "operationId": "get_jobs_page", + "security": [ + { + "HTTPBasic": [] + } + ], "parameters": [ { + "name": "solver_key", + "in": "path", "required": true, "schema": { "type": "string", "pattern": "^simcore/services/comp/([a-z0-9][a-z0-9_.-]*/)*([a-z0-9-_]+[a-z0-9])$", "title": "Solver Key" - }, - "name": "solver_key", - "in": "path" + } }, { + "name": "version", + "in": "path", "required": true, "schema": { "type": "string", "pattern": "^(0|[1-9]\\d*)(\\.(0|[1-9]\\d*)){2}(-(0|[1-9]\\d*|\\d*[-a-zA-Z][-\\da-zA-Z]*)(\\.(0|[1-9]\\d*|\\d*[-a-zA-Z][-\\da-zA-Z]*))*)?(\\+[-\\da-zA-Z]+(\\.[-\\da-zA-Z-]+)*)?$", "title": "Version" - }, - "name": "version", - "in": "path" + } }, { + "name": "limit", + "in": "query", "required": false, "schema": { "type": "integer", "maximum": 100, "minimum": 1, - "title": "Limit", - "default": 50 - }, - "name": "limit", - "in": "query" + "default": 50, + "title": "Limit" + } }, { + "name": "offset", + "in": "query", "required": false, "schema": { "type": "integer", "minimum": 0, - "title": "Offset", - "default": 0 - }, - "name": "offset", - "in": "query" + "default": 0, + "title": "Offset" + } } ], "responses": { @@ -3412,12 +3459,7 @@ } } } - }, - "security": [ - { - "HTTPBasic": [] - } - ] + } } }, "/v0/solvers/{solver_key}/releases/{version}/jobs/{job_id}/outputs": { @@ -3427,36 +3469,41 @@ ], "summary": "Get Job Outputs", "operationId": "get_job_outputs", + "security": [ + { + "HTTPBasic": [] + } + ], "parameters": [ { + "name": "solver_key", + "in": "path", "required": true, "schema": { "type": "string", "pattern": "^simcore/services/comp/([a-z0-9][a-z0-9_.-]*/)*([a-z0-9-_]+[a-z0-9])$", "title": "Solver Key" - }, - "name": "solver_key", - "in": "path" + } }, { + "name": "version", + "in": "path", "required": true, "schema": { "type": "string", "pattern": "^(0|[1-9]\\d*)(\\.(0|[1-9]\\d*)){2}(-(0|[1-9]\\d*|\\d*[-a-zA-Z][-\\da-zA-Z]*)(\\.(0|[1-9]\\d*|\\d*[-a-zA-Z][-\\da-zA-Z]*))*)?(\\+[-\\da-zA-Z]+(\\.[-\\da-zA-Z-]+)*)?$", "title": "Version" - }, - "name": "version", - "in": "path" + } }, { + "name": "job_id", + "in": "path", "required": true, "schema": { "type": "string", "format": "uuid", "title": "Job Id" - }, - "name": "job_id", - "in": "path" + } } ], "responses": { @@ -3550,12 +3597,7 @@ } } } - }, - "security": [ - { - "HTTPBasic": [] - } - ] + } } }, "/v0/solvers/{solver_key}/releases/{version}/jobs/{job_id}/outputs/logfile": { @@ -3566,36 +3608,41 @@ "summary": "Get Job Output Logfile", "description": "Special extra output with persistent logs file for the solver run.\n\n**NOTE**: this is not a log stream but a predefined output that is only\navailable after the job is done.\n\nNew in *version 0.4.0*", "operationId": "get_job_output_logfile", + "security": [ + { + "HTTPBasic": [] + } + ], "parameters": [ { + "name": "solver_key", + "in": "path", "required": true, "schema": { "type": "string", "pattern": "^simcore/services/comp/([a-z0-9][a-z0-9_.-]*/)*([a-z0-9-_]+[a-z0-9])$", "title": "Solver Key" - }, - "name": "solver_key", - "in": "path" + } }, { + "name": "version", + "in": "path", "required": true, "schema": { "type": "string", "pattern": "^(0|[1-9]\\d*)(\\.(0|[1-9]\\d*)){2}(-(0|[1-9]\\d*|\\d*[-a-zA-Z][-\\da-zA-Z]*)(\\.(0|[1-9]\\d*|\\d*[-a-zA-Z][-\\da-zA-Z]*))*)?(\\+[-\\da-zA-Z]+(\\.[-\\da-zA-Z-]+)*)?$", "title": "Version" - }, - "name": "version", - "in": "path" + } }, { + "name": "job_id", + "in": "path", "required": true, "schema": { "type": "string", "format": "uuid", "title": "Job Id" - }, - "name": "job_id", - "in": "path" + } } ], "responses": { @@ -3603,7 +3650,6 @@ "description": "Successful Response" }, "200": { - "description": "Returns a log file", "content": { "application/octet-stream": { "schema": { @@ -3622,7 +3668,8 @@ "type": "string" } } - } + }, + "description": "Returns a log file" }, "404": { "description": "Log not found" @@ -3687,12 +3734,7 @@ } } } - }, - "security": [ - { - "HTTPBasic": [] - } - ] + } } }, "/v0/solvers/{solver_key}/releases/{version}/jobs/{job_id}/wallet": { @@ -3703,36 +3745,41 @@ "summary": "Get Job Wallet", "description": "Get job wallet\n\nNew in *version 0.7*", "operationId": "get_job_wallet", + "security": [ + { + "HTTPBasic": [] + } + ], "parameters": [ { + "name": "solver_key", + "in": "path", "required": true, "schema": { "type": "string", "pattern": "^simcore/services/comp/([a-z0-9][a-z0-9_.-]*/)*([a-z0-9-_]+[a-z0-9])$", "title": "Solver Key" - }, - "name": "solver_key", - "in": "path" + } }, { + "name": "version", + "in": "path", "required": true, "schema": { "type": "string", "pattern": "^(0|[1-9]\\d*)(\\.(0|[1-9]\\d*)){2}(-(0|[1-9]\\d*|\\d*[-a-zA-Z][-\\da-zA-Z]*)(\\.(0|[1-9]\\d*|\\d*[-a-zA-Z][-\\da-zA-Z]*))*)?(\\+[-\\da-zA-Z]+(\\.[-\\da-zA-Z-]+)*)?$", "title": "Version" - }, - "name": "version", - "in": "path" + } }, { + "name": "job_id", + "in": "path", "required": true, "schema": { "type": "string", "format": "uuid", "title": "Job Id" - }, - "name": "job_id", - "in": "path" + } } ], "responses": { @@ -3741,7 +3788,15 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/WalletGetWithAvailableCredits" + "anyOf": [ + { + "$ref": "#/components/schemas/WalletGetWithAvailableCredits" + }, + { + "type": "null" + } + ], + "title": "Response Get Job Wallet V0 Solvers Solver Key Releases Version Jobs Job Id Wallet Get" } } } @@ -3826,12 +3881,7 @@ } } } - }, - "security": [ - { - "HTTPBasic": [] - } - ] + } } }, "/v0/solvers/{solver_key}/releases/{version}/jobs/{job_id}/pricing_unit": { @@ -3842,36 +3892,41 @@ "summary": "Get Job Pricing Unit", "description": "Get job pricing unit\n\nNew in *version 0.7*", "operationId": "get_job_pricing_unit", + "security": [ + { + "HTTPBasic": [] + } + ], "parameters": [ { + "name": "solver_key", + "in": "path", "required": true, "schema": { "type": "string", "pattern": "^simcore/services/comp/([a-z0-9][a-z0-9_.-]*/)*([a-z0-9-_]+[a-z0-9])$", "title": "Solver Key" - }, - "name": "solver_key", - "in": "path" + } }, { + "name": "version", + "in": "path", "required": true, "schema": { "type": "string", "pattern": "^(0|[1-9]\\d*)(\\.(0|[1-9]\\d*)){2}(-(0|[1-9]\\d*|\\d*[-a-zA-Z][-\\da-zA-Z]*)(\\.(0|[1-9]\\d*|\\d*[-a-zA-Z][-\\da-zA-Z]*))*)?(\\+[-\\da-zA-Z]+(\\.[-\\da-zA-Z-]+)*)?$", "title": "Version" - }, - "name": "version", - "in": "path" + } }, { + "name": "job_id", + "in": "path", "required": true, "schema": { "type": "string", "format": "uuid", "title": "Job Id" - }, - "name": "job_id", - "in": "path" + } } ], "responses": { @@ -3880,7 +3935,15 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PricingUnitGet" + "anyOf": [ + { + "$ref": "#/components/schemas/PricingUnitGet" + }, + { + "type": "null" + } + ], + "title": "Response Get Job Pricing Unit V0 Solvers Solver Key Releases Version Jobs Job Id Pricing Unit Get" } } } @@ -3955,12 +4018,7 @@ } } } - }, - "security": [ - { - "HTTPBasic": [] - } - ] + } } }, "/v0/solvers/{solver_key}/releases/{version}/jobs/{job_id}/logstream": { @@ -3970,36 +4028,41 @@ ], "summary": "Get Log Stream", "operationId": "get_log_stream", + "security": [ + { + "HTTPBasic": [] + } + ], "parameters": [ { + "name": "solver_key", + "in": "path", "required": true, "schema": { "type": "string", "pattern": "^simcore/services/comp/([a-z0-9][a-z0-9_.-]*/)*([a-z0-9-_]+[a-z0-9])$", "title": "Solver Key" - }, - "name": "solver_key", - "in": "path" + } }, { + "name": "version", + "in": "path", "required": true, "schema": { "type": "string", "pattern": "^(0|[1-9]\\d*)(\\.(0|[1-9]\\d*)){2}(-(0|[1-9]\\d*|\\d*[-a-zA-Z][-\\da-zA-Z]*)(\\.(0|[1-9]\\d*|\\d*[-a-zA-Z][-\\da-zA-Z]*))*)?(\\+[-\\da-zA-Z]+(\\.[-\\da-zA-Z-]+)*)?$", "title": "Version" - }, - "name": "version", - "in": "path" + } }, { + "name": "job_id", + "in": "path", "required": true, "schema": { "type": "string", "format": "uuid", "title": "Job Id" - }, - "name": "job_id", - "in": "path" + } } ], "responses": { @@ -4008,6 +4071,7 @@ "content": { "application/x-ndjson": { "schema": { + "type": "string", "anyOf": [ { "$ref": "#/components/schemas/JobLog" @@ -4016,7 +4080,6 @@ "$ref": "#/components/schemas/ErrorGet" } ], - "type": "string", "title": "Response 200 Get Log Stream V0 Solvers Solver Key Releases Version Jobs Job Id Logstream Get" } } @@ -4092,12 +4155,7 @@ } } } - }, - "security": [ - { - "HTTPBasic": [] - } - ] + } } }, "/v0/studies": { @@ -4108,29 +4166,34 @@ "summary": "List Studies", "description": "New in *version 0.5.0*", "operationId": "list_studies", + "security": [ + { + "HTTPBasic": [] + } + ], "parameters": [ { + "name": "limit", + "in": "query", "required": false, "schema": { "type": "integer", "maximum": 100, "minimum": 1, - "title": "Limit", - "default": 50 - }, - "name": "limit", - "in": "query" + "default": 50, + "title": "Limit" + } }, { + "name": "offset", + "in": "query", "required": false, "schema": { "type": "integer", "minimum": 0, - "title": "Offset", - "default": 0 - }, - "name": "offset", - "in": "query" + "default": 0, + "title": "Offset" + } } ], "responses": { @@ -4154,12 +4217,7 @@ } } } - }, - "security": [ - { - "HTTPBasic": [] - } - ] + } } }, "/v0/studies/{study_id}": { @@ -4170,16 +4228,21 @@ "summary": "Get Study", "description": "New in *version 0.5.0*", "operationId": "get_study", + "security": [ + { + "HTTPBasic": [] + } + ], "parameters": [ { + "name": "study_id", + "in": "path", "required": true, "schema": { "type": "string", "format": "uuid", "title": "Study Id" - }, - "name": "study_id", - "in": "path" + } } ], "responses": { @@ -4213,12 +4276,7 @@ } } } - }, - "security": [ - { - "HTTPBasic": [] - } - ] + } } }, "/v0/studies/{study_id}:clone": { @@ -4228,36 +4286,55 @@ ], "summary": "Clone Study", "operationId": "clone_study", + "security": [ + { + "HTTPBasic": [] + } + ], "parameters": [ { + "name": "study_id", + "in": "path", "required": true, "schema": { "type": "string", "format": "uuid", "title": "Study Id" - }, - "name": "study_id", - "in": "path" + } }, { + "name": "x-simcore-parent-project-uuid", + "in": "header", "required": false, "schema": { - "type": "string", - "format": "uuid", + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], "title": "X-Simcore-Parent-Project-Uuid" - }, - "name": "x-simcore-parent-project-uuid", - "in": "header" + } }, { + "name": "x-simcore-parent-node-id", + "in": "header", "required": false, "schema": { - "type": "string", - "format": "uuid", + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], "title": "X-Simcore-Parent-Node-Id" - }, - "name": "x-simcore-parent-node-id", - "in": "header" + } } ], "responses": { @@ -4291,12 +4368,7 @@ } } } - }, - "security": [ - { - "HTTPBasic": [] - } - ] + } } }, "/v0/studies/{study_id}/ports": { @@ -4307,16 +4379,21 @@ "summary": "List Study Ports", "description": "Lists metadata on ports of a given study\n\nNew in *version 0.5.0*", "operationId": "list_study_ports", + "security": [ + { + "HTTPBasic": [] + } + ], "parameters": [ { + "name": "study_id", + "in": "path", "required": true, "schema": { "type": "string", "format": "uuid", "title": "Study Id" - }, - "name": "study_id", - "in": "path" + } } ], "responses": { @@ -4350,12 +4427,7 @@ } } } - }, - "security": [ - { - "HTTPBasic": [] - } - ] + } } }, "/v0/studies/{study_id}/jobs": { @@ -4366,57 +4438,76 @@ "summary": "Create Study Job", "description": "hidden -- if True (default) hides project from UI", "operationId": "create_study_job", + "security": [ + { + "HTTPBasic": [] + } + ], "parameters": [ { + "name": "study_id", + "in": "path", "required": true, "schema": { "type": "string", "format": "uuid", "title": "Study Id" - }, - "name": "study_id", - "in": "path" + } }, { + "name": "hidden", + "in": "query", "required": false, "schema": { "type": "boolean", - "title": "Hidden", - "default": true - }, - "name": "hidden", - "in": "query" + "default": true, + "title": "Hidden" + } }, { + "name": "x-simcore-parent-project-uuid", + "in": "header", "required": false, "schema": { - "type": "string", - "format": "uuid", + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], "title": "X-Simcore-Parent-Project-Uuid" - }, - "name": "x-simcore-parent-project-uuid", - "in": "header" + } }, { + "name": "x-simcore-parent-node-id", + "in": "header", "required": false, "schema": { - "type": "string", - "format": "uuid", + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], "title": "X-Simcore-Parent-Node-Id" - }, - "name": "x-simcore-parent-node-id", - "in": "header" + } } ], "requestBody": { + "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/JobInputs" } } - }, - "required": true + } }, "responses": { "200": { @@ -4439,12 +4530,7 @@ } } } - }, - "security": [ - { - "HTTPBasic": [] - } - ] + } } }, "/v0/studies/{study_id}/jobs/{job_id}": { @@ -4455,26 +4541,31 @@ "summary": "Delete Study Job", "description": "Deletes an existing study job", "operationId": "delete_study_job", + "security": [ + { + "HTTPBasic": [] + } + ], "parameters": [ { + "name": "study_id", + "in": "path", "required": true, "schema": { "type": "string", "format": "uuid", "title": "Study Id" - }, - "name": "study_id", - "in": "path" + } }, { + "name": "job_id", + "in": "path", "required": true, "schema": { "type": "string", "format": "uuid", "title": "Job Id" - }, - "name": "job_id", - "in": "path" + } } ], "responses": { @@ -4482,14 +4573,14 @@ "description": "Successful Response" }, "404": { - "description": "Not Found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorGet" } } - } + }, + "description": "Not Found" }, "422": { "description": "Validation Error", @@ -4498,15 +4589,10 @@ "schema": { "$ref": "#/components/schemas/HTTPValidationError" } - } - } - } - }, - "security": [ - { - "HTTPBasic": [] + } + } } - ] + } } }, "/v0/studies/{study_id}/jobs/{job_id}:start": { @@ -4517,36 +4603,48 @@ "summary": "Start Study Job", "description": "Changed in *version 0.6.0*: Now responds with a 202 when successfully starting a computation", "operationId": "start_study_job", + "security": [ + { + "HTTPBasic": [] + } + ], "parameters": [ { + "name": "study_id", + "in": "path", "required": true, "schema": { "type": "string", "format": "uuid", "title": "Study Id" - }, - "name": "study_id", - "in": "path" + } }, { + "name": "job_id", + "in": "path", "required": true, "schema": { "type": "string", "format": "uuid", "title": "Job Id" - }, - "name": "job_id", - "in": "path" + } }, { + "name": "cluster_id", + "in": "query", "required": false, "schema": { - "type": "integer", - "minimum": 0, + "anyOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "null" + } + ], "title": "Cluster Id" - }, - "name": "cluster_id", - "in": "query" + } } ], "responses": { @@ -4660,12 +4758,7 @@ } } } - }, - "security": [ - { - "HTTPBasic": [] - } - ] + } } }, "/v0/studies/{study_id}/jobs/{job_id}:stop": { @@ -4675,26 +4768,31 @@ ], "summary": "Stop Study Job", "operationId": "stop_study_job", + "security": [ + { + "HTTPBasic": [] + } + ], "parameters": [ { + "name": "study_id", + "in": "path", "required": true, "schema": { "type": "string", "format": "uuid", "title": "Study Id" - }, - "name": "study_id", - "in": "path" + } }, { + "name": "job_id", + "in": "path", "required": true, "schema": { "type": "string", "format": "uuid", "title": "Job Id" - }, - "name": "job_id", - "in": "path" + } } ], "responses": { @@ -4718,12 +4816,7 @@ } } } - }, - "security": [ - { - "HTTPBasic": [] - } - ] + } } }, "/v0/studies/{study_id}/jobs/{job_id}:inspect": { @@ -4733,26 +4826,31 @@ ], "summary": "Inspect Study Job", "operationId": "inspect_study_job", + "security": [ + { + "HTTPBasic": [] + } + ], "parameters": [ { + "name": "study_id", + "in": "path", "required": true, "schema": { "type": "string", "format": "uuid", "title": "Study Id" - }, - "name": "study_id", - "in": "path" + } }, { + "name": "job_id", + "in": "path", "required": true, "schema": { "type": "string", "format": "uuid", "title": "Job Id" - }, - "name": "job_id", - "in": "path" + } } ], "responses": { @@ -4776,12 +4874,7 @@ } } } - }, - "security": [ - { - "HTTPBasic": [] - } - ] + } } }, "/v0/studies/{study_id}/jobs/{job_id}/outputs": { @@ -4791,26 +4884,31 @@ ], "summary": "Get Study Job Outputs", "operationId": "get_study_job_outputs", + "security": [ + { + "HTTPBasic": [] + } + ], "parameters": [ { + "name": "study_id", + "in": "path", "required": true, "schema": { "type": "string", "format": "uuid", "title": "Study Id" - }, - "name": "study_id", - "in": "path" + } }, { + "name": "job_id", + "in": "path", "required": true, "schema": { "type": "string", "format": "uuid", "title": "Job Id" - }, - "name": "job_id", - "in": "path" + } } ], "responses": { @@ -4834,12 +4932,7 @@ } } } - }, - "security": [ - { - "HTTPBasic": [] - } - ] + } } }, "/v0/studies/{study_id}/jobs/{job_id}/outputs/log-links": { @@ -4849,26 +4942,31 @@ ], "summary": "Get download links for study job log files", "operationId": "get_study_job_output_logfile", + "security": [ + { + "HTTPBasic": [] + } + ], "parameters": [ { + "name": "study_id", + "in": "path", "required": true, "schema": { "type": "string", "format": "uuid", "title": "Study Id" - }, - "name": "study_id", - "in": "path" + } }, { + "name": "job_id", + "in": "path", "required": true, "schema": { "type": "string", "format": "uuid", "title": "Job Id" - }, - "name": "job_id", - "in": "path" + } } ], "responses": { @@ -4892,12 +4990,7 @@ } } } - }, - "security": [ - { - "HTTPBasic": [] - } - ] + } } }, "/v0/studies/{study_id}/jobs/{job_id}/metadata": { @@ -4908,26 +5001,31 @@ "summary": "Get Study Job Custom Metadata", "description": "Get custom metadata from a study's job\n\nNew in *version 0.7*", "operationId": "get_study_job_custom_metadata", + "security": [ + { + "HTTPBasic": [] + } + ], "parameters": [ { + "name": "study_id", + "in": "path", "required": true, "schema": { "type": "string", "format": "uuid", "title": "Study Id" - }, - "name": "study_id", - "in": "path" + } }, { + "name": "job_id", + "in": "path", "required": true, "schema": { "type": "string", "format": "uuid", "title": "Job Id" - }, - "name": "job_id", - "in": "path" + } } ], "responses": { @@ -4951,12 +5049,7 @@ } } } - }, - "security": [ - { - "HTTPBasic": [] - } - ] + } }, "put": { "tags": [ @@ -4965,37 +5058,42 @@ "summary": "Replace Study Job Custom Metadata", "description": "Changes custom metadata of a study's job\n\nNew in *version 0.7*", "operationId": "replace_study_job_custom_metadata", + "security": [ + { + "HTTPBasic": [] + } + ], "parameters": [ { + "name": "study_id", + "in": "path", "required": true, "schema": { "type": "string", "format": "uuid", "title": "Study Id" - }, - "name": "study_id", - "in": "path" + } }, { + "name": "job_id", + "in": "path", "required": true, "schema": { "type": "string", "format": "uuid", "title": "Job Id" - }, - "name": "job_id", - "in": "path" + } } ], "requestBody": { + "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/JobMetadataUpdate" } } - }, - "required": true + } }, "responses": { "200": { @@ -5018,12 +5116,7 @@ } } } - }, - "security": [ - { - "HTTPBasic": [] - } - ] + } } }, "/v0/wallets/default": { @@ -5131,15 +5224,20 @@ "summary": "Get Wallet", "description": "Get wallet\n\nNew in *version 0.7*", "operationId": "get_wallet", + "security": [ + { + "HTTPBasic": [] + } + ], "parameters": [ { + "name": "wallet_id", + "in": "path", "required": true, "schema": { "type": "integer", "title": "Wallet Id" - }, - "name": "wallet_id", - "in": "path" + } } ], "responses": { @@ -5233,12 +5331,7 @@ } } } - }, - "security": [ - { - "HTTPBasic": [] - } - ] + } } }, "/v0/credits/price": { @@ -5321,7 +5414,16 @@ "description": "File name" }, "filesize": { - "type": "integer", + "anyOf": [ + { + "type": "string", + "pattern": "^\\s*(\\d*\\.?\\d+)\\s*(\\w+)?" + }, + { + "type": "integer", + "minimum": 0 + } + ], "title": "Filesize", "description": "File size in bytes" }, @@ -5350,12 +5452,7 @@ "description": "The file resource id" }, "upload_schema": { - "allOf": [ - { - "$ref": "#/components/schemas/FileUploadData" - } - ], - "title": "Upload Schema", + "$ref": "#/components/schemas/FileUploadData", "description": "Schema for uploading file" } }, @@ -5400,18 +5497,39 @@ "description": "Name of the file with extension" }, "content_type": { - "type": "string", + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], "title": "Content Type", "description": "Guess of type content [EXPERIMENTAL]" }, "checksum": { - "type": "string", - "pattern": "^[a-fA-F0-9]{64}$", + "anyOf": [ + { + "type": "string", + "pattern": "^[a-fA-F0-9]{64}$" + }, + { + "type": "null" + } + ], "title": "Checksum", "description": "SHA256 hash of the file's content" }, "e_tag": { - "type": "string", + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], "title": "E Tag", "description": "S3 entity tag" } @@ -5444,12 +5562,12 @@ "properties": { "chunk_size": { "type": "integer", + "minimum": 0, "title": "Chunk Size" }, "urls": { "items": { "type": "string", - "maxLength": 65536, "minLength": 1, "format": "uri" }, @@ -5475,14 +5593,27 @@ "title": "Productname" }, "usdPerCredit": { - "type": "number", - "minimum": 0.0, + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], "title": "Usdpercredit", "description": "Price of a credit in USD. If None, then this product's price is UNDEFINED" }, "minPaymentAmountUsd": { - "type": "integer", - "minimum": 0, + "anyOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "null" + } + ], "title": "Minpaymentamountusd", "description": "Minimum amount (included) in USD that can be paid for this productCan be None if this product's price is UNDEFINED" } @@ -5501,10 +5632,17 @@ "$ref": "#/components/schemas/UsersGroup" }, "organizations": { - "items": { - "$ref": "#/components/schemas/UsersGroup" - }, - "type": "array", + "anyOf": [ + { + "items": { + "$ref": "#/components/schemas/UsersGroup" + }, + "type": "array" + }, + { + "type": "null" + } + ], "title": "Organizations", "default": [] }, @@ -5562,26 +5700,47 @@ "description": "Runner that executes job" }, "url": { - "type": "string", - "maxLength": 2083, - "minLength": 1, - "format": "uri", + "anyOf": [ + { + "type": "string", + "maxLength": 2083, + "minLength": 1, + "format": "uri" + }, + { + "type": "null" + } + ], "title": "Url", "description": "Link to get this resource (self)" }, "runner_url": { - "type": "string", - "maxLength": 2083, - "minLength": 1, - "format": "uri", + "anyOf": [ + { + "type": "string", + "maxLength": 2083, + "minLength": 1, + "format": "uri" + }, + { + "type": "null" + } + ], "title": "Runner Url", "description": "Link to the solver's job (parent collection)" }, "outputs_url": { - "type": "string", - "maxLength": 2083, - "minLength": 1, - "format": "uri", + "anyOf": [ + { + "type": "string", + "maxLength": 2083, + "minLength": 1, + "format": "uri" + }, + { + "type": "null" + } + ], "title": "Outputs Url", "description": "Link to the job outputs (sub-collection)" } @@ -5599,14 +5758,14 @@ ], "title": "Job", "example": { + "created_at": "2021-01-22T23:59:52.322176", "id": "f622946d-fd29-35b9-a193-abdd1095167c", + "inputs_checksum": "12345", "name": "solvers/isolve/releases/1.3.4/jobs/f622946d-fd29-35b9-a193-abdd1095167c", + "outputs_url": "https://api.osparc.io/v0/solvers/isolve/releases/1.3.4/jobs/f622946d-fd29-35b9-a193-abdd1095167c/outputs", "runner_name": "solvers/isolve/releases/1.3.4", - "inputs_checksum": "12345", - "created_at": "2021-01-22T23:59:52.322176", - "url": "https://api.osparc.io/v0/solvers/isolve/releases/1.3.4/jobs/f622946d-fd29-35b9-a193-abdd1095167c", "runner_url": "https://api.osparc.io/v0/solvers/isolve/releases/1.3.4", - "outputs_url": "https://api.osparc.io/v0/solvers/isolve/releases/1.3.4/jobs/f622946d-fd29-35b9-a193-abdd1095167c/outputs" + "url": "https://api.osparc.io/v0/solvers/isolve/releases/1.3.4/jobs/f622946d-fd29-35b9-a193-abdd1095167c" } }, "JobInputs": { @@ -5632,6 +5791,9 @@ { "items": {}, "type": "array" + }, + { + "type": "null" } ] }, @@ -5646,14 +5808,14 @@ "title": "JobInputs", "example": { "values": { - "x": 4.33, - "n": 55, - "title": "Temperature", "enabled": true, "input_file": { "filename": "input.txt", "id": "0a3b2c56-dbcd-4871-b93b-d454b7883f9f" - } + }, + "n": 55, + "title": "Temperature", + "x": 4.33 } } }, @@ -5665,8 +5827,15 @@ "title": "Job Id" }, "node_id": { - "type": "string", - "format": "uuid", + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], "title": "Node Id" }, "log_level": { @@ -5690,11 +5859,11 @@ "title": "JobLog", "example": { "job_id": "145beae4-a3a8-4fde-adbb-4e8257c2c083", - "node_id": "3742215e-6756-48d2-8b73-4d043065309f", "log_level": 10, "messages": [ "PROGRESS: 5/10" - ] + ], + "node_id": "3742215e-6756-48d2-8b73-4d043065309f" } }, "JobLogsMap": { @@ -5744,10 +5913,17 @@ "description": "Custom key-value map" }, "url": { - "type": "string", - "maxLength": 2083, - "minLength": 1, - "format": "uri", + "anyOf": [ + { + "type": "string", + "maxLength": 2083, + "minLength": 1, + "format": "uri" + }, + { + "type": "null" + } + ], "title": "Url", "description": "Link to get this resource (self)" } @@ -5816,6 +5992,9 @@ { "items": {}, "type": "array" + }, + { + "type": "null" } ] }, @@ -5832,14 +6011,14 @@ "example": { "job_id": "99d9ac65-9f10-4e2f-a433-b5e412bb037b", "results": { + "enabled": false, "maxSAR": 4.33, "n": 55, - "title": "Specific Absorption Rate", - "enabled": false, "output_file": { "filename": "sar_matrix.txt", "id": "0a3b2c56-dbcd-4871-b93b-d454b7883f9f" - } + }, + "title": "Specific Absorption Rate" } } }, @@ -5867,14 +6046,28 @@ "description": "Last modification timestamp of the solver job" }, "started_at": { - "type": "string", - "format": "date-time", + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], "title": "Started At", "description": "Timestamp that indicate the moment the solver starts execution or None if the event did not occur" }, "stopped_at": { - "type": "string", - "format": "date-time", + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], "title": "Stopped At", "description": "Timestamp at which the solver finished or killed execution or None if the event did not occur" } @@ -5888,41 +6081,78 @@ "title": "JobStatus", "example": { "job_id": "145beae4-a3a8-4fde-adbb-4e8257c2c083", - "state": "STARTED", "progress": 3, - "submitted_at": "2021-04-01 07:15:54.631007", - "started_at": "2021-04-01 07:16:43.670610" + "started_at": "2021-04-01 07:16:43.670610", + "state": "STARTED", + "submitted_at": "2021-04-01 07:15:54.631007" } }, "Links": { "properties": { "first": { - "type": "string", - "title": "First", - "example": "/api/v1/users?limit=1&offset1" + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "First" }, "last": { - "type": "string", - "title": "Last", - "example": "/api/v1/users?limit=1&offset1" + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last" }, "self": { - "type": "string", - "title": "Self", - "example": "/api/v1/users?limit=1&offset1" + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Self" }, "next": { - "type": "string", - "title": "Next", - "example": "/api/v1/users?limit=1&offset1" + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Next" }, "prev": { - "type": "string", - "title": "Prev", - "example": "/api/v1/users?limit=1&offset1" + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Prev" } }, "type": "object", + "required": [ + "first", + "last", + "self", + "next", + "prev" + ], "title": "Links" }, "LogLink": { @@ -5933,7 +6163,6 @@ }, "download_link": { "type": "string", - "maxLength": 65536, "minLength": 1, "format": "uri", "title": "Download Link" @@ -5958,24 +6187,29 @@ "title": "Version" }, "released": { - "additionalProperties": { - "type": "string", - "pattern": "^(0|[1-9]\\d*)(\\.(0|[1-9]\\d*)){2}(-(0|[1-9]\\d*|\\d*[-a-zA-Z][-\\da-zA-Z]*)(\\.(0|[1-9]\\d*|\\d*[-a-zA-Z][-\\da-zA-Z]*))*)?(\\+[-\\da-zA-Z]+(\\.[-\\da-zA-Z-]+)*)?$" - }, - "type": "object", + "anyOf": [ + { + "additionalProperties": { + "type": "string", + "pattern": "^(0|[1-9]\\d*)(\\.(0|[1-9]\\d*)){2}(-(0|[1-9]\\d*|\\d*[-a-zA-Z][-\\da-zA-Z]*)(\\.(0|[1-9]\\d*|\\d*[-a-zA-Z][-\\da-zA-Z]*))*)?(\\+[-\\da-zA-Z]+(\\.[-\\da-zA-Z-]+)*)?$" + }, + "type": "object" + }, + { + "type": "null" + } + ], "title": "Released", "description": "Maps every route's path tag with a released version" }, "docs_url": { "type": "string", - "maxLength": 65536, "minLength": 1, "format": "uri", "title": "Docs Url" }, "docs_dev_url": { "type": "string", - "maxLength": 65536, "minLength": 1, "format": "uri", "title": "Docs Dev Url" @@ -5990,14 +6224,14 @@ ], "title": "Meta", "example": { + "docs_dev_url": "https://api.osparc.io/dev/doc", + "docs_url": "https://api.osparc.io/dev/doc", "name": "simcore_service_foo", - "version": "2.4.45", "released": { "v1": "1.3.4", "v2": "2.4.45" }, - "docs_url": "https://api.osparc.io/dev/doc", - "docs_dev_url": "https://api.osparc.io/dev/doc" + "version": "2.4.45" } }, "OnePage_SolverPort_": { @@ -6019,8 +6253,7 @@ "required": [ "items" ], - "title": "OnePage[SolverPort]", - "description": "A single page is used to envelope a small sequence that does not require\npagination\n\nIf total > MAXIMUM_NUMBER_OF_ITEMS_PER_PAGE, we should consider extending this\nentrypoint to proper pagination" + "title": "OnePage[SolverPort]" }, "OnePage_StudyPort_": { "properties": { @@ -6041,8 +6274,7 @@ "required": [ "items" ], - "title": "OnePage[StudyPort]", - "description": "A single page is used to envelope a small sequence that does not require\npagination\n\nIf total > MAXIMUM_NUMBER_OF_ITEMS_PER_PAGE, we should consider extending this\nentrypoint to proper pagination" + "title": "OnePage[StudyPort]" }, "Page_File_": { "properties": { @@ -6054,18 +6286,39 @@ "title": "Items" }, "total": { - "type": "integer", - "minimum": 0, + "anyOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "null" + } + ], "title": "Total" }, "limit": { - "type": "integer", - "minimum": 1, + "anyOf": [ + { + "type": "integer", + "minimum": 1 + }, + { + "type": "null" + } + ], "title": "Limit" }, "offset": { - "type": "integer", - "minimum": 0, + "anyOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "null" + } + ], "title": "Offset" }, "links": { @@ -6075,6 +6328,9 @@ "type": "object", "required": [ "items", + "total", + "limit", + "offset", "links" ], "title": "Page[File]" @@ -6089,18 +6345,39 @@ "title": "Items" }, "total": { - "type": "integer", - "minimum": 0, + "anyOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "null" + } + ], "title": "Total" }, "limit": { - "type": "integer", - "minimum": 1, + "anyOf": [ + { + "type": "integer", + "minimum": 1 + }, + { + "type": "null" + } + ], "title": "Limit" }, "offset": { - "type": "integer", - "minimum": 0, + "anyOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "null" + } + ], "title": "Offset" }, "links": { @@ -6110,6 +6387,9 @@ "type": "object", "required": [ "items", + "total", + "limit", + "offset", "links" ], "title": "Page[Job]" @@ -6124,18 +6404,39 @@ "title": "Items" }, "total": { - "type": "integer", - "minimum": 0, + "anyOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "null" + } + ], "title": "Total" }, "limit": { - "type": "integer", - "minimum": 1, + "anyOf": [ + { + "type": "integer", + "minimum": 1 + }, + { + "type": "null" + } + ], "title": "Limit" }, "offset": { - "type": "integer", - "minimum": 0, + "anyOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "null" + } + ], "title": "Offset" }, "links": { @@ -6145,6 +6446,9 @@ "type": "object", "required": [ "items", + "total", + "limit", + "offset", "links" ], "title": "Page[Study]" @@ -6154,8 +6458,8 @@ "enum": [ "TIER" ], - "title": "PricingPlanClassification", - "description": "An enumeration." + "const": "TIER", + "title": "PricingPlanClassification" }, "PricingUnitGet": { "properties": { @@ -6174,7 +6478,7 @@ "title": "Unitextrainfo" }, "currentCostPerUnit": { - "type": "number", + "type": "string", "title": "Currentcostperunit" }, "default": { @@ -6195,16 +6499,28 @@ "Profile": { "properties": { "first_name": { - "type": "string", - "maxLength": 255, - "title": "First Name", - "example": "James" + "anyOf": [ + { + "type": "string", + "maxLength": 255 + }, + { + "type": "null" + } + ], + "title": "First Name" }, "last_name": { - "type": "string", - "maxLength": 255, - "title": "Last Name", - "example": "Maxwell" + "anyOf": [ + { + "type": "string", + "maxLength": 255 + }, + { + "type": "null" + } + ], + "title": "Last Name" }, "id": { "type": "integer", @@ -6221,11 +6537,25 @@ "$ref": "#/components/schemas/UserRoleEnum" }, "groups": { - "$ref": "#/components/schemas/Groups" + "anyOf": [ + { + "$ref": "#/components/schemas/Groups" + }, + { + "type": "null" + } + ] }, "gravatar_id": { - "type": "string", - "maxLength": 40, + "anyOf": [ + { + "type": "string", + "maxLength": 40 + }, + { + "type": "null" + } + ], "title": "Gravatar Id", "description": "md5 hash value of email to retrieve an avatar image from https://www.gravatar.com" } @@ -6238,40 +6568,52 @@ ], "title": "Profile", "example": { - "id": "20", "first_name": "James", - "last_name": "Maxwell", - "login": "james-maxwell@itis.swiss", - "role": "USER", + "gravatar_id": "9a8930a5b20d7048e37740bac5c1ca4f", "groups": { + "all": { + "description": "all users", + "gid": "1", + "label": "Everyone" + }, "me": { + "description": "primary group", "gid": "123", - "label": "maxy", - "description": "primary group" + "label": "maxy" }, - "organizations": [], - "all": { - "gid": "1", - "label": "Everyone", - "description": "all users" - } + "organizations": [] }, - "gravatar_id": "9a8930a5b20d7048e37740bac5c1ca4f" + "id": "20", + "last_name": "Maxwell", + "login": "james-maxwell@itis.swiss", + "role": "USER" } }, "ProfileUpdate": { "properties": { "first_name": { - "type": "string", - "maxLength": 255, - "title": "First Name", - "example": "James" + "anyOf": [ + { + "type": "string", + "maxLength": 255 + }, + { + "type": "null" + } + ], + "title": "First Name" }, "last_name": { - "type": "string", - "maxLength": 255, - "title": "Last Name", - "example": "Maxwell" + "anyOf": [ + { + "type": "string", + "maxLength": 255 + }, + { + "type": "null" + } + ], + "title": "Last Name" } }, "type": "object", @@ -6362,7 +6704,14 @@ "description": "Human readable name" }, "description": { - "type": "string", + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], "title": "Description" }, "maintainer": { @@ -6370,10 +6719,17 @@ "title": "Maintainer" }, "url": { - "type": "string", - "maxLength": 2083, - "minLength": 1, - "format": "uri", + "anyOf": [ + { + "type": "string", + "maxLength": 2083, + "minLength": 1, + "format": "uri" + }, + { + "type": "null" + } + ], "title": "Url", "description": "Link to get this resource" } @@ -6389,12 +6745,12 @@ "title": "Solver", "description": "A released solver with a specific version", "example": { - "id": "simcore/services/comp/isolve", - "version": "2.1.1", - "title": "iSolve", "description": "EM solver", + "id": "simcore/services/comp/isolve", "maintainer": "info@itis.swiss", - "url": "https://api.osparc.io/v0/solvers/simcore%2Fservices%2Fcomp%2Fisolve/releases/2.1.1" + "title": "iSolve", + "url": "https://api.osparc.io/v0/solvers/simcore%2Fservices%2Fcomp%2Fisolve/releases/2.1.1", + "version": "2.1.1" } }, "SolverPort": { @@ -6414,7 +6770,14 @@ "title": "Kind" }, "content_schema": { - "type": "object", + "anyOf": [ + { + "type": "object" + }, + { + "type": "null" + } + ], "title": "Content Schema", "description": "jsonschema for the port's value. SEE https://json-schema.org" } @@ -6426,15 +6789,15 @@ ], "title": "SolverPort", "example": { - "key": "input_2", - "kind": "input", "content_schema": { + "maximum": 5, + "minimum": 0, "title": "Sleep interval", "type": "integer", - "x_unit": "second", - "minimum": 0, - "maximum": 5 - } + "x_unit": "second" + }, + "key": "input_2", + "kind": "input" } }, "Study": { @@ -6476,7 +6839,14 @@ "title": "Kind" }, "content_schema": { - "type": "object", + "anyOf": [ + { + "type": "object" + }, + { + "type": "null" + } + ], "title": "Content Schema", "description": "jsonschema for the port's value. SEE https://json-schema.org" } @@ -6488,15 +6858,15 @@ ], "title": "StudyPort", "example": { - "key": "input_2", - "kind": "input", "content_schema": { + "maximum": 5, + "minimum": 0, "title": "Sleep interval", "type": "integer", - "x_unit": "second", - "minimum": 0, - "maximum": 5 - } + "x_unit": "second" + }, + "key": "input_2", + "kind": "input" } }, "UploadLinks": { @@ -6547,8 +6917,7 @@ "PRODUCT_OWNER", "ADMIN" ], - "title": "UserRoleEnum", - "description": "An enumeration." + "title": "UserRoleEnum" }, "UsersGroup": { "properties": { @@ -6561,7 +6930,14 @@ "title": "Label" }, "description": { - "type": "string", + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], "title": "Description" } }, @@ -6620,7 +6996,14 @@ "title": "Name" }, "description": { - "type": "string", + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], "title": "Description" }, "owner": { @@ -6630,7 +7013,14 @@ "minimum": 0 }, "thumbnail": { - "type": "string", + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], "title": "Thumbnail" }, "status": { @@ -6647,7 +7037,7 @@ "title": "Modified" }, "availableCredits": { - "type": "number", + "type": "string", "title": "Availablecredits" } }, @@ -6655,7 +7045,9 @@ "required": [ "walletId", "name", + "description", "owner", + "thumbnail", "status", "created", "modified", @@ -6669,8 +7061,7 @@ "ACTIVE", "INACTIVE" ], - "title": "WalletStatus", - "description": "An enumeration." + "title": "WalletStatus" } }, "securitySchemes": { diff --git a/services/api-server/tests/unit/test_api_solver_jobs.py b/services/api-server/tests/unit/test_api_solver_jobs.py index 0872b25b873..7bd6178e877 100644 --- a/services/api-server/tests/unit/test_api_solver_jobs.py +++ b/services/api-server/tests/unit/test_api_solver_jobs.py @@ -417,7 +417,8 @@ def _wallet_side_effect( capture: HttpApiCallCaptureModel, ): wallet = TypeAdapter( - Envelope[WalletGetWithAvailableCredits], capture.response_body + Envelope[WalletGetWithAvailableCredits]).validate_python( + capture.response_body ).data assert wallet is not None wallet.available_credits = ( From 866ded6a9736fd2ab27eaf261fc8ea3d77b97122 Mon Sep 17 00:00:00 2001 From: Giancarlo Romeo Date: Tue, 22 Oct 2024 11:43:37 +0200 Subject: [PATCH 25/37] upgrade reqs --- services/api-server/requirements/_base.txt | 227 +++++++++++++++++++-- services/api-server/requirements/_test.txt | 4 + 2 files changed, 215 insertions(+), 16 deletions(-) diff --git a/services/api-server/requirements/_base.txt b/services/api-server/requirements/_base.txt index 4c295d1c773..f76689511a8 100644 --- a/services/api-server/requirements/_base.txt +++ b/services/api-server/requirements/_base.txt @@ -23,17 +23,31 @@ aiofiles==23.2.1 # -r requirements/_base.in aiohttp==3.9.3 # via + # -c requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/models-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/postgres-database/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/postgres-database/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/service-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/settings-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/models-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/postgres-database/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/postgres-database/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/settings-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../requirements/constraints.txt # -c requirements/../../../requirements/constraints.txt @@ -84,17 +98,31 @@ attrs==23.2.0 # jsonschema certifi==2024.2.2 # via + # -c requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/models-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/postgres-database/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/postgres-database/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/service-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/settings-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/models-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/postgres-database/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/postgres-database/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/settings-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../requirements/constraints.txt # -c requirements/../../../requirements/constraints.txt @@ -111,17 +139,31 @@ click==8.1.7 # uvicorn cryptography==42.0.5 # via + # -c requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/models-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/postgres-database/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/postgres-database/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/service-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/settings-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/models-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/postgres-database/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/postgres-database/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/settings-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../requirements/constraints.txt # -c requirements/../../../requirements/constraints.txt @@ -140,22 +182,8 @@ email-validator==2.1.1 # pydantic fast-depends==2.4.2 # via faststream -fastapi==0.114.2 +fastapi==0.115.2 # via - # -c requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt - # -c requirements/../../../packages/postgres-database/requirements/../../../requirements/constraints.txt - # -c requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt - # -c requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt - # -c requirements/../../../packages/service-library/requirements/../../../requirements/constraints.txt - # -c requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt - # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt - # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/postgres-database/requirements/../../../requirements/constraints.txt - # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt - # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt - # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../requirements/constraints.txt - # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt - # -c requirements/../../../packages/simcore-sdk/requirements/../../../requirements/constraints.txt - # -c requirements/../../../requirements/constraints.txt # -r requirements/../../../packages/service-library/requirements/_fastapi.in # -r requirements/_base.in # prometheus-fastapi-instrumentator @@ -193,17 +221,31 @@ httptools==0.6.1 # via uvicorn httpx==0.27.0 # via + # -c requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/models-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/postgres-database/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/postgres-database/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/service-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/settings-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/models-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/postgres-database/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/postgres-database/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/settings-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../requirements/constraints.txt # -c requirements/../../../requirements/constraints.txt @@ -223,17 +265,31 @@ itsdangerous==2.1.2 # via fastapi jinja2==3.1.3 # via + # -c requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/models-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/postgres-database/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/postgres-database/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/service-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/settings-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/models-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/postgres-database/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/postgres-database/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/settings-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../requirements/constraints.txt # -c requirements/../../../requirements/constraints.txt @@ -247,17 +303,31 @@ jsonschema==3.2.0 # -r requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/_base.in mako==1.3.2 # via + # -c requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/models-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/postgres-database/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/postgres-database/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/service-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/settings-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/models-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/postgres-database/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/postgres-database/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/settings-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../requirements/constraints.txt # -c requirements/../../../requirements/constraints.txt @@ -335,17 +405,31 @@ opentelemetry-util-http==0.47b0 # opentelemetry-instrumentation-requests orjson==3.10.0 # via + # -c requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/models-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/postgres-database/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/postgres-database/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/service-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/settings-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/models-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/postgres-database/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/postgres-database/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/settings-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../requirements/constraints.txt # -c requirements/../../../requirements/constraints.txt @@ -387,32 +471,59 @@ pycparser==2.22 # via cffi pydantic==2.9.2 # via + # -c requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/models-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/postgres-database/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/postgres-database/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt - # -c requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/_base.in # -c requirements/../../../packages/service-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/settings-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/models-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/postgres-database/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/postgres-database/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/settings-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../requirements/constraints.txt # -c requirements/../../../requirements/constraints.txt + # -r requirements/../../../packages/common-library/requirements/_base.in + # -r requirements/../../../packages/models-library/requirements/../../../packages/common-library/requirements/_base.in # -r requirements/../../../packages/models-library/requirements/_base.in + # -r requirements/../../../packages/postgres-database/requirements/../../../packages/common-library/requirements/_base.in # -r requirements/../../../packages/postgres-database/requirements/_base.in + # -r requirements/../../../packages/service-library/requirements/../../../packages/common-library/requirements/_base.in + # -r requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../packages/common-library/requirements/_base.in # -r requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/_base.in + # -r requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../packages/common-library/requirements/_base.in # -r requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/_base.in # -r requirements/../../../packages/service-library/requirements/_base.in + # -r requirements/../../../packages/settings-library/requirements/../../../packages/common-library/requirements/_base.in # -r requirements/../../../packages/settings-library/requirements/_base.in + # -r requirements/../../../packages/simcore-sdk/requirements/../../../packages/common-library/requirements/_base.in + # -r requirements/../../../packages/simcore-sdk/requirements/../../../packages/models-library/requirements/../../../packages/common-library/requirements/_base.in # -r requirements/../../../packages/simcore-sdk/requirements/../../../packages/models-library/requirements/_base.in + # -r requirements/../../../packages/simcore-sdk/requirements/../../../packages/postgres-database/requirements/../../../packages/common-library/requirements/_base.in # -r requirements/../../../packages/simcore-sdk/requirements/../../../packages/postgres-database/requirements/_base.in + # -r requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/common-library/requirements/_base.in + # -r requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../packages/common-library/requirements/_base.in # -r requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/_base.in + # -r requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../packages/common-library/requirements/_base.in # -r requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/_base.in # -r requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/_base.in + # -r requirements/../../../packages/simcore-sdk/requirements/../../../packages/settings-library/requirements/../../../packages/common-library/requirements/_base.in # -r requirements/../../../packages/simcore-sdk/requirements/../../../packages/settings-library/requirements/_base.in # -r requirements/../../../packages/simcore-sdk/requirements/_base.in # -r requirements/_base.in @@ -459,17 +570,31 @@ python-multipart==0.0.9 # via fastapi pyyaml==6.0.1 # via + # -c requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/models-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/postgres-database/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/postgres-database/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/service-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/settings-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/models-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/postgres-database/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/postgres-database/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/settings-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../requirements/constraints.txt # -c requirements/../../../requirements/constraints.txt @@ -480,17 +605,31 @@ pyyaml==6.0.1 # uvicorn redis==5.0.4 # via + # -c requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/models-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/postgres-database/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/postgres-database/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/service-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/settings-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/models-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/postgres-database/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/postgres-database/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/settings-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../requirements/constraints.txt # -c requirements/../../../requirements/constraints.txt @@ -525,17 +664,31 @@ sniffio==1.3.1 # httpx sqlalchemy==1.4.52 # via + # -c requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/models-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/postgres-database/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/postgres-database/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/service-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/settings-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/models-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/postgres-database/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/postgres-database/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/settings-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../requirements/constraints.txt # -c requirements/../../../requirements/constraints.txt @@ -545,17 +698,31 @@ sqlalchemy==1.4.52 # alembic starlette==0.38.5 # via + # -c requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/models-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/postgres-database/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/postgres-database/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/service-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/settings-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/models-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/postgres-database/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/postgres-database/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/settings-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../requirements/constraints.txt # -c requirements/../../../requirements/constraints.txt @@ -603,34 +770,62 @@ typing-extensions==4.10.0 # typer ujson==5.9.0 # via + # -c requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/models-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/postgres-database/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/postgres-database/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/service-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/settings-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/models-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/postgres-database/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/postgres-database/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/settings-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../requirements/constraints.txt # -c requirements/../../../requirements/constraints.txt # fastapi urllib3==2.2.2 # via + # -c requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/models-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/postgres-database/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/postgres-database/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/service-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/settings-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/models-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/postgres-database/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/postgres-database/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/models-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/service-library/requirements/../../../requirements/constraints.txt + # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/settings-library/requirements/../../../packages/common-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../packages/settings-library/requirements/../../../requirements/constraints.txt # -c requirements/../../../packages/simcore-sdk/requirements/../../../requirements/constraints.txt # -c requirements/../../../requirements/constraints.txt diff --git a/services/api-server/requirements/_test.txt b/services/api-server/requirements/_test.txt index 07bd8c9d7da..19d8d350199 100644 --- a/services/api-server/requirements/_test.txt +++ b/services/api-server/requirements/_test.txt @@ -104,6 +104,10 @@ frozenlist==1.4.1 # aiosignal graphql-core==3.2.4 # via moto +greenlet==3.0.3 + # via + # -c requirements/_base.txt + # sqlalchemy h11==0.14.0 # via # -c requirements/_base.txt From f68123be87f62060315c9d8c62741860cc89cc8d Mon Sep 17 00:00:00 2001 From: Giancarlo Romeo Date: Tue, 22 Oct 2024 11:58:19 +0200 Subject: [PATCH 26/37] fix mypy --- services/api-server/tests/unit/_with_db/conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/api-server/tests/unit/_with_db/conftest.py b/services/api-server/tests/unit/_with_db/conftest.py index 89cf5f22344..22b2f6b4c84 100644 --- a/services/api-server/tests/unit/_with_db/conftest.py +++ b/services/api-server/tests/unit/_with_db/conftest.py @@ -260,7 +260,7 @@ async def _generate_fake_api_key(n: PositiveInt): row = await result.fetchone() assert row _generate_fake_api_key.row_ids.append(row.id) - yield ApiKeyInDB.from_orm(row) + yield ApiKeyInDB.model_validate(row) _generate_fake_api_key.row_ids = [] yield _generate_fake_api_key From e9abfbd83df64267a4d5a934b7556f4da1898469 Mon Sep 17 00:00:00 2001 From: Giancarlo Romeo Date: Tue, 22 Oct 2024 13:05:21 +0200 Subject: [PATCH 27/37] fix url --- packages/pytest-simcore/src/pytest_simcore/httpbin_service.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/pytest-simcore/src/pytest_simcore/httpbin_service.py b/packages/pytest-simcore/src/pytest_simcore/httpbin_service.py index 6bc71929eb3..d60a6e35fa2 100644 --- a/packages/pytest-simcore/src/pytest_simcore/httpbin_service.py +++ b/packages/pytest-simcore/src/pytest_simcore/httpbin_service.py @@ -14,6 +14,7 @@ import requests import requests.exceptions from docker.errors import APIError +from common_library.pydantic_networks_extension import HttpUrlLegacy from pydantic import HttpUrl, TypeAdapter from tenacity import retry from tenacity.after import after_log @@ -56,7 +57,7 @@ def _wait_until_httpbin_is_responsive(): _wait_until_httpbin_is_responsive() - yield TypeAdapter(HttpUrl).validate_python(base_url) + yield TypeAdapter(HttpUrlLegacy).validate_python(base_url) finally: with suppress(APIError): From 51d1acad8de1d86f1bdc096281b6091b9659dc8d Mon Sep 17 00:00:00 2001 From: Giancarlo Romeo Date: Tue, 22 Oct 2024 13:14:50 +0200 Subject: [PATCH 28/37] fix wallet --- .../src/models_library/api_schemas_webserver/wallets.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/models-library/src/models_library/api_schemas_webserver/wallets.py b/packages/models-library/src/models_library/api_schemas_webserver/wallets.py index 963d3940c4f..0ff5a090c60 100644 --- a/packages/models-library/src/models_library/api_schemas_webserver/wallets.py +++ b/packages/models-library/src/models_library/api_schemas_webserver/wallets.py @@ -22,6 +22,10 @@ class WalletGet(OutputSchema): created: datetime modified: datetime + model_config = ConfigDict( + frozen=False, + ) + class WalletGetWithAvailableCredits(WalletGet): available_credits: Decimal From 245739e7bb3f961fcd72c00b35858df2a2dd0079 Mon Sep 17 00:00:00 2001 From: Giancarlo Romeo Date: Tue, 22 Oct 2024 13:31:28 +0200 Subject: [PATCH 29/37] fix mypy --- services/api-server/tests/unit/test_models_schemas_solvers.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/services/api-server/tests/unit/test_models_schemas_solvers.py b/services/api-server/tests/unit/test_models_schemas_solvers.py index dbdd148be0b..ef2cf5b8917 100644 --- a/services/api-server/tests/unit/test_models_schemas_solvers.py +++ b/services/api-server/tests/unit/test_models_schemas_solvers.py @@ -20,14 +20,14 @@ def test_solvers_sorting_by_name_and_version(faker: Faker): # and a different version of the same # NOTE: that id=None so that it can be re-coputed - earlier_release = one_solver.copy( + earlier_release = one_solver.model_copy( update={"version": f"{one_solver.version}beta"}, deep=True ) assert earlier_release.pep404_version.is_prerelease assert earlier_release.pep404_version < one_solver.pep404_version # and yet a completely different solver - another_solver = one_solver.copy(update={"id": "simcore/services/comp/zSolve"}) + another_solver = one_solver.model_copy(update={"id": "simcore/services/comp/zSolve"}) assert one_solver.id != another_solver.id assert one_solver.pep404_version == another_solver.pep404_version From f8145be9eddfbd93177b0252a656fb4ee057d3e9 Mon Sep 17 00:00:00 2001 From: Giancarlo Romeo Date: Tue, 22 Oct 2024 13:53:29 +0200 Subject: [PATCH 30/37] fix test --- .../tests/unit/test_services_solver_job_outputs.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/services/api-server/tests/unit/test_services_solver_job_outputs.py b/services/api-server/tests/unit/test_services_solver_job_outputs.py index 04765e420f7..131fdd9630d 100644 --- a/services/api-server/tests/unit/test_services_solver_job_outputs.py +++ b/services/api-server/tests/unit/test_services_solver_job_outputs.py @@ -3,7 +3,7 @@ # pylint: disable=unused-variable import types -from typing import get_args, get_origin +from typing import get_args, get_origin, Union from simcore_service_api_server.models.schemas.jobs import ArgumentTypes, File from simcore_service_api_server.services.solver_job_outputs import ( @@ -16,10 +16,11 @@ def test_resultstypes_and_argument_type_sync(): # I/O types returned by node-ports must be one-to-one mapped # with those returned as output results - assert get_origin(ArgumentTypes) == types.UnionType + # Python 3.10 and later treats unions with | as types.UnionType + assert get_origin(ArgumentTypes) in (types.UnionType, Union) argument_types_args = set(get_args(ArgumentTypes)) - assert get_origin(ResultsTypes) == types.UnionType + assert get_origin(ResultsTypes) in (types.UnionType, Union) results_types_args = set(get_args(ResultsTypes)) # files are in the inputs as File (or Raises KeyError if not) From 55f5af5805bf7f69f16362f11af47d64f9e38ada Mon Sep 17 00:00:00 2001 From: Giancarlo Romeo Date: Tue, 22 Oct 2024 16:14:51 +0200 Subject: [PATCH 31/37] fix openapi spec validation --- services/api-server/Makefile | 8 ++------ services/api-server/openapi.json | 2 +- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/services/api-server/Makefile b/services/api-server/Makefile index 14210bb0815..900c0e8e0f1 100644 --- a/services/api-server/Makefile +++ b/services/api-server/Makefile @@ -15,8 +15,8 @@ reqs: ## compiles pip requirements (.in -> .txt) # specification of the used openapi-generator-cli (see also https://github.com/ITISFoundation/openapi-generator) -OPENAPI_GENERATOR_NAME := itisfoundation/openapi-generator-cli-openapi-generator-v4.2.3 -OPENAPI_GENERATOR_TAG := v0 +OPENAPI_GENERATOR_NAME := openapitools/openapi-generator-cli +OPENAPI_GENERATOR_TAG := latest OPENAPI_GENERATOR_IMAGE := $(OPENAPI_GENERATOR_NAME):$(OPENAPI_GENERATOR_TAG) define _create_and_validate_openapi @@ -25,10 +25,6 @@ define _create_and_validate_openapi export API_SERVER_DEV_FEATURES_ENABLED=$1; \ python3 -c "import json; from $(APP_PACKAGE_NAME).main import *; print( json.dumps(the_app.openapi(), indent=2) )" > $@ - # patching version until tools adapted - @sed -i 's/"openapi": "3.1.0",/"openapi": "3.0.2",/g' $@ - - # validates OAS file: $@ docker run --rm \ --volume "$(CURDIR):/local" \ diff --git a/services/api-server/openapi.json b/services/api-server/openapi.json index d2e7c528f95..aa9452aa337 100644 --- a/services/api-server/openapi.json +++ b/services/api-server/openapi.json @@ -1,5 +1,5 @@ { - "openapi": "3.0.2", + "openapi": "3.1.0", "info": { "title": "osparc.io public API", "description": "osparc-simcore public API specifications", From 8bdfa5e2b46a5833e9673edeb256b6b52f51e7cc Mon Sep 17 00:00:00 2001 From: Giancarlo Romeo Date: Tue, 22 Oct 2024 16:34:20 +0200 Subject: [PATCH 32/37] fix serialization --- .../models-library/src/models_library/app_diagnostics.py | 8 ++++---- services/api-server/tests/unit/conftest.py | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/models-library/src/models_library/app_diagnostics.py b/packages/models-library/src/models_library/app_diagnostics.py index b1d19f49f72..ce8c9331eae 100644 --- a/packages/models-library/src/models_library/app_diagnostics.py +++ b/packages/models-library/src/models_library/app_diagnostics.py @@ -1,6 +1,6 @@ -from typing import Annotated, Any +from typing import Any -from pydantic import AfterValidator, AnyUrl, BaseModel, Field +from pydantic import AnyUrl, BaseModel, Field class AppStatusCheck(BaseModel): @@ -15,11 +15,11 @@ class AppStatusCheck(BaseModel): description="Client sessions info. If single session per app, then is denoted as main", ) - url: Annotated[AnyUrl, AfterValidator(str)] | None = Field( + url: AnyUrl | None = Field( default=None, description="Link to current resource", ) - diagnostics_url: Annotated[AnyUrl, AfterValidator(str)] | None = Field( + diagnostics_url: AnyUrl | None = Field( default=None, description="Link to diagnostics report sub-resource. This MIGHT take some time to compute", ) diff --git a/services/api-server/tests/unit/conftest.py b/services/api-server/tests/unit/conftest.py index 7da1d115020..939f7bf9170 100644 --- a/services/api-server/tests/unit/conftest.py +++ b/services/api-server/tests/unit/conftest.py @@ -378,7 +378,7 @@ def mocked_storage_service_api_base( "url": faker.url(), "diagnostics_url": faker.url(), } - ).model_dump(), + ).model_dump(mode="json"), ) # SEE https://github.com/pcrespov/sandbox-python/blob/f650aad57aced304aac9d0ad56c00723d2274ad0/respx-lib/test_disable_mock.py From be61302030dea55d58d462bc956ddf7ac19b9d97 Mon Sep 17 00:00:00 2001 From: Giancarlo Romeo Date: Tue, 22 Oct 2024 16:40:03 +0200 Subject: [PATCH 33/37] revert HttpUrl legacy --- packages/pytest-simcore/src/pytest_simcore/httpbin_service.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/pytest-simcore/src/pytest_simcore/httpbin_service.py b/packages/pytest-simcore/src/pytest_simcore/httpbin_service.py index d60a6e35fa2..6bc71929eb3 100644 --- a/packages/pytest-simcore/src/pytest_simcore/httpbin_service.py +++ b/packages/pytest-simcore/src/pytest_simcore/httpbin_service.py @@ -14,7 +14,6 @@ import requests import requests.exceptions from docker.errors import APIError -from common_library.pydantic_networks_extension import HttpUrlLegacy from pydantic import HttpUrl, TypeAdapter from tenacity import retry from tenacity.after import after_log @@ -57,7 +56,7 @@ def _wait_until_httpbin_is_responsive(): _wait_until_httpbin_is_responsive() - yield TypeAdapter(HttpUrlLegacy).validate_python(base_url) + yield TypeAdapter(HttpUrl).validate_python(base_url) finally: with suppress(APIError): From c15224e412e0eda5807c91ab0de5de9c046e9406 Mon Sep 17 00:00:00 2001 From: Giancarlo Romeo Date: Tue, 22 Oct 2024 22:17:45 +0200 Subject: [PATCH 34/37] fix url --- .../api-server/tests/unit/test_utils_http_calls_capture.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/services/api-server/tests/unit/test_utils_http_calls_capture.py b/services/api-server/tests/unit/test_utils_http_calls_capture.py index c11ec04411d..3322865ea2d 100644 --- a/services/api-server/tests/unit/test_utils_http_calls_capture.py +++ b/services/api-server/tests/unit/test_utils_http_calls_capture.py @@ -22,7 +22,7 @@ async def test_capture_http_call( ): # CAPTURE async with httpx.AsyncClient() as client: - response: httpx.Response = await client.get(f"{httpbin_base_url}/json") + response: httpx.Response = await client.get(f"{httpbin_base_url}json") print(response) _request: httpx.Request = response.request @@ -64,7 +64,7 @@ async def test_capture_http_dynamic_call( sample_uid = faker.uuid4() # used during test sampling response: httpx.Response = await client.post( - f"{httpbin_base_url}/anything/{sample_uid}", + f"{httpbin_base_url}anything/{sample_uid!r}", params={"n": 42}, json={ "resource_id": sample_uid, From 003aff8a140999356e113e0262e75bd713bc6a86 Mon Sep 17 00:00:00 2001 From: Giancarlo Romeo Date: Tue, 22 Oct 2024 22:52:59 +0200 Subject: [PATCH 35/37] fix http --- .../api-server/tests/unit/test_utils_http_calls_capture.py | 7 ++++--- services/storage/tests/unit/test_utils.py | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/services/api-server/tests/unit/test_utils_http_calls_capture.py b/services/api-server/tests/unit/test_utils_http_calls_capture.py index 3322865ea2d..013c3a6b6a9 100644 --- a/services/api-server/tests/unit/test_utils_http_calls_capture.py +++ b/services/api-server/tests/unit/test_utils_http_calls_capture.py @@ -10,6 +10,7 @@ import httpx import jinja2 +import pytest import respx from faker import Faker from models_library.basic_regex import UUID_RE_BASE @@ -64,7 +65,7 @@ async def test_capture_http_dynamic_call( sample_uid = faker.uuid4() # used during test sampling response: httpx.Response = await client.post( - f"{httpbin_base_url}anything/{sample_uid!r}", + f"{httpbin_base_url}anything/{sample_uid}", params={"n": 42}, json={ "resource_id": sample_uid, @@ -100,7 +101,7 @@ async def test_capture_http_dynamic_call( respx_mock.request( method=captured.method, path__regex=re.sub( - f"{sample_uid}", pattern, captured.path + f"{sample_uid!r}", pattern, captured.path ), # using REGEX name=captured.name, ).respond( @@ -110,7 +111,7 @@ async def test_capture_http_dynamic_call( other_uid = faker.uuid4() - response: httpx.Response = await client.post( + response = await client.post( f"http://test.it/anything/{other_uid}", params={"n": 42}, json={ diff --git a/services/storage/tests/unit/test_utils.py b/services/storage/tests/unit/test_utils.py index 90dca22d42d..b830ac112a5 100644 --- a/services/storage/tests/unit/test_utils.py +++ b/services/storage/tests/unit/test_utils.py @@ -34,7 +34,7 @@ async def test_download_files(tmp_path: Path, httpbin_base_url: HttpUrl): async with ClientSession() as session: total_size = await download_to_file_or_raise( - session, f"{httpbin_base_url}/bytes/{expected_size}", destination + session, f"{httpbin_base_url}bytes/{expected_size}", destination ) assert destination.exists() assert expected_size == total_size From 3c0c9feffdbaa8b02f85a8ca92cbf6f8e3f0ab9d Mon Sep 17 00:00:00 2001 From: Giancarlo Romeo Date: Tue, 22 Oct 2024 23:01:58 +0200 Subject: [PATCH 36/37] fix mock --- services/api-server/tests/unit/test_utils_http_calls_capture.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/api-server/tests/unit/test_utils_http_calls_capture.py b/services/api-server/tests/unit/test_utils_http_calls_capture.py index 013c3a6b6a9..aec291bef4f 100644 --- a/services/api-server/tests/unit/test_utils_http_calls_capture.py +++ b/services/api-server/tests/unit/test_utils_http_calls_capture.py @@ -101,7 +101,7 @@ async def test_capture_http_dynamic_call( respx_mock.request( method=captured.method, path__regex=re.sub( - f"{sample_uid!r}", pattern, captured.path + f"{sample_uid}", pattern, captured.path ), # using REGEX name=captured.name, ).respond( From 08ea53028f4b9281180947ba505900bde78b1620 Mon Sep 17 00:00:00 2001 From: Giancarlo Romeo Date: Tue, 22 Oct 2024 23:25:26 +0200 Subject: [PATCH 37/37] fix starlette exception handlers --- .../exceptions/handlers/__init__.py | 12 ++++++------ .../exceptions/handlers/_custom_errors.py | 3 ++- .../exceptions/handlers/_handlers_backend_errors.py | 6 +++--- .../exceptions/handlers/_http_exceptions.py | 4 +++- .../exceptions/handlers/_httpx_client_exceptions.py | 3 ++- .../exceptions/handlers/_log_streaming_errors.py | 5 ++--- .../exceptions/handlers/_validation_errors.py | 3 ++- 7 files changed, 20 insertions(+), 16 deletions(-) diff --git a/services/api-server/src/simcore_service_api_server/exceptions/handlers/__init__.py b/services/api-server/src/simcore_service_api_server/exceptions/handlers/__init__.py index 239de8d7a92..d2779338980 100644 --- a/services/api-server/src/simcore_service_api_server/exceptions/handlers/__init__.py +++ b/services/api-server/src/simcore_service_api_server/exceptions/handlers/__init__.py @@ -18,12 +18,12 @@ def setup(app: FastAPI, *, is_debug: bool = False): - app.add_exception_handler(HTTPException, http_exception_handler) # type: ignore[arg-type] - app.add_exception_handler(HttpxException, handle_httpx_client_exceptions) # type: ignore[arg-type] - app.add_exception_handler(RequestValidationError, http422_error_handler) # type: ignore[arg-type] - app.add_exception_handler(LogStreamingBaseError, log_handling_error_handler) # type: ignore[arg-type] - app.add_exception_handler(CustomBaseError, custom_error_handler) # type: ignore[arg-type] - app.add_exception_handler(BaseBackEndError, backend_error_handler) # type: ignore[arg-type] + app.add_exception_handler(HTTPException, http_exception_handler) + app.add_exception_handler(HttpxException, handle_httpx_client_exceptions) + app.add_exception_handler(RequestValidationError, http422_error_handler) + app.add_exception_handler(LogStreamingBaseError, log_handling_error_handler) + app.add_exception_handler(CustomBaseError, custom_error_handler) + app.add_exception_handler(BaseBackEndError, backend_error_handler) # SEE https://docs.python.org/3/library/exceptions.html#exception-hierarchy app.add_exception_handler( diff --git a/services/api-server/src/simcore_service_api_server/exceptions/handlers/_custom_errors.py b/services/api-server/src/simcore_service_api_server/exceptions/handlers/_custom_errors.py index 48ab4aeab11..558b5191f59 100644 --- a/services/api-server/src/simcore_service_api_server/exceptions/handlers/_custom_errors.py +++ b/services/api-server/src/simcore_service_api_server/exceptions/handlers/_custom_errors.py @@ -8,8 +8,9 @@ from ._utils import create_error_json_response -async def custom_error_handler(request: Request, exc: CustomBaseError): +async def custom_error_handler(request: Request, exc: Exception): assert request # nosec + assert isinstance(exc, CustomBaseError) error_msg = f"{exc}" if isinstance(exc, InsufficientCreditsError): diff --git a/services/api-server/src/simcore_service_api_server/exceptions/handlers/_handlers_backend_errors.py b/services/api-server/src/simcore_service_api_server/exceptions/handlers/_handlers_backend_errors.py index e1dc19c26ea..e46d0f8f977 100644 --- a/services/api-server/src/simcore_service_api_server/exceptions/handlers/_handlers_backend_errors.py +++ b/services/api-server/src/simcore_service_api_server/exceptions/handlers/_handlers_backend_errors.py @@ -5,8 +5,8 @@ from ._utils import create_error_json_response -async def backend_error_handler( - request: Request, exc: BaseBackEndError -) -> JSONResponse: +async def backend_error_handler(request: Request, exc: Exception) -> JSONResponse: assert request # nosec + assert isinstance(exc, BaseBackEndError) + return create_error_json_response(f"{exc}", status_code=exc.status_code) diff --git a/services/api-server/src/simcore_service_api_server/exceptions/handlers/_http_exceptions.py b/services/api-server/src/simcore_service_api_server/exceptions/handlers/_http_exceptions.py index f0a03e2605b..0eac9c1789b 100644 --- a/services/api-server/src/simcore_service_api_server/exceptions/handlers/_http_exceptions.py +++ b/services/api-server/src/simcore_service_api_server/exceptions/handlers/_http_exceptions.py @@ -5,6 +5,8 @@ from ._utils import create_error_json_response -async def http_exception_handler(request: Request, exc: HTTPException) -> JSONResponse: +async def http_exception_handler(request: Request, exc: Exception) -> JSONResponse: assert request # nosec + assert isinstance(exc, HTTPException) + return create_error_json_response(exc.detail, status_code=exc.status_code) diff --git a/services/api-server/src/simcore_service_api_server/exceptions/handlers/_httpx_client_exceptions.py b/services/api-server/src/simcore_service_api_server/exceptions/handlers/_httpx_client_exceptions.py index 265e68c9115..99989de85e3 100644 --- a/services/api-server/src/simcore_service_api_server/exceptions/handlers/_httpx_client_exceptions.py +++ b/services/api-server/src/simcore_service_api_server/exceptions/handlers/_httpx_client_exceptions.py @@ -14,13 +14,14 @@ _logger = logging.getLogger(__file__) -async def handle_httpx_client_exceptions(request: Request, exc: HTTPError): +async def handle_httpx_client_exceptions(request: Request, exc: Exception): """ Default httpx exception handler. See https://www.python-httpx.org/exceptions/ With this in place only HTTPStatusErrors need to be customized closer to the httpx client itself. """ assert request # nosec + assert isinstance(exc, HTTPError) status_code: Any detail: str diff --git a/services/api-server/src/simcore_service_api_server/exceptions/handlers/_log_streaming_errors.py b/services/api-server/src/simcore_service_api_server/exceptions/handlers/_log_streaming_errors.py index 066ee5dd2d6..9340b9fcbd8 100644 --- a/services/api-server/src/simcore_service_api_server/exceptions/handlers/_log_streaming_errors.py +++ b/services/api-server/src/simcore_service_api_server/exceptions/handlers/_log_streaming_errors.py @@ -10,10 +10,9 @@ from ._utils import create_error_json_response -async def log_handling_error_handler( - request: Request, exc: LogStreamingBaseError -) -> JSONResponse: +async def log_handling_error_handler(request: Request, exc: Exception) -> JSONResponse: assert request # nosec + assert isinstance(exc, LogStreamingBaseError) msg = f"{exc}" status_code: int = status.HTTP_500_INTERNAL_SERVER_ERROR diff --git a/services/api-server/src/simcore_service_api_server/exceptions/handlers/_validation_errors.py b/services/api-server/src/simcore_service_api_server/exceptions/handlers/_validation_errors.py index de7fd25fecf..f7d5f0d7c93 100644 --- a/services/api-server/src/simcore_service_api_server/exceptions/handlers/_validation_errors.py +++ b/services/api-server/src/simcore_service_api_server/exceptions/handlers/_validation_errors.py @@ -10,9 +10,10 @@ async def http422_error_handler( request: Request, - exc: RequestValidationError | ValidationError, + exc: Exception, ) -> JSONResponse: assert request # nosec + assert isinstance(exc, RequestValidationError | ValidationError) return create_error_json_response( *exc.errors(), status_code=status.HTTP_422_UNPROCESSABLE_ENTITY