From 297f79f1f32040006d3859ae17cf47bec4ccdb8b Mon Sep 17 00:00:00 2001 From: Pedro Crespo-Valero <32402063+pcrespov@users.noreply.github.com> Date: Thu, 3 Oct 2024 18:41:52 +0200 Subject: [PATCH 1/7] exposes api used by @mguidon --- .../api/routes/files.py | 30 ++++--------------- .../api/routes/solvers.py | 3 +- .../api/routes/solvers_jobs.py | 7 ++--- .../api/routes/solvers_jobs_getters.py | 7 +++-- .../api/routes/wallets.py | 6 ++-- 5 files changed, 16 insertions(+), 37 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 a89771dc490..76110352782 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 @@ -2,7 +2,6 @@ import datetime import io import logging -from textwrap import dedent from typing import IO, Annotated, Any from uuid import UUID @@ -10,7 +9,6 @@ from fastapi import File as FileParam from fastapi import Header, Request, UploadFile, status from fastapi.exceptions import HTTPException -from fastapi.responses import HTMLResponse from fastapi_pagination.api import create_page from models_library.api_schemas_storage import ETag, FileUploadCompletionBody, LinkType from models_library.basic_types import SHA256Str @@ -29,7 +27,6 @@ from starlette.datastructures import URL from starlette.responses import RedirectResponse -from ..._meta import API_VTAG from ...exceptions.service_errors_utils import DEFAULT_BACKEND_SERVICE_STATUS_CODES from ...models.pagination import Page, PaginationParams from ...models.schemas.errors import ErrorGet @@ -158,7 +155,11 @@ def _get_spooled_file_size(file_io: IO) -> int: return file_size -@router.put("/content", response_model=File, responses=_FILE_STATUS_CODES) +@router.put( + "/content", + response_model=File, + responses=_FILE_STATUS_CODES, +) @cancel_on_disconnect async def upload_file( request: Request, @@ -433,24 +434,3 @@ async def download_file( _logger.info("Downloading %s to %s ...", file_meta, presigned_download_link) return RedirectResponse(presigned_download_link) - - -async def files_upload_multiple_view(): - """Extra **Web form** to upload multiple files at http://localhost:8000/v0/files/upload-form-view - and overcomes the limitations of Swagger-UI view - - NOTE: Only enabled if DEBUG=1 - NOTE: As of 2020-10-07, Swagger UI doesn't support multiple file uploads in the same form field - """ - return HTMLResponse( - content=dedent( - f""" - -
- - -
- - """ - ) - ) 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..01e58dc2653 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 @@ -265,7 +265,8 @@ async def list_solver_ports( @router.get( "/{solver_key:path}/releases/{version}/pricing_plan", response_model=ServicePricingPlanGet, - include_in_schema=API_SERVER_DEV_FEATURES_ENABLED, + description="Gets solver pricing plan\n\n" + + FMSG_CHANGELOG_NEW_IN_VERSION.format("0.7"), responses=_SOLVER_STATUS_CODES, ) async def get_solver_pricing_plan( 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..0cdbfdf7e0a 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 @@ -40,7 +40,6 @@ from ..dependencies.authentication import get_current_user_id, get_product_name from ..dependencies.services import get_api_client from ..dependencies.webserver import AuthSession, get_webserver_session -from ._common import API_SERVER_DEV_FEATURES_ENABLED from ._constants import FMSG_CHANGELOG_ADDED_IN_VERSION, FMSG_CHANGELOG_NEW_IN_VERSION _logger = logging.getLogger(__name__) @@ -145,9 +144,8 @@ async def create_job( "/{solver_key:path}/releases/{version}/jobs/{job_id:uuid}", status_code=status.HTTP_204_NO_CONTENT, responses=JOBS_STATUS_CODES, - include_in_schema=API_SERVER_DEV_FEATURES_ENABLED, description="Deletes an existing solver job\n\n" - + FMSG_CHANGELOG_NEW_IN_VERSION.format("0.5"), + + FMSG_CHANGELOG_NEW_IN_VERSION.format("0.7"), ) async def delete_job( solver_key: SolverKeyId, @@ -271,9 +269,8 @@ async def inspect_job( "/{solver_key:path}/releases/{version}/jobs/{job_id:uuid}/metadata", response_model=JobMetadata, responses=METADATA_STATUS_CODES, - include_in_schema=API_SERVER_DEV_FEATURES_ENABLED, description="Updates custom metadata from a job\n\n" - + FMSG_CHANGELOG_NEW_IN_VERSION.format("0.5"), + + FMSG_CHANGELOG_NEW_IN_VERSION.format("0.7"), ) async def replace_job_custom_metadata( solver_key: SolverKeyId, 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..857e67d0116 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 @@ -116,6 +116,7 @@ "/{solver_key:path}/releases/{version}/jobs", response_model=list[Job], responses=JOBS_STATUS_CODES, + deprecated=True, ) async def list_jobs( solver_key: SolverKeyId, @@ -129,6 +130,8 @@ async def list_jobs( """List of jobs in a specific released solver (limited to 20 jobs) SEE `get_jobs_page` for paginated version of this function + NOTE: This implementation and returned values are deprecated and the + will be replaced by that of get_jobs_page """ solver = await catalog_client.get_service( @@ -158,7 +161,6 @@ async def list_jobs( "/{solver_key:path}/releases/{version}/jobs/page", response_model=Page[Job], responses=JOBS_STATUS_CODES, - include_in_schema=API_SERVER_DEV_FEATURES_ENABLED, description=( "List of jobs on a specific released solver (includes pagination)\n\n" + FMSG_CHANGELOG_NEW_IN_VERSION.format("0.7") @@ -349,9 +351,8 @@ async def get_job_output_logfile( "/{solver_key:path}/releases/{version}/jobs/{job_id:uuid}/metadata", response_model=JobMetadata, responses=METADATA_STATUS_CODES, - include_in_schema=API_SERVER_DEV_FEATURES_ENABLED, description="Gets custom metadata from a job\n\n" - + FMSG_CHANGELOG_NEW_IN_VERSION.format("0.5"), + + FMSG_CHANGELOG_NEW_IN_VERSION.format("0.7"), ) async def get_job_custom_metadata( solver_key: SolverKeyId, diff --git a/services/api-server/src/simcore_service_api_server/api/routes/wallets.py b/services/api-server/src/simcore_service_api_server/api/routes/wallets.py index 0043dce6157..0b3df66b1d5 100644 --- a/services/api-server/src/simcore_service_api_server/api/routes/wallets.py +++ b/services/api-server/src/simcore_service_api_server/api/routes/wallets.py @@ -7,7 +7,7 @@ from ...exceptions.service_errors_utils import DEFAULT_BACKEND_SERVICE_STATUS_CODES from ...models.schemas.errors import ErrorGet from ..dependencies.webserver import AuthSession, get_webserver_session -from ._common import API_SERVER_DEV_FEATURES_ENABLED +from ._constants import FMSG_CHANGELOG_NEW_IN_VERSION _logger = logging.getLogger(__name__) @@ -28,8 +28,8 @@ @router.get( "/default", + description="Get default wallet\n\n" + FMSG_CHANGELOG_NEW_IN_VERSION.format("0.7"), response_model=WalletGetWithAvailableCredits, - include_in_schema=API_SERVER_DEV_FEATURES_ENABLED, responses=WALLET_STATUS_CODES, ) async def get_default_wallet( @@ -41,8 +41,8 @@ async def get_default_wallet( @router.get( "/{wallet_id}", response_model=WalletGetWithAvailableCredits, - include_in_schema=API_SERVER_DEV_FEATURES_ENABLED, responses=WALLET_STATUS_CODES, + description="Get wallet\n\n" + FMSG_CHANGELOG_NEW_IN_VERSION.format("0.7"), ) async def get_wallet( wallet_id: int, From 93b651af85ec9d943ed87918dd32645bc8f368b4 Mon Sep 17 00:00:00 2001 From: Pedro Crespo-Valero <32402063+pcrespov@users.noreply.github.com> Date: Thu, 3 Oct 2024 18:42:06 +0200 Subject: [PATCH 2/7] update OAS --- services/api-server/openapi.json | 1417 +++++++++++++++++++++++++++--- 1 file changed, 1283 insertions(+), 134 deletions(-) diff --git a/services/api-server/openapi.json b/services/api-server/openapi.json index 8ade6cff614..92261f29f62 100644 --- a/services/api-server/openapi.json +++ b/services/api-server/openapi.json @@ -1869,13 +1869,132 @@ ] } }, + "/v0/solvers/{solver_key}/releases/{version}/pricing_plan": { + "get": { + "tags": [ + "solvers" + ], + "summary": "Get Solver Pricing Plan", + "description": "Gets solver pricing plan\n\nNew in *version 0.7*", + "operationId": "get_solver_pricing_plan", + "parameters": [ + { + "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" + }, + { + "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": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServicePricingPlanGet" + } + } + } + }, + "404": { + "description": "Not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorGet" + } + } + } + }, + "429": { + "description": "Too many requests", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorGet" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorGet" + } + } + } + }, + "502": { + "description": "Unexpected error when communicating with backend service", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorGet" + } + } + } + }, + "503": { + "description": "Service unavailable", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorGet" + } + } + } + }, + "504": { + "description": "Request to a backend service timed out.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorGet" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + }, + "security": [ + { + "HTTPBasic": [] + } + ] + } + }, "/v0/solvers/{solver_key}/releases/{version}/jobs": { "get": { "tags": [ "solvers" ], "summary": "List Jobs", - "description": "List of jobs in a specific released solver (limited to 20 jobs)\n\nSEE `get_jobs_page` for paginated version of this function", + "description": "List of jobs in a specific released solver (limited to 20 jobs)\n\nSEE `get_jobs_page` for paginated version of this function\nNOTE: This implementation and returned values are deprecated and the\n will be replaced by that of get_jobs_page", "operationId": "list_jobs", "parameters": [ { @@ -1995,6 +2114,7 @@ } } }, + "deprecated": true, "security": [ { "HTTPBasic": [] @@ -2169,14 +2289,14 @@ ] } }, - "/v0/solvers/{solver_key}/releases/{version}/jobs/{job_id}:start": { - "post": { + "/v0/solvers/{solver_key}/releases/{version}/jobs/{job_id}": { + "get": { "tags": [ "solvers" ], - "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", + "summary": "Get Job", + "description": "Gets job of a given solver", + "operationId": "get_job", "parameters": [ { "required": true, @@ -2207,25 +2327,15 @@ }, "name": "job_id", "in": "path" - }, - { - "required": false, - "schema": { - "type": "integer", - "minimum": 0, - "title": "Cluster Id" - }, - "name": "cluster_id", - "in": "query" } ], "responses": { - "202": { + "200": { "description": "Successful Response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/JobStatus" + "$ref": "#/components/schemas/Job" } } } @@ -2300,32 +2410,12 @@ } } }, - "200": { - "description": "Job already started", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/JobStatus" - } - } - } - }, - "406": { - "description": "Cluster not found", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorGet" - } - } - } - }, "422": { - "description": "Configuration error", + "description": "Validation Error", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ErrorGet" + "$ref": "#/components/schemas/HTTPValidationError" } } } @@ -2336,15 +2426,14 @@ "HTTPBasic": [] } ] - } - }, - "/v0/solvers/{solver_key}/releases/{version}/jobs/{job_id}:stop": { - "post": { + }, + "delete": { "tags": [ "solvers" ], - "summary": "Stop Job", - "operationId": "stop_job", + "summary": "Delete Job", + "description": "Deletes an existing solver job\n\nNew in *version 0.7*", + "operationId": "delete_job", "parameters": [ { "required": true, @@ -2378,15 +2467,8 @@ } ], "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/JobStatus" - } - } - } + "204": { + "description": "Successful Response" }, "402": { "description": "Payment required", @@ -2476,13 +2558,14 @@ ] } }, - "/v0/solvers/{solver_key}/releases/{version}/jobs/{job_id}:inspect": { + "/v0/solvers/{solver_key}/releases/{version}/jobs/{job_id}:start": { "post": { "tags": [ "solvers" ], - "summary": "Inspect Job", - "operationId": "inspect_job", + "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", "parameters": [ { "required": true, @@ -2513,10 +2596,20 @@ }, "name": "job_id", "in": "path" + }, + { + "required": false, + "schema": { + "type": "integer", + "minimum": 0, + "title": "Cluster Id" + }, + "name": "cluster_id", + "in": "query" } ], "responses": { - "200": { + "202": { "description": "Successful Response", "content": { "application/json": { @@ -2596,12 +2689,32 @@ } } }, + "200": { + "description": "Job already started", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/JobStatus" + } + } + } + }, + "406": { + "description": "Cluster not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorGet" + } + } + } + }, "422": { - "description": "Validation Error", + "description": "Configuration error", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "$ref": "#/components/schemas/ErrorGet" } } } @@ -2614,14 +2727,13 @@ ] } }, - "/v0/solvers/{solver_key}/releases/{version}/jobs/{job_id}": { - "get": { + "/v0/solvers/{solver_key}/releases/{version}/jobs/{job_id}:stop": { + "post": { "tags": [ "solvers" ], - "summary": "Get Job", - "description": "Gets job of a given solver", - "operationId": "get_job", + "summary": "Stop Job", + "operationId": "stop_job", "parameters": [ { "required": true, @@ -2640,18 +2752,574 @@ "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": "version", + "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/JobStatus" + } + } + } + }, + "402": { + "description": "Payment required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorGet" + } + } + } + }, + "404": { + "description": "Job/wallet/pricing details not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorGet" + } + } + } + }, + "429": { + "description": "Too many requests", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorGet" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorGet" + } + } + } + }, + "502": { + "description": "Unexpected error when communicating with backend service", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorGet" + } + } + } + }, + "503": { + "description": "Service unavailable", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorGet" + } + } + } + }, + "504": { + "description": "Request to a backend service timed out.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorGet" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + }, + "security": [ + { + "HTTPBasic": [] + } + ] + } + }, + "/v0/solvers/{solver_key}/releases/{version}/jobs/{job_id}:inspect": { + "post": { + "tags": [ + "solvers" + ], + "summary": "Inspect Job", + "operationId": "inspect_job", + "parameters": [ + { + "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" + }, + { + "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": 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/JobStatus" + } + } + } + }, + "402": { + "description": "Payment required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorGet" + } + } + } + }, + "404": { + "description": "Job/wallet/pricing details not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorGet" + } + } + } + }, + "429": { + "description": "Too many requests", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorGet" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorGet" + } + } + } + }, + "502": { + "description": "Unexpected error when communicating with backend service", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorGet" + } + } + } + }, + "503": { + "description": "Service unavailable", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorGet" + } + } + } + }, + "504": { + "description": "Request to a backend service timed out.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorGet" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + }, + "security": [ + { + "HTTPBasic": [] + } + ] + } + }, + "/v0/solvers/{solver_key}/releases/{version}/jobs/{job_id}/metadata": { + "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", + "parameters": [ + { + "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" + }, + { + "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": 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/JobMetadata" + } + } + } + }, + "404": { + "description": "Metadata not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorGet" + } + } + } + }, + "429": { + "description": "Too many requests", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorGet" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorGet" + } + } + } + }, + "502": { + "description": "Unexpected error when communicating with backend service", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorGet" + } + } + } + }, + "503": { + "description": "Service unavailable", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorGet" + } + } + } + }, + "504": { + "description": "Request to a backend service timed out.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorGet" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + }, + "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": [ + { + "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" + }, + { + "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": 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", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/JobMetadata" + } + } + } + }, + "404": { + "description": "Metadata not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorGet" + } + } + } + }, + "429": { + "description": "Too many requests", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorGet" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorGet" + } + } + } + }, + "502": { + "description": "Unexpected error when communicating with backend service", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorGet" + } + } + } + }, + "503": { + "description": "Service unavailable", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorGet" + } + } + } + }, + "504": { + "description": "Request to a backend service timed out.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorGet" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + }, + "security": [ + { + "HTTPBasic": [] + } + ] + } + }, + "/v0/solvers/{solver_key}/releases/{version}/jobs/page": { + "get": { + "tags": [ + "solvers" + ], + "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", + "parameters": [ + { + "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" + }, + { + "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": "integer", + "maximum": 100, + "minimum": 1, + "title": "Limit", + "default": 50 + }, + "name": "limit", + "in": "query" }, { - "required": true, + "required": false, "schema": { - "type": "string", - "format": "uuid", - "title": "Job Id" + "type": "integer", + "minimum": 0, + "title": "Offset", + "default": 0 }, - "name": "job_id", - "in": "path" + "name": "offset", + "in": "query" } ], "responses": { @@ -2660,7 +3328,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Job" + "$ref": "#/components/schemas/Page_Job_" } } } @@ -3867,82 +4535,297 @@ "name": "study_id", "in": "path" }, - { - "required": true, - "schema": { - "type": "string", - "format": "uuid", - "title": "Job Id" - }, - "name": "job_id", - "in": "path" - } - ], - "responses": { - "200": { - "description": "Successful Response", + { + "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/JobOutputs" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + }, + "security": [ + { + "HTTPBasic": [] + } + ] + } + }, + "/v0/studies/{study_id}/jobs/{job_id}/outputs/log-links": { + "get": { + "tags": [ + "studies" + ], + "summary": "Get download links for study job log files", + "operationId": "get_study_job_output_logfile", + "parameters": [ + { + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Study Id" + }, + "name": "study_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/JobLogsMap" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + }, + "security": [ + { + "HTTPBasic": [] + } + ] + } + }, + "/v0/wallets/default": { + "get": { + "tags": [ + "wallets" + ], + "summary": "Get Default Wallet", + "description": "Get default wallet\n\nNew in *version 0.7*", + "operationId": "get_default_wallet", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/WalletGetWithAvailableCredits" + } + } + } + }, + "404": { + "description": "Wallet not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorGet" + } + } + } + }, + "403": { + "description": "Access to wallet is not allowed", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorGet" + } + } + } + }, + "429": { + "description": "Too many requests", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorGet" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorGet" + } + } + } + }, + "502": { + "description": "Unexpected error when communicating with backend service", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorGet" + } + } + } + }, + "503": { + "description": "Service unavailable", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorGet" + } + } + } + }, + "504": { + "description": "Request to a backend service timed out.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorGet" + } + } + } + } + }, + "security": [ + { + "HTTPBasic": [] + } + ] + } + }, + "/v0/wallets/{wallet_id}": { + "get": { + "tags": [ + "wallets" + ], + "summary": "Get Wallet", + "description": "Get wallet\n\nNew in *version 0.7*", + "operationId": "get_wallet", + "parameters": [ + { + "required": true, + "schema": { + "type": "integer", + "title": "Wallet Id" + }, + "name": "wallet_id", + "in": "path" + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/WalletGetWithAvailableCredits" + } + } + } + }, + "404": { + "description": "Wallet not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorGet" + } + } + } + }, + "403": { + "description": "Access to wallet is not allowed", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorGet" + } + } + } + }, + "429": { + "description": "Too many requests", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorGet" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorGet" + } + } + } + }, + "502": { + "description": "Unexpected error when communicating with backend service", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/JobOutputs" + "$ref": "#/components/schemas/ErrorGet" } } } }, - "422": { - "description": "Validation Error", + "503": { + "description": "Service unavailable", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "$ref": "#/components/schemas/ErrorGet" } } } - } - }, - "security": [ - { - "HTTPBasic": [] - } - ] - } - }, - "/v0/studies/{study_id}/jobs/{job_id}/outputs/log-links": { - "get": { - "tags": [ - "studies" - ], - "summary": "Get download links for study job log files", - "operationId": "get_study_job_output_logfile", - "parameters": [ - { - "required": true, - "schema": { - "type": "string", - "format": "uuid", - "title": "Study Id" - }, - "name": "study_id", - "in": "path" }, - { - "required": true, - "schema": { - "type": "string", - "format": "uuid", - "title": "Job Id" - }, - "name": "job_id", - "in": "path" - } - ], - "responses": { - "200": { - "description": "Successful Response", + "504": { + "description": "Request to a backend service timed out.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/JobLogsMap" + "$ref": "#/components/schemas/ErrorGet" } } } @@ -4438,6 +5321,79 @@ ], "title": "JobLogsMap" }, + "JobMetadata": { + "properties": { + "job_id": { + "type": "string", + "format": "uuid", + "title": "Job Id", + "description": "Parent Job" + }, + "metadata": { + "additionalProperties": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "integer" + }, + { + "type": "number" + }, + { + "type": "string" + } + ] + }, + "type": "object", + "title": "Metadata", + "description": "Custom key-value map" + }, + "url": { + "type": "string", + "maxLength": 2083, + "minLength": 1, + "format": "uri", + "title": "Url", + "description": "Link to get this resource (self)" + } + }, + "type": "object", + "required": [ + "job_id", + "metadata", + "url" + ], + "title": "JobMetadata" + }, + "JobMetadataUpdate": { + "properties": { + "metadata": { + "additionalProperties": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "integer" + }, + { + "type": "number" + }, + { + "type": "string" + } + ] + }, + "type": "object", + "title": "Metadata", + "description": "Custom key-value map" + } + }, + "type": "object", + "title": "JobMetadataUpdate" + }, "JobOutputs": { "properties": { "job_id": { @@ -4730,6 +5686,41 @@ ], "title": "Page[File]" }, + "Page_Job_": { + "properties": { + "items": { + "items": { + "$ref": "#/components/schemas/Job" + }, + "type": "array", + "title": "Items" + }, + "total": { + "type": "integer", + "minimum": 0, + "title": "Total" + }, + "limit": { + "type": "integer", + "minimum": 1, + "title": "Limit" + }, + "offset": { + "type": "integer", + "minimum": 0, + "title": "Offset" + }, + "links": { + "$ref": "#/components/schemas/Links" + } + }, + "type": "object", + "required": [ + "items", + "links" + ], + "title": "Page[Job]" + }, "Page_Study_": { "properties": { "items": { @@ -4765,6 +5756,49 @@ ], "title": "Page[Study]" }, + "PricingPlanClassification": { + "type": "string", + "enum": [ + "TIER" + ], + "title": "PricingPlanClassification", + "description": "An enumeration." + }, + "PricingUnitGet": { + "properties": { + "pricingUnitId": { + "type": "integer", + "exclusiveMinimum": true, + "title": "Pricingunitid", + "minimum": 0 + }, + "unitName": { + "type": "string", + "title": "Unitname" + }, + "unitExtraInfo": { + "type": "object", + "title": "Unitextrainfo" + }, + "currentCostPerUnit": { + "type": "number", + "title": "Currentcostperunit" + }, + "default": { + "type": "boolean", + "title": "Default" + } + }, + "type": "object", + "required": [ + "pricingUnitId", + "unitName", + "unitExtraInfo", + "currentCostPerUnit", + "default" + ], + "title": "PricingUnitGet" + }, "Profile": { "properties": { "first_name": { @@ -4867,6 +5901,54 @@ "title": "RunningState", "description": "State of execution of a project's computational workflow\n\nSEE StateType for task state" }, + "ServicePricingPlanGet": { + "properties": { + "pricingPlanId": { + "type": "integer", + "exclusiveMinimum": true, + "title": "Pricingplanid", + "minimum": 0 + }, + "displayName": { + "type": "string", + "title": "Displayname" + }, + "description": { + "type": "string", + "title": "Description" + }, + "classification": { + "$ref": "#/components/schemas/PricingPlanClassification" + }, + "createdAt": { + "type": "string", + "format": "date-time", + "title": "Createdat" + }, + "pricingPlanKey": { + "type": "string", + "title": "Pricingplankey" + }, + "pricingUnits": { + "items": { + "$ref": "#/components/schemas/PricingUnitGet" + }, + "type": "array", + "title": "Pricingunits" + } + }, + "type": "object", + "required": [ + "pricingPlanId", + "displayName", + "description", + "classification", + "createdAt", + "pricingPlanKey", + "pricingUnits" + ], + "title": "ServicePricingPlanGet" + }, "Solver": { "properties": { "id": { @@ -5129,6 +6211,73 @@ "type" ], "title": "ValidationError" + }, + "WalletGetWithAvailableCredits": { + "properties": { + "walletId": { + "type": "integer", + "exclusiveMinimum": true, + "title": "Walletid", + "minimum": 0 + }, + "name": { + "type": "string", + "maxLength": 100, + "minLength": 1, + "title": "Name" + }, + "description": { + "type": "string", + "title": "Description" + }, + "owner": { + "type": "integer", + "exclusiveMinimum": true, + "title": "Owner", + "minimum": 0 + }, + "thumbnail": { + "type": "string", + "title": "Thumbnail" + }, + "status": { + "$ref": "#/components/schemas/WalletStatus" + }, + "created": { + "type": "string", + "format": "date-time", + "title": "Created" + }, + "modified": { + "type": "string", + "format": "date-time", + "title": "Modified" + }, + "availableCredits": { + "type": "number", + "title": "Availablecredits" + } + }, + "type": "object", + "required": [ + "walletId", + "name", + "owner", + "status", + "created", + "modified", + "availableCredits" + ], + "title": "WalletGetWithAvailableCredits" + }, + "WalletStatus": { + "type": "string", + "enum": [ + "ACTIVE", + "INACTIVE" + ], + "title": "WalletStatus", + "description": "An enumeration." } }, "securitySchemes": { From a5c2c5bf59ef59648ec1fb4c092024f0a338f8df Mon Sep 17 00:00:00 2001 From: Pedro Crespo-Valero <32402063+pcrespov@users.noreply.github.com> Date: Thu, 3 Oct 2024 18:42:31 +0200 Subject: [PATCH 3/7] =?UTF-8?q?services/api-server=20version:=200.6.0=20?= =?UTF-8?q?=E2=86=92=200.7.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- services/api-server/VERSION | 2 +- services/api-server/setup.cfg | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/services/api-server/VERSION b/services/api-server/VERSION index a918a2aa18d..faef31a4357 100644 --- a/services/api-server/VERSION +++ b/services/api-server/VERSION @@ -1 +1 @@ -0.6.0 +0.7.0 diff --git a/services/api-server/setup.cfg b/services/api-server/setup.cfg index 5cef2727de7..da01c1bbd3e 100644 --- a/services/api-server/setup.cfg +++ b/services/api-server/setup.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 0.6.0 +current_version = 0.7.0 commit = True message = services/api-server version: {current_version} → {new_version} tag = False @@ -10,12 +10,12 @@ commit_args = --no-verify [tool:pytest] asyncio_mode = auto addopts = --strict-markers -markers = +markers = slow: marks tests as slow (deselect with '-m "not slow"') acceptance_test: "marks tests as 'acceptance tests' i.e. does the system do what the user expects? Typically those are workflows." testit: "marks test to run during development" [mypy] -plugins = +plugins = pydantic.mypy sqlalchemy.ext.mypy.plugin From dea1cd819d06aefbd613b1f1ace830a045dd82cf Mon Sep 17 00:00:00 2001 From: Pedro Crespo-Valero <32402063+pcrespov@users.noreply.github.com> Date: Thu, 3 Oct 2024 18:46:33 +0200 Subject: [PATCH 4/7] rm deprecation --- services/api-server/openapi.json | 3 +-- .../api/routes/solvers_jobs_getters.py | 6 ++---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/services/api-server/openapi.json b/services/api-server/openapi.json index 92261f29f62..bc7f58a04a1 100644 --- a/services/api-server/openapi.json +++ b/services/api-server/openapi.json @@ -1994,7 +1994,7 @@ "solvers" ], "summary": "List Jobs", - "description": "List of jobs in a specific released solver (limited to 20 jobs)\n\nSEE `get_jobs_page` for paginated version of this function\nNOTE: This implementation and returned values are deprecated and the\n will be replaced by that of get_jobs_page", + "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", "parameters": [ { @@ -2114,7 +2114,6 @@ } } }, - "deprecated": true, "security": [ { "HTTPBasic": [] 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 857e67d0116..62477a1c596 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 @@ -116,7 +116,6 @@ "/{solver_key:path}/releases/{version}/jobs", response_model=list[Job], responses=JOBS_STATUS_CODES, - deprecated=True, ) async def list_jobs( solver_key: SolverKeyId, @@ -129,9 +128,8 @@ async def list_jobs( ): """List of jobs in a specific released solver (limited to 20 jobs) - SEE `get_jobs_page` for paginated version of this function - NOTE: This implementation and returned values are deprecated and the - will be replaced by that of get_jobs_page + - DEPRECATION: This implementation and returned values are deprecated and the will be replaced by that of get_jobs_page + - SEE `get_jobs_page` for paginated version of this function """ solver = await catalog_client.get_service( From 7b3983cb42a1e294b673d39991e06834f2666c77 Mon Sep 17 00:00:00 2001 From: Pedro Crespo-Valero <32402063+pcrespov@users.noreply.github.com> Date: Thu, 3 Oct 2024 18:52:01 +0200 Subject: [PATCH 5/7] updates OAS --- services/api-server/openapi.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/api-server/openapi.json b/services/api-server/openapi.json index bc7f58a04a1..59aa2d91b11 100644 --- a/services/api-server/openapi.json +++ b/services/api-server/openapi.json @@ -3,7 +3,7 @@ "info": { "title": "osparc.io public API", "description": "osparc-simcore public API specifications", - "version": "0.6.0" + "version": "0.7.0" }, "paths": { "/v0/meta": { From b04882fa6a1a96d38b7dbc358fa4ae7cb409978d Mon Sep 17 00:00:00 2001 From: Pedro Crespo-Valero <32402063+pcrespov@users.noreply.github.com> Date: Thu, 3 Oct 2024 19:25:17 +0200 Subject: [PATCH 6/7] exposes all that is implemented --- .../api/routes/solvers_jobs_getters.py | 7 ++++--- .../api/routes/studies_jobs.py | 14 +++++++++----- 2 files changed, 13 insertions(+), 8 deletions(-) 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 62477a1c596..fb98a858e47 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 @@ -52,7 +52,6 @@ from ..dependencies.rabbitmq import get_log_check_timeout, get_log_distributor from ..dependencies.services import get_api_client from ..dependencies.webserver import AuthSession, get_webserver_session -from ._common import API_SERVER_DEV_FEATURES_ENABLED from ._constants import FMSG_CHANGELOG_NEW_IN_VERSION from .solvers_jobs import ( JOBS_STATUS_CODES, @@ -379,7 +378,7 @@ async def get_job_custom_metadata( "/{solver_key:path}/releases/{version}/jobs/{job_id:uuid}/wallet", response_model=WalletGetWithAvailableCredits | None, responses=WALLET_STATUS_CODES, - include_in_schema=API_SERVER_DEV_FEATURES_ENABLED, + description=("Get job wallet\n\n" + FMSG_CHANGELOG_NEW_IN_VERSION.format("0.7")), ) async def get_job_wallet( solver_key: SolverKeyId, @@ -399,7 +398,9 @@ async def get_job_wallet( "/{solver_key:path}/releases/{version}/jobs/{job_id:uuid}/pricing_unit", response_model=PricingUnitGet | None, responses=_PRICING_UNITS_STATUS_CODES, - include_in_schema=API_SERVER_DEV_FEATURES_ENABLED, + description=( + "Get job pricing unit\n\n" + FMSG_CHANGELOG_NEW_IN_VERSION.format("0.7") + ), ) async def get_job_pricing_unit( solver_key: SolverKeyId, diff --git a/services/api-server/src/simcore_service_api_server/api/routes/studies_jobs.py b/services/api-server/src/simcore_service_api_server/api/routes/studies_jobs.py index 60916446809..177b50d1e6c 100644 --- a/services/api-server/src/simcore_service_api_server/api/routes/studies_jobs.py +++ b/services/api-server/src/simcore_service_api_server/api/routes/studies_jobs.py @@ -52,7 +52,7 @@ from ...services.webserver import AuthSession from ..dependencies.application import get_reverse_url_mapper from ._common import API_SERVER_DEV_FEATURES_ENABLED -from ._constants import FMSG_CHANGELOG_CHANGED_IN_VERSION +from ._constants import FMSG_CHANGELOG_CHANGED_IN_VERSION, FMSG_CHANGELOG_NEW_IN_VERSION _logger = logging.getLogger(__name__) router = APIRouter() @@ -333,7 +333,10 @@ async def get_study_job_output_logfile( @router.get( "/{study_id}/jobs/{job_id}/metadata", response_model=JobMetadata, - include_in_schema=API_SERVER_DEV_FEATURES_ENABLED, + description=( + "Get custom metadata from a study's job\n\n" + + FMSG_CHANGELOG_NEW_IN_VERSION.format("0.7") + ), ) async def get_study_job_custom_metadata( study_id: StudyID, @@ -341,7 +344,6 @@ async def get_study_job_custom_metadata( webserver_api: Annotated[AuthSession, Depends(get_webserver_session)], url_for: Annotated[Callable, Depends(get_reverse_url_mapper)], ): - """Gets custom metadata from a job""" job_name = _compose_job_resource_name(study_id, job_id) msg = f"Gets metadata attached to study_id={study_id!r} job_id={job_id!r}.\njob_name={job_name!r}.\nSEE https://github.com/ITISFoundation/osparc-simcore/issues/4313" _logger.debug(msg) @@ -361,7 +363,10 @@ async def get_study_job_custom_metadata( @router.put( "/{study_id}/jobs/{job_id}/metadata", response_model=JobMetadata, - include_in_schema=API_SERVER_DEV_FEATURES_ENABLED, + description=( + "Changes custom metadata of a study's job\n\n" + + FMSG_CHANGELOG_NEW_IN_VERSION.format("0.7") + ), ) async def replace_study_job_custom_metadata( study_id: StudyID, @@ -370,7 +375,6 @@ async def replace_study_job_custom_metadata( webserver_api: Annotated[AuthSession, Depends(get_webserver_session)], url_for: Annotated[Callable, Depends(get_reverse_url_mapper)], ): - """Changes job's custom metadata""" job_name = _compose_job_resource_name(study_id, job_id) msg = f"Attaches metadata={replace.metadata!r} to study_id={study_id!r} job_id={job_id!r}.\njob_name={job_name!r}.\nSEE https://github.com/ITISFoundation/osparc-simcore/issues/4313" From c51c3aa470bc4c69d3d5389accc89c629309f42f Mon Sep 17 00:00:00 2001 From: Pedro Crespo-Valero <32402063+pcrespov@users.noreply.github.com> Date: Thu, 3 Oct 2024 19:25:40 +0200 Subject: [PATCH 7/7] updates opeanpi --- services/api-server/openapi.json | 394 +++++++++++++++++++++++++++++++ 1 file changed, 394 insertions(+) diff --git a/services/api-server/openapi.json b/services/api-server/openapi.json index 59aa2d91b11..7965ae507f2 100644 --- a/services/api-server/openapi.json +++ b/services/api-server/openapi.json @@ -3695,6 +3695,274 @@ ] } }, + "/v0/solvers/{solver_key}/releases/{version}/jobs/{job_id}/wallet": { + "get": { + "tags": [ + "solvers" + ], + "summary": "Get Job Wallet", + "description": "Get job wallet\n\nNew in *version 0.7*", + "operationId": "get_job_wallet", + "parameters": [ + { + "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" + }, + { + "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": 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/WalletGetWithAvailableCredits" + } + } + } + }, + "404": { + "description": "Wallet not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorGet" + } + } + } + }, + "403": { + "description": "Access to wallet is not allowed", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorGet" + } + } + } + }, + "429": { + "description": "Too many requests", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorGet" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorGet" + } + } + } + }, + "502": { + "description": "Unexpected error when communicating with backend service", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorGet" + } + } + } + }, + "503": { + "description": "Service unavailable", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorGet" + } + } + } + }, + "504": { + "description": "Request to a backend service timed out.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorGet" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + }, + "security": [ + { + "HTTPBasic": [] + } + ] + } + }, + "/v0/solvers/{solver_key}/releases/{version}/jobs/{job_id}/pricing_unit": { + "get": { + "tags": [ + "solvers" + ], + "summary": "Get Job Pricing Unit", + "description": "Get job pricing unit\n\nNew in *version 0.7*", + "operationId": "get_job_pricing_unit", + "parameters": [ + { + "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" + }, + { + "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": 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/PricingUnitGet" + } + } + } + }, + "404": { + "description": "Pricing unit not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorGet" + } + } + } + }, + "429": { + "description": "Too many requests", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorGet" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorGet" + } + } + } + }, + "502": { + "description": "Unexpected error when communicating with backend service", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorGet" + } + } + } + }, + "503": { + "description": "Service unavailable", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorGet" + } + } + } + }, + "504": { + "description": "Request to a backend service timed out.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorGet" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + }, + "security": [ + { + "HTTPBasic": [] + } + ] + } + }, "/v0/solvers/{solver_key}/releases/{version}/jobs/{job_id}/logstream": { "get": { "tags": [ @@ -4632,6 +4900,132 @@ ] } }, + "/v0/studies/{study_id}/jobs/{job_id}/metadata": { + "get": { + "tags": [ + "studies" + ], + "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", + "parameters": [ + { + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Study Id" + }, + "name": "study_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/JobMetadata" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + }, + "security": [ + { + "HTTPBasic": [] + } + ] + }, + "put": { + "tags": [ + "studies" + ], + "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", + "parameters": [ + { + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Study Id" + }, + "name": "study_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", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/JobMetadata" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + }, + "security": [ + { + "HTTPBasic": [] + } + ] + } + }, "/v0/wallets/default": { "get": { "tags": [