From 7079546a2734f94ac6cd54d827f6bc485255b544 Mon Sep 17 00:00:00 2001 From: Pedro Crespo-Valero <32402063+pcrespov@users.noreply.github.com> Date: Wed, 14 Aug 2024 20:07:09 +0200 Subject: [PATCH 01/18] drops dev api in web-api --- api/specs/web-server/_catalog.py | 36 +- .../api/v0/openapi.yaml | 401 +++--------------- .../catalog/_handlers.py | 90 +--- 3 files changed, 71 insertions(+), 456 deletions(-) diff --git a/api/specs/web-server/_catalog.py b/api/specs/web-server/_catalog.py index bdd1f7f61f9..ffaa9ed916b 100644 --- a/api/specs/web-server/_catalog.py +++ b/api/specs/web-server/_catalog.py @@ -5,7 +5,6 @@ from models_library.api_schemas_webserver.catalog import ( CatalogServiceGet, CatalogServiceUpdate, - ServiceGet, ServiceInputGet, ServiceInputKey, ServiceOutputGet, @@ -38,43 +37,16 @@ @router.get( - "/dev/catalog/services/-/latest", + "/catalog/services/-/latest", response_model=Page[CatalogServiceGet], ) -def dev_list_services_latest(_query_params: Annotated[ListServiceParams, Depends()]): - pass - - -@router.get( - "/dev/catalog/services/{service_key}/{service_version}", - response_model=Envelope[CatalogServiceGet], -) -def dev_get_service(_path_params: Annotated[ServicePathParams, Depends()]): - ... - - -@router.patch( - "/dev/catalog/services/{service_key}/{service_version}", - response_model=Envelope[CatalogServiceGet], -) -def dev_update_service( - _path_params: Annotated[ServicePathParams, Depends()], - _update: CatalogServiceUpdate, -): - ... - - -@router.get( - "/catalog/services", - response_model=Envelope[list[ServiceGet]], -) -def list_services(): +def list_services_latest(_query_params: Annotated[ListServiceParams, Depends()]): pass @router.get( "/catalog/services/{service_key}/{service_version}", - response_model=Envelope[ServiceGet], + response_model=Envelope[CatalogServiceGet], ) def get_service(_path_params: Annotated[ServicePathParams, Depends()]): ... @@ -82,7 +54,7 @@ def get_service(_path_params: Annotated[ServicePathParams, Depends()]): @router.patch( "/catalog/services/{service_key}/{service_version}", - response_model=Envelope[ServiceGet], + response_model=Envelope[CatalogServiceGet], ) def update_service( _path_params: Annotated[ServicePathParams, Depends()], diff --git a/services/web/server/src/simcore_service_webserver/api/v0/openapi.yaml b/services/web/server/src/simcore_service_webserver/api/v0/openapi.yaml index 65586d41d10..c262b2889d7 100644 --- a/services/web/server/src/simcore_service_webserver/api/v0/openapi.yaml +++ b/services/web/server/src/simcore_service_webserver/api/v0/openapi.yaml @@ -485,12 +485,12 @@ paths: application/json: schema: {} image/png: {} - /v0/dev/catalog/services/-/latest: + /v0/catalog/services/-/latest: get: tags: - catalog - summary: Dev List Services Latest - operationId: dev_list_services_latest + summary: List Services Latest + operationId: list_services_latest parameters: - required: false schema: @@ -517,80 +517,6 @@ paths: application/json: schema: $ref: '#/components/schemas/Page_CatalogServiceGet_' - /v0/dev/catalog/services/{service_key}/{service_version}: - get: - tags: - - catalog - summary: Dev Get Service - operationId: dev_get_service - parameters: - - required: true - schema: - title: Service Key - pattern: ^simcore/services/((comp|dynamic|frontend))/([a-z0-9][a-z0-9_.-]*/)*([a-z0-9-_]+[a-z0-9])$ - type: string - name: service_key - in: path - - required: true - schema: - title: Service Version - 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: string - name: service_version - in: path - responses: - '200': - description: Successful Response - content: - application/json: - schema: - $ref: '#/components/schemas/Envelope_CatalogServiceGet_' - patch: - tags: - - catalog - summary: Dev Update Service - operationId: dev_update_service - parameters: - - required: true - schema: - title: Service Key - pattern: ^simcore/services/((comp|dynamic|frontend))/([a-z0-9][a-z0-9_.-]*/)*([a-z0-9-_]+[a-z0-9])$ - type: string - name: service_key - in: path - - required: true - schema: - title: Service Version - 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: string - name: service_version - in: path - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/CatalogServiceUpdate' - required: true - responses: - '200': - description: Successful Response - content: - application/json: - schema: - $ref: '#/components/schemas/Envelope_CatalogServiceGet_' - /v0/catalog/services: - get: - tags: - - catalog - summary: List Services - operationId: list_services - responses: - '200': - description: Successful Response - content: - application/json: - schema: - $ref: '#/components/schemas/Envelope_list_models_library.api_schemas_webserver.catalog.ServiceGet__' /v0/catalog/services/{service_key}/{service_version}: get: tags: @@ -618,7 +544,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/Envelope_ServiceGet_' + $ref: '#/components/schemas/Envelope_CatalogServiceGet_' patch: tags: - catalog @@ -651,7 +577,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/Envelope_ServiceGet_' + $ref: '#/components/schemas/Envelope_CatalogServiceGet_' /v0/catalog/services/{service_key}/{service_version}/inputs: get: tags: @@ -3489,7 +3415,7 @@ paths: '403': description: ProjectInvalidRightsError '404': - description: UserDefaultWalletNotFoundError, ProjectNotFoundError + description: ProjectNotFoundError, UserDefaultWalletNotFoundError '409': description: ProjectTooManyProjectOpenedError '422': @@ -5822,36 +5748,6 @@ components: affiliation: title: Affiliation type: string - Badge: - title: Badge - required: - - name - - image - - url - type: object - properties: - name: - title: Name - type: string - description: Name of the subject - image: - title: Image - maxLength: 2083 - minLength: 1 - type: string - description: Url to the badge - format: uri - url: - title: Url - maxLength: 2083 - minLength: 1 - type: string - description: Link to the status - format: uri - example: - name: osparc.io - image: https://img.shields.io/website-up-down-green-red/https/itisfoundation.github.io.svg?label=documentation - url: https://itisfoundation.github.io/ Body_service_submission: title: Body_service_submission required: @@ -7067,14 +6963,6 @@ components: $ref: '#/components/schemas/ResearchResource' error: title: Error - Envelope_ServiceGet_: - title: Envelope[ServiceGet] - type: object - properties: - data: - $ref: '#/components/schemas/models_library__api_schemas_webserver__catalog__ServiceGet' - error: - title: Error Envelope_ServiceInputGet_: title: Envelope[ServiceInputGet] type: object @@ -7346,17 +7234,6 @@ components: $ref: '#/components/schemas/FileMetaDataGet' error: title: Error - Envelope_list_models_library.api_schemas_webserver.catalog.ServiceGet__: - title: Envelope[list[models_library.api_schemas_webserver.catalog.ServiceGet]] - type: object - properties: - data: - title: Data - type: array - items: - $ref: '#/components/schemas/models_library__api_schemas_webserver__catalog__ServiceGet' - error: - title: Error Envelope_list_models_library.api_schemas_webserver.catalog.ServiceInputGet__: title: Envelope[list[models_library.api_schemas_webserver.catalog.ServiceInputGet]] type: object @@ -7575,7 +7452,7 @@ components: title: Data type: array items: - $ref: '#/components/schemas/simcore_service_webserver__studies_dispatcher___rest_handlers__ServiceGet' + $ref: '#/components/schemas/ServiceGet' error: title: Error Envelope_list_simcore_service_webserver.studies_dispatcher._rest_handlers.Viewer__: @@ -10758,20 +10635,58 @@ components: - V2 type: string description: An enumeration. - ServiceGroupAccessRights: - title: ServiceGroupAccessRights + ServiceGet: + title: ServiceGet + required: + - key + - title + - description + - thumbnail + - view_url type: object properties: - execute_access: - title: Execute Access - type: boolean - description: defines whether the group can execute the service - default: false - write_access: - title: Write Access - type: boolean - description: defines whether the group can modify the service - default: false + key: + title: Key + pattern: ^simcore/services/((comp|dynamic|frontend))/([a-z0-9][a-z0-9_.-]*/)*([a-z0-9-_]+[a-z0-9])$ + type: string + description: Service key ID + title: + title: Title + type: string + description: Service name for display + description: + title: Description + type: string + description: Long description of the service + thumbnail: + title: Thumbnail + maxLength: 2083 + minLength: 1 + type: string + description: Url to service thumbnail + format: uri + file_extensions: + title: File Extensions + type: array + items: + type: string + description: File extensions that this service can process + view_url: + title: View Url + maxLength: 2083 + minLength: 1 + type: string + description: Redirection to open a service in osparc (see /view) + format: uri + example: + key: simcore/services/dynamic/sim4life + title: Sim4Life Mattermost + description: It is also sim4life for the web + thumbnail: https://via.placeholder.com/170x120.png + file_extensions: + - smash + - h5 + view_url: https://host.com/view?viewer_key=simcore/services/dynamic/raw-graphs&viewer_version=1.2.3 ServiceGroupAccessRightsV2: title: ServiceGroupAccessRightsV2 type: object @@ -12410,205 +12325,3 @@ components: title: Delete type: boolean additionalProperties: false - models_library__api_schemas_webserver__catalog__ServiceGet: - title: ServiceGet - required: - - name - - description - - key - - version - - type - - authors - - contact - - inputs - - outputs - type: object - properties: - name: - title: Name - type: string - description: 'Display name: short, human readable name for the node' - example: Fast Counter - thumbnail: - title: Thumbnail - maxLength: 2083 - minLength: 1 - type: string - description: url to the thumbnail - format: uri - description: - title: Description - type: string - description: human readable description of the purpose of the node - versionDisplay: - title: Versiondisplay - type: string - description: A user-friendly or marketing name for the release. This can - be used to reference the release in a more readable and recognizable format, - such as 'Matterhorn Release,' 'Spring Update,' or 'Holiday Edition.' This - name is not used for version comparison but is useful for communication - and documentation purposes. - deprecated: - title: Deprecated - type: string - description: Owner can set the date to retire the service. Three possibilities:If - None, the service is marked as `published`;If now=deprecated, the service is retired - format: date-time - classifiers: - title: Classifiers - type: array - items: - type: string - quality: - title: Quality - type: object - default: {} - accessRights: - title: Accessrights - type: object - additionalProperties: - $ref: '#/components/schemas/ServiceGroupAccessRights' - description: service access rights per group id - key: - title: Key - pattern: ^simcore/services/((comp|dynamic|frontend))/([a-z0-9][a-z0-9_.-]*/)*([a-z0-9-_]+[a-z0-9])$ - type: string - description: distinctive name for the node based on the docker registry - path - version: - title: Version - 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: string - description: service version number - releaseDate: - title: Releasedate - type: string - description: "A timestamp when the specific version of the service was released.\ - \ This field helps in tracking the timeline of releases and understanding\ - \ the sequence of updates. A timestamp string should be formatted as YYYY-MM-DD[T]HH:MM[:SS[.ffffff]][Z\ - \ or [\xB1]HH[:]MM]" - format: date-time - integration-version: - title: Integration-Version - pattern: ^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$ - type: string - description: This version is used to maintain backward compatibility when - there are changes in the way a service is integrated into the framework - type: - allOf: - - $ref: '#/components/schemas/ServiceType' - description: service type - badges: - title: Badges - type: array - items: - $ref: '#/components/schemas/Badge' - deprecated: true - authors: - title: Authors - minItems: 1 - type: array - items: - $ref: '#/components/schemas/Author' - contact: - title: Contact - type: string - description: email to correspond to the authors about the node - format: email - inputs: - title: Inputs - type: object - description: inputs with extended information - outputs: - title: Outputs - type: object - description: outputs with extended information - boot-options: - title: Boot-Options - type: object - description: Service defined boot options. These get injected in the service - as env variables. - min-visible-inputs: - title: Min-Visible-Inputs - minimum: 0 - type: integer - description: The number of 'data type inputs' displayed by default in the - UI. When None all 'data type inputs' are displayed. - progress_regexp: - title: Progress Regexp - type: string - description: regexp pattern for detecting computational service's progress - imageDigest: - title: Imagedigest - type: string - description: Image manifest digest. Note that this is NOT injected as an - image label - owner: - title: Owner - type: string - format: email - description: 'Service metadata at publication time - - - - read-only (can only be changed overwriting the image labels in the registry) - - - base metaddata - - - injected in the image labels - - - NOTE: This model is serialized in .osparc/metadata.yml and in the labels of - the docker image' - simcore_service_webserver__studies_dispatcher___rest_handlers__ServiceGet: - title: ServiceGet - required: - - key - - title - - description - - thumbnail - - view_url - type: object - properties: - key: - title: Key - pattern: ^simcore/services/((comp|dynamic|frontend))/([a-z0-9][a-z0-9_.-]*/)*([a-z0-9-_]+[a-z0-9])$ - type: string - description: Service key ID - title: - title: Title - type: string - description: Service name for display - description: - title: Description - type: string - description: Long description of the service - thumbnail: - title: Thumbnail - maxLength: 2083 - minLength: 1 - type: string - description: Url to service thumbnail - format: uri - file_extensions: - title: File Extensions - type: array - items: - type: string - description: File extensions that this service can process - view_url: - title: View Url - maxLength: 2083 - minLength: 1 - type: string - description: Redirection to open a service in osparc (see /view) - format: uri - example: - key: simcore/services/dynamic/sim4life - title: Sim4Life Mattermost - description: It is also sim4life for the web - thumbnail: https://via.placeholder.com/170x120.png - file_extensions: - - smash - - h5 - view_url: https://host.com/view?viewer_key=simcore/services/dynamic/raw-graphs&viewer_version=1.2.3 diff --git a/services/web/server/src/simcore_service_webserver/catalog/_handlers.py b/services/web/server/src/simcore_service_webserver/catalog/_handlers.py index 639e2501228..ee5dc05106c 100644 --- a/services/web/server/src/simcore_service_webserver/catalog/_handlers.py +++ b/services/web/server/src/simcore_service_webserver/catalog/_handlers.py @@ -8,14 +8,13 @@ import asyncio import logging import urllib.parse -from typing import Any, Final +from typing import Final from aiohttp import web from aiohttp.web import Request, RouteTableDef from models_library.api_schemas_webserver.catalog import ( CatalogServiceGet, CatalogServiceUpdate, - ServiceGet, ServiceInputKey, ServiceOutputKey, ) @@ -27,7 +26,6 @@ ServiceResourcesDict, ServiceResourcesDictHelpers, ) -from models_library.utils.json_serialization import json_loads from pydantic import BaseModel, Extra, Field, parse_obj_as, validator from servicelib.aiohttp.requests_validation import ( parse_request_body_as, @@ -75,13 +73,13 @@ class ListServiceParams(PageQueryParameters): @routes.get( - f"{VTAG_DEV}/catalog/services/-/latest", - name="dev_list_services_latest", + f"{VTAG}/catalog/services/-/latest", + name="list_services_latest", ) @login_required @permission_required("services.catalog.*") @_handlers_errors.reraise_catalog_exceptions_as_http_errors -async def dev_list_services_latest(request: Request): +async def list_services_latest(request: Request): request_ctx = CatalogRequestContext.create(request) query_params: ListServiceParams = parse_request_query_parameters_as( ListServiceParams, request @@ -113,13 +111,13 @@ async def dev_list_services_latest(request: Request): @routes.get( - f"{VTAG_DEV}/catalog/services/{{service_key}}/{{service_version}}", - name="dev_get_service", + f"{VTAG}/catalog/services/{{service_key}}/{{service_version}}", + name="get_service", ) @login_required @permission_required("services.catalog.*") @_handlers_errors.reraise_catalog_exceptions_as_http_errors -async def dev_get_service(request: Request): +async def get_service(request: Request): request_ctx = CatalogRequestContext.create(request) path_params = parse_request_path_parameters_as(ServicePathParams, request) @@ -139,13 +137,13 @@ async def dev_get_service(request: Request): @routes.patch( - f"{VTAG_DEV}/catalog/services/{{service_key}}/{{service_version}}", - name="dev_update_service", + f"{VTAG}/catalog/services/{{service_key}}/{{service_version}}", + name="update_service", ) @login_required @permission_required("services.catalog.*") @_handlers_errors.reraise_catalog_exceptions_as_http_errors -async def dev_update_service(request: Request): +async def update_service(request: Request): request_ctx = CatalogRequestContext.create(request) path_params = parse_request_path_parameters_as(ServicePathParams, request) update: CatalogServiceUpdate = await parse_request_body_as( @@ -169,74 +167,6 @@ async def dev_update_service(request: Request): return envelope_json_response(CatalogServiceGet.parse_obj(updated)) -@routes.get(f"{VTAG}/catalog/services", name="list_services") -@login_required -@permission_required("services.catalog.*") -async def list_services(request: Request): - req_ctx = CatalogRequestContext.create(request) - - data_array = await _api.list_services( - request.app, - user_id=req_ctx.user_id, - product_name=req_ctx.product_name, - unit_registry=req_ctx.unit_registry, - ) - - # NOTE: this is too heave in devel-mode. Temporary removed - # assert parse_obj_as(list[ServiceGet], data_array) is not None # nosec - # - - return await asyncio.get_event_loop().run_in_executor( - None, envelope_json_response, data_array - ) - - -@routes.get( - f"{VTAG}/catalog/services/{{service_key}}/{{service_version}}", - name="get_service", -) -@login_required -@permission_required("services.catalog.*") -async def get_service(request: Request): - ctx = CatalogRequestContext.create(request) - path_params = parse_request_path_parameters_as(ServicePathParams, request) - - data = await _api.get_service( - path_params.service_key, path_params.service_version, ctx - ) - assert parse_obj_as(ServiceGet, data) is not None # nosec - return await asyncio.get_event_loop().run_in_executor( - None, envelope_json_response, data - ) - - -@routes.patch( - f"{VTAG}/catalog/services/{{service_key}}/{{service_version}}", - name="update_service", -) -@login_required -@permission_required("services.catalog.*") -async def update_service(request: Request): - ctx = CatalogRequestContext.create(request) - path_params = parse_request_path_parameters_as(ServicePathParams, request) - update_data: dict[str, Any] = await request.json(loads=json_loads) - - assert parse_obj_as(CatalogServiceUpdate, update_data) is not None # nosec - - # Evaluate and return validated model - data = await _api.update_service( - path_params.service_key, - path_params.service_version, - update_data, - ctx, - ) - - assert parse_obj_as(ServiceGet, data) is not None # nosec - return await asyncio.get_event_loop().run_in_executor( - None, envelope_json_response, data - ) - - @routes.get( f"{VTAG}/catalog/services/{{service_key}}/{{service_version}}/inputs", name="list_service_inputs", From b087041f9e698c2464f2e1fe019741dd2ff7f39b Mon Sep 17 00:00:00 2001 From: Pedro Crespo-Valero <32402063+pcrespov@users.noreply.github.com> Date: Wed, 14 Aug 2024 20:08:43 +0200 Subject: [PATCH 02/18] renames pluginapi --- .../server/src/simcore_service_webserver/catalog/_api.py | 6 +++--- .../src/simcore_service_webserver/catalog/_handlers.py | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/services/web/server/src/simcore_service_webserver/catalog/_api.py b/services/web/server/src/simcore_service_webserver/catalog/_api.py index 02dc0b8c151..44b8bb087f0 100644 --- a/services/web/server/src/simcore_service_webserver/catalog/_api.py +++ b/services/web/server/src/simcore_service_webserver/catalog/_api.py @@ -87,7 +87,7 @@ async def _safe_replace_service_input_outputs( # IMPLEMENTATION -------------------------------------------------------------------------------- -async def dev_list_latest_services( +async def list_latest_services( app: web.Application, *, user_id: UserID, @@ -112,7 +112,7 @@ async def dev_list_latest_services( return page_data, page.meta -async def dev_get_service( +async def get_service_v2( app: web.Application, *, product_name: ProductName, @@ -139,7 +139,7 @@ async def dev_get_service( return data -async def dev_update_service( +async def update_service_v2( app: web.Application, *, product_name: ProductName, diff --git a/services/web/server/src/simcore_service_webserver/catalog/_handlers.py b/services/web/server/src/simcore_service_webserver/catalog/_handlers.py index ee5dc05106c..cfaafe30ab6 100644 --- a/services/web/server/src/simcore_service_webserver/catalog/_handlers.py +++ b/services/web/server/src/simcore_service_webserver/catalog/_handlers.py @@ -85,7 +85,7 @@ async def list_services_latest(request: Request): ListServiceParams, request ) - page_items, page_meta = await _api.dev_list_latest_services( + page_items, page_meta = await _api.list_latest_services( request.app, user_id=request_ctx.user_id, product_name=request_ctx.product_name, @@ -124,7 +124,7 @@ async def get_service(request: Request): assert request_ctx # nosec assert path_params # nosec - service = await _api.dev_get_service( + service = await _api.get_service_v2( request.app, user_id=request_ctx.user_id, product_name=request_ctx.product_name, @@ -154,7 +154,7 @@ async def update_service(request: Request): assert path_params # nosec assert update # nosec - updated = await _api.dev_update_service( + updated = await _api.update_service_v2( request.app, user_id=request_ctx.user_id, product_name=request_ctx.product_name, From 8f2c16892ac400aafad43f3faf73c6ca1073fa5f Mon Sep 17 00:00:00 2001 From: Pedro Crespo-Valero <32402063+pcrespov@users.noreply.github.com> Date: Wed, 14 Aug 2024 20:10:37 +0200 Subject: [PATCH 03/18] =?UTF-8?q?services/webserver=20api=20version:=200.4?= =?UTF-8?q?1.0=20=E2=86=92=200.42.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- services/web/server/VERSION | 2 +- services/web/server/setup.cfg | 2 +- .../server/src/simcore_service_webserver/api/v0/openapi.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/services/web/server/VERSION b/services/web/server/VERSION index 72a8a6313bb..787ffc30a81 100644 --- a/services/web/server/VERSION +++ b/services/web/server/VERSION @@ -1 +1 @@ -0.41.0 +0.42.0 diff --git a/services/web/server/setup.cfg b/services/web/server/setup.cfg index 802ba3451b1..e428608f1f2 100644 --- a/services/web/server/setup.cfg +++ b/services/web/server/setup.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 0.41.0 +current_version = 0.42.0 commit = True message = services/webserver api version: {current_version} → {new_version} tag = False diff --git a/services/web/server/src/simcore_service_webserver/api/v0/openapi.yaml b/services/web/server/src/simcore_service_webserver/api/v0/openapi.yaml index c262b2889d7..7779de1ccdc 100644 --- a/services/web/server/src/simcore_service_webserver/api/v0/openapi.yaml +++ b/services/web/server/src/simcore_service_webserver/api/v0/openapi.yaml @@ -2,7 +2,7 @@ openapi: 3.0.2 info: title: simcore-service-webserver description: Main service with an interface (http-API & websockets) to the web front-end - version: 0.41.0 + version: 0.42.0 servers: - url: '' description: webserver From 38b549d6c736b943bca16e438ce3e801311d8ff8 Mon Sep 17 00:00:00 2001 From: Pedro Crespo-Valero <32402063+pcrespov@users.noreply.github.com> Date: Wed, 14 Aug 2024 20:12:07 +0200 Subject: [PATCH 04/18] updates front-end --- .../client/source/class/osparc/data/Resources.js | 12 ++++++------ .../client/source/class/osparc/service/Store.js | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/services/static-webserver/client/source/class/osparc/data/Resources.js b/services/static-webserver/client/source/class/osparc/data/Resources.js index f2d68b21418..44ea7b20671 100644 --- a/services/static-webserver/client/source/class/osparc/data/Resources.js +++ b/services/static-webserver/client/source/class/osparc/data/Resources.js @@ -467,27 +467,27 @@ qx.Class.define("osparc.data.Resources", { }, /* - * SERVICES DEV + * SERVICES V2 (web-api >=0.42.0) */ - "servicesDev": { + "servicesV2": { useCache: false, // handled in osparc.service.Store idField: ["key", "version"], endpoints: { get: { method: "GET", - url: statics.API + "/dev/catalog/services/-/latest" + url: statics.API + "/catalog/services/-/latest" }, getPage: { method: "GET", - url: statics.API + "/dev/catalog/services/-/latest?offset={offset}&limit={limit}" + url: statics.API + "/catalog/services/-/latest?offset={offset}&limit={limit}" }, getOne: { method: "GET", - url: statics.API + "/dev/catalog/services/{key}/{version}" + url: statics.API + "/catalog/services/{key}/{version}" }, patch: { method: "PATCH", - url: statics.API + "/dev/catalog/services/{key}/{version}" + url: statics.API + "/catalog/services/{key}/{version}" } } }, diff --git a/services/static-webserver/client/source/class/osparc/service/Store.js b/services/static-webserver/client/source/class/osparc/service/Store.js index b7f1e96659a..9c72e9dd6be 100644 --- a/services/static-webserver/client/source/class/osparc/service/Store.js +++ b/services/static-webserver/client/source/class/osparc/service/Store.js @@ -30,7 +30,7 @@ qx.Class.define("osparc.service.Store", { return; } - osparc.data.Resources.getInstance().getAllPages("servicesDev") + osparc.data.Resources.getInstance().getAllPages("servicesV2") .then(servicesArray => { const servicesObj = osparc.service.Utils.convertArrayToObject(servicesArray); this.__addHits(servicesObj); @@ -58,7 +58,7 @@ qx.Class.define("osparc.service.Store", { const params = { url: osparc.data.Resources.getServiceUrl(key, version) }; - osparc.data.Resources.getOne("servicesDev", params) + osparc.data.Resources.getOne("servicesV2", params) .then(service => { this.__addHit(service); this.__addTSRInfo(service); @@ -106,7 +106,7 @@ qx.Class.define("osparc.service.Store", { url: osparc.data.Resources.getServiceUrl(key, version), data: patchData }; - return osparc.data.Resources.fetch("servicesDev", "patch", params) + return osparc.data.Resources.fetch("servicesV2", "patch", params) .then(() => { this.servicesCached[key][version][fieldKey] = value; serviceData[fieldKey] = value; From 9aab22a6d12862f5d4e6002feedc42be43924346 Mon Sep 17 00:00:00 2001 From: Pedro Crespo-Valero <32402063+pcrespov@users.noreply.github.com> Date: Wed, 14 Aug 2024 20:19:12 +0200 Subject: [PATCH 05/18] deprecation warnings --- .../src/simcore_service_webserver/catalog/_api.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/services/web/server/src/simcore_service_webserver/catalog/_api.py b/services/web/server/src/simcore_service_webserver/catalog/_api.py index 44b8bb087f0..9bbbae4e43c 100644 --- a/services/web/server/src/simcore_service_webserver/catalog/_api.py +++ b/services/web/server/src/simcore_service_webserver/catalog/_api.py @@ -1,4 +1,5 @@ import logging +import warnings from collections.abc import Iterator from typing import Any, cast @@ -187,6 +188,13 @@ async def list_services( async def get_service( service_key: ServiceKey, service_version: ServiceVersion, ctx: CatalogRequestContext ) -> dict[str, Any]: + + warnings.warn( + "`get_service` is deprecated, use `get_service_v2` instead", + DeprecationWarning, + stacklevel=1, + ) + service = await client.get_service( ctx.app, ctx.user_id, service_key, service_version, ctx.product_name ) @@ -204,6 +212,12 @@ async def update_service( update_data: dict[str, Any], ctx: CatalogRequestContext, ): + warnings.warn( + "`update_service_v2` is deprecated, use `update_service_v2` instead", + DeprecationWarning, + stacklevel=1, + ) + service = await client.update_service( ctx.app, ctx.user_id, From 70d8f83e1043b2892e39f4b0bed071ef86b8d089 Mon Sep 17 00:00:00 2001 From: Pedro Crespo-Valero <32402063+pcrespov@users.noreply.github.com> Date: Mon, 19 Aug 2024 11:33:54 +0200 Subject: [PATCH 06/18] updates tests --- .../with_dbs/01/test_catalog_handlers__services.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/services/web/server/tests/unit/with_dbs/01/test_catalog_handlers__services.py b/services/web/server/tests/unit/with_dbs/01/test_catalog_handlers__services.py index e6fee8b174e..4b97d4fc34b 100644 --- a/services/web/server/tests/unit/with_dbs/01/test_catalog_handlers__services.py +++ b/services/web/server/tests/unit/with_dbs/01/test_catalog_handlers__services.py @@ -130,7 +130,7 @@ async def _update( "user_role", [UserRole.USER], ) -async def test_dev_list_latest_services( +async def test_list_services_latest( client: TestClient, logged_user: UserInfoDict, mocked_rpc_catalog_service_api: dict[str, MagicMock], @@ -138,14 +138,14 @@ async def test_dev_list_latest_services( assert client.app assert client.app.router - # LIST latest - url = client.app.router["dev_list_services_latest"].url_for() + url = client.app.router["list_services_latest"].url_for() assert url.path.endswith("/catalog/services/-/latest") response = await client.get(f"{url}", params={"offset": "0", "limit": "1"}) data, error = await assert_status(response, status.HTTP_200_OK) assert data assert error is None + model = parse_obj_as(Page[CatalogServiceGet], data) assert model assert model.data @@ -158,7 +158,7 @@ async def test_dev_list_latest_services( "user_role", [UserRole.USER], ) -async def test_dev_get_and_patch_service( +async def test_get_and_patch_service( client: TestClient, logged_user: UserInfoDict, mocked_rpc_catalog_service_api: dict[str, MagicMock], @@ -169,7 +169,7 @@ async def test_dev_get_and_patch_service( service_key = "simcore/services/dynamic/someservice" service_version = "3.4.5" - url = client.app.router["dev_get_service"].url_for( + url = client.app.router["get_service"].url_for( service_key=urllib.parse.quote(service_key, safe=""), service_version=service_version, ) @@ -203,6 +203,7 @@ async def test_dev_get_and_patch_service( data, error = await assert_status(response, status.HTTP_200_OK) assert data assert error is None + model = parse_obj_as(CatalogServiceGet, data) assert model.key == service_key assert model.version == service_version From d23ba53fd1bec6adbc6248055a3e42b6a816038f Mon Sep 17 00:00:00 2001 From: Pedro Crespo-Valero <32402063+pcrespov@users.noreply.github.com> Date: Mon, 19 Aug 2024 11:41:55 +0200 Subject: [PATCH 07/18] minor --- .../locust_files/catalog_services2.py | 57 +++++++++++++++++++ tests/performance/locust_settings.py | 22 ++++--- 2 files changed, 70 insertions(+), 9 deletions(-) create mode 100644 tests/performance/locust_files/catalog_services2.py diff --git a/tests/performance/locust_files/catalog_services2.py b/tests/performance/locust_files/catalog_services2.py new file mode 100644 index 00000000000..9b38588ecc7 --- /dev/null +++ b/tests/performance/locust_files/catalog_services2.py @@ -0,0 +1,57 @@ +# +# SEE https://docs.locust.io/en/stable/quickstart.html +# + +import logging +from time import time + +import faker +from locust import task +from locust.contrib.fasthttp import FastHttpUser + +logging.basicConfig(level=logging.INFO) + +fake = faker.Faker() + + +class WebApiUser(FastHttpUser): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + self.email = fake.email() + + @task() + def get_services_with_details(self): + start = time() + with self.client.get( + "/v0/services?user_id=1&details=true", + headers={ + "x-simcore-products-name": "osparc", + }, + catch_response=True, + ) as response: + response.raise_for_status() + num_services = len(response.json()) + print(f"got {num_services} WITH DETAILS in {time() - start}s") + response.success() + + @task() + def get_services_without_details(self): + start = time() + with self.client.get( + "/v0/services?user_id=1&details=false", + headers={ + "x-simcore-products-name": "osparc", + }, + catch_response=True, + ) as response: + response.raise_for_status() + num_services = len(response.json()) + print(f"got {num_services} in {time() - start}s") + response.success() + + def on_start(self): + print("Created User ", self.email) + + def on_stop(self): + print("Stopping", self.email) diff --git a/tests/performance/locust_settings.py b/tests/performance/locust_settings.py index 5190383526c..733c6a7304e 100644 --- a/tests/performance/locust_settings.py +++ b/tests/performance/locust_settings.py @@ -33,14 +33,15 @@ class LocustSettings(BaseSettings): LOCUST_CHECK_FAIL_RATIO: PositiveFloat = Field(default=0.01, ge=0.0, le=1.0) LOCUST_HEADLESS: bool = Field(default=True) LOCUST_HOST: AnyHttpUrl = Field( - default=..., examples=["https://api.osparc-master.speag.com"] + default=..., + examples=["https://api.osparc-master.speag.com"], ) LOCUST_LOCUSTFILE: Path = Field( default=..., description="Test file. Path should be relative to `locust_files` dir", ) LOCUST_PRINT_STATS: bool = Field(default=True) - LOCUST_RUN_TIME: timedelta = Field(default=...) + LOCUST_RUN_TIME: timedelta LOCUST_SPAWN_RATE: PositiveInt = Field(default=20) LOCUST_TIMESCALE: NonNegativeInt = Field( default=1, @@ -59,7 +60,7 @@ class LocustSettings(BaseSettings): @field_validator("LOCUST_RUN_TIME", mode="before") @classmethod - def validate_run_time(cls, v: str) -> str | timedelta: + def _validate_run_time(cls, v: str) -> str | timedelta: result = parse("{hour:d}h{min:d}m{sec:d}s", v) if not isinstance(result, Result): return v @@ -67,28 +68,31 @@ def validate_run_time(cls, v: str) -> str | timedelta: _min = result.named.get("min") sec = result.named.get("sec") if hour is None or _min is None or sec is None: - raise ValueError("Could not parse time") + msg = "Could not parse time" + raise ValueError(msg) return timedelta(hours=hour, minutes=_min, seconds=sec) @field_validator("LOCUST_LOCUSTFILE", mode="after") @classmethod - def validate_locust_file(cls, v: Path) -> Path: + def _validate_locust_file(cls, v: Path) -> Path: v = v.resolve() if not v.is_file(): - raise ValueError(f"{v} must be an existing file") + msg = f"{v} must be an existing file" + raise ValueError(msg) if not v.is_relative_to(_LOCUST_FILES_DIR): - raise ValueError(f"{v} must be a test file relative to {_LOCUST_FILES_DIR}") + msg = f"{v} must be a test file relative to {_LOCUST_FILES_DIR}" + raise ValueError(msg) return v.relative_to(_TEST_DIR) @field_serializer("LOCUST_RUN_TIME") - def serialize_run_time(self, td: timedelta, info: SerializationInfo) -> str: + def _serialize_run_time(self, td: timedelta, info: SerializationInfo) -> str: total_seconds = int(td.total_seconds()) hours, remainder = divmod(total_seconds, 3600) minutes, seconds = divmod(remainder, 60) return f"{hours}h{minutes}m{seconds}s" @field_serializer("LOCUST_HOST") - def serialize_host(self, url: AnyHttpUrl, info: SerializationInfo) -> str: + def _serialize_host(self, url: AnyHttpUrl, info: SerializationInfo) -> str: # added as a temporary fix for https://github.com/pydantic/pydantic/issues/7186 s = f"{url}" return s.rstrip("/") From 89210837b6849ada439118617d504c4471435eea Mon Sep 17 00:00:00 2001 From: Pedro Crespo-Valero <32402063+pcrespov@users.noreply.github.com> Date: Mon, 19 Aug 2024 14:02:11 +0200 Subject: [PATCH 08/18] doc --- tests/performance/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/performance/README.md b/tests/performance/README.md index 4cdaa11c4fd..29ea17f540e 100644 --- a/tests/performance/README.md +++ b/tests/performance/README.md @@ -14,10 +14,12 @@ make config input="--LOCUST_HOST=https://api.osparc-master.speag.com --LOCUST_USERS=100 --LOCUST_RUN_TIME=0:10:00 --LOCUST_LOCUSTFILE=locust_files/platform_ping_test.py" ``` This will validate your settings and you should be good to go once you see a the settings printed in your terminal. + 2. Add settings related to your locust file. E.g. if your file expects to find an environment variable `MYENVVAR` you add it to `.env`: ```bash echo "MYENVVAR=thisismyenvvar" >> .env ``` + 3. Once you have all settings setup you uun your test script using the Make `test` recipe: ```bash make test From f253c00c4c6437874953d5802b0f3f65c35b7c79 Mon Sep 17 00:00:00 2001 From: Pedro Crespo-Valero <32402063+pcrespov@users.noreply.github.com> Date: Mon, 19 Aug 2024 14:32:22 +0200 Subject: [PATCH 09/18] creating new entrypoint --- .../locust_files/catalog_services2.py | 57 ------------------- .../locust_files/webserver_services.py | 43 ++++++++++---- 2 files changed, 31 insertions(+), 69 deletions(-) delete mode 100644 tests/performance/locust_files/catalog_services2.py diff --git a/tests/performance/locust_files/catalog_services2.py b/tests/performance/locust_files/catalog_services2.py deleted file mode 100644 index 9b38588ecc7..00000000000 --- a/tests/performance/locust_files/catalog_services2.py +++ /dev/null @@ -1,57 +0,0 @@ -# -# SEE https://docs.locust.io/en/stable/quickstart.html -# - -import logging -from time import time - -import faker -from locust import task -from locust.contrib.fasthttp import FastHttpUser - -logging.basicConfig(level=logging.INFO) - -fake = faker.Faker() - - -class WebApiUser(FastHttpUser): - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - - self.email = fake.email() - - @task() - def get_services_with_details(self): - start = time() - with self.client.get( - "/v0/services?user_id=1&details=true", - headers={ - "x-simcore-products-name": "osparc", - }, - catch_response=True, - ) as response: - response.raise_for_status() - num_services = len(response.json()) - print(f"got {num_services} WITH DETAILS in {time() - start}s") - response.success() - - @task() - def get_services_without_details(self): - start = time() - with self.client.get( - "/v0/services?user_id=1&details=false", - headers={ - "x-simcore-products-name": "osparc", - }, - catch_response=True, - ) as response: - response.raise_for_status() - num_services = len(response.json()) - print(f"got {num_services} in {time() - start}s") - response.success() - - def on_start(self): - print("Created User ", self.email) - - def on_stop(self): - print("Stopping", self.email) diff --git a/tests/performance/locust_files/webserver_services.py b/tests/performance/locust_files/webserver_services.py index b863f9f770c..c08b5acea8d 100644 --- a/tests/performance/locust_files/webserver_services.py +++ b/tests/performance/locust_files/webserver_services.py @@ -3,10 +3,12 @@ # import logging +import urllib +import urllib.parse import faker +import locust from dotenv import load_dotenv -from locust import task from locust.contrib.fasthttp import FastHttpUser logging.basicConfig(level=logging.INFO) @@ -22,28 +24,45 @@ def __init__(self, *args, **kwargs): self.email = fake.email() - # @task - # def health_check(self): - # self.client.get("/v0/health") + @locust.task + def list_latest_services(self): + base_url = "/v0/catalog/services/-/latest" + params = {"offset": 20, "limit": 20} - @task(weight=5) - def get_services(self): - self.client.get( - "/v0/catalog/services", - ) + while True: + response = self.client.get(base_url, params=params) + response.raise_for_status() + + page = response.json() + + # Process the current page data here + next_link = page["_links"].get("next") + if not next_link: + break + + # Update base_url and params for the next request + parsed_next = urllib.parse.urlparse(next_link) + base_url = parsed_next.path + params = dict(urllib.parse.parse_qsl(parsed_next.query)) def on_start(self): print("Created User ", self.email) + password = "testtesttest" # noqa: S105 + self.client.post( "/v0/auth/register", json={ "email": self.email, - "password": "my secret", - "confirm": "my secret", + "password": password, + "confirm": password, }, ) self.client.post( - "/v0/auth/login", json={"email": self.email, "password": "my secret"} + "/v0/auth/login", + json={ + "email": self.email, + "password": password, + }, ) def on_stop(self): From 0df051e2c488c07e7b5f96723c9ac95a481725d9 Mon Sep 17 00:00:00 2001 From: Pedro Crespo-Valero <32402063+pcrespov@users.noreply.github.com> Date: Mon, 19 Aug 2024 18:05:04 +0200 Subject: [PATCH 10/18] updates tests --- tests/e2e/tests/startupCalls.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/tests/startupCalls.test.js b/tests/e2e/tests/startupCalls.test.js index bf0b1e92320..3276b105b68 100644 --- a/tests/e2e/tests/startupCalls.test.js +++ b/tests/e2e/tests/startupCalls.test.js @@ -33,7 +33,7 @@ describe('Calls after logging in', () => { }, ourTimeout); test('Services', async () => { - const responseEnv = await utils.fetchReq('catalog/services'); + const responseEnv = await utils.fetchReq('catalog/services/-/latest'); expect(Array.isArray(responseEnv.data)).toBeTruthy(); expect(responseEnv.data.length).toBeGreaterThan(0); }, ourTimeout); From aceefdf2b5a22f739bb5bb6e7a79b15b03eb4a9b Mon Sep 17 00:00:00 2001 From: Pedro Crespo-Valero <32402063+pcrespov@users.noreply.github.com> Date: Mon, 19 Aug 2024 18:06:30 +0200 Subject: [PATCH 11/18] ignore locust report --- .gitignore | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index 681ae664847..bdeeb087ed8 100644 --- a/.gitignore +++ b/.gitignore @@ -40,18 +40,21 @@ pip-log.txt pip-delete-this-directory.txt # Unit test / coverage reports -htmlcov/ -.tox/ +.cache .coverage .coverage.* -.cache -nosetests.xml -coverage.xml -cov.xml -*.cover .hypothesis/ .pytest_cache/ +.tox/ +*.cover +cov.xml +coverage.xml +htmlcov/ +locust_report/ +nosetests.xml test_failures/ + + # Translations *.mo *.pot From cc411619f03204526bc299645880833ea2600528 Mon Sep 17 00:00:00 2001 From: Pedro Crespo-Valero <32402063+pcrespov@users.noreply.github.com> Date: Mon, 19 Aug 2024 19:37:52 +0200 Subject: [PATCH 12/18] log --- tests/e2e/tests/startupCalls.test.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/e2e/tests/startupCalls.test.js b/tests/e2e/tests/startupCalls.test.js index 3276b105b68..315c2ae63c4 100644 --- a/tests/e2e/tests/startupCalls.test.js +++ b/tests/e2e/tests/startupCalls.test.js @@ -34,6 +34,9 @@ describe('Calls after logging in', () => { test('Services', async () => { const responseEnv = await utils.fetchReq('catalog/services/-/latest'); + console.log('Status Code:', responseEnv.status); + console.log('Response Data:', responseEnv.data); + expect(Array.isArray(responseEnv.data)).toBeTruthy(); expect(responseEnv.data.length).toBeGreaterThan(0); }, ourTimeout); From 8632fbcaaacdabee73d8c4f1f2e34cd63e248ccd Mon Sep 17 00:00:00 2001 From: Pedro Crespo-Valero <32402063+pcrespov@users.noreply.github.com> Date: Mon, 19 Aug 2024 19:53:59 +0200 Subject: [PATCH 13/18] log --- tests/e2e/tests/startupCalls.test.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/e2e/tests/startupCalls.test.js b/tests/e2e/tests/startupCalls.test.js index 315c2ae63c4..36ef2a7f7fe 100644 --- a/tests/e2e/tests/startupCalls.test.js +++ b/tests/e2e/tests/startupCalls.test.js @@ -34,11 +34,10 @@ describe('Calls after logging in', () => { test('Services', async () => { const responseEnv = await utils.fetchReq('catalog/services/-/latest'); - console.log('Status Code:', responseEnv.status); console.log('Response Data:', responseEnv.data); - - expect(Array.isArray(responseEnv.data)).toBeTruthy(); - expect(responseEnv.data.length).toBeGreaterThan(0); + expect(responseEnv.data._meta.total).toBeGreaterThan(0); + expect(Array.isArray(responseEnv.data.data)).toBeTruthy(); + expect(responseEnv.data.data.length).toBeGreaterThan(0); }, ourTimeout); test('Locations', async () => { From b22db3799417f3103bc32a363b9a61f9180780d1 Mon Sep 17 00:00:00 2001 From: Pedro Crespo-Valero <32402063+pcrespov@users.noreply.github.com> Date: Mon, 19 Aug 2024 19:57:41 +0200 Subject: [PATCH 14/18] minor --- tests/e2e/tests/startupCalls.test.js | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/e2e/tests/startupCalls.test.js b/tests/e2e/tests/startupCalls.test.js index 36ef2a7f7fe..c9ce849056f 100644 --- a/tests/e2e/tests/startupCalls.test.js +++ b/tests/e2e/tests/startupCalls.test.js @@ -34,7 +34,6 @@ describe('Calls after logging in', () => { test('Services', async () => { const responseEnv = await utils.fetchReq('catalog/services/-/latest'); - console.log('Response Data:', responseEnv.data); expect(responseEnv.data._meta.total).toBeGreaterThan(0); expect(Array.isArray(responseEnv.data.data)).toBeTruthy(); expect(responseEnv.data.data.length).toBeGreaterThan(0); From 772907155589fddc36cf330d5071610c54c02f02 Mon Sep 17 00:00:00 2001 From: Pedro Crespo-Valero <32402063+pcrespov@users.noreply.github.com> Date: Tue, 20 Aug 2024 11:23:38 +0200 Subject: [PATCH 15/18] doc --- tests/performance/locust_settings.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/performance/locust_settings.py b/tests/performance/locust_settings.py index 733c6a7304e..24f896180fd 100644 --- a/tests/performance/locust_settings.py +++ b/tests/performance/locust_settings.py @@ -43,6 +43,10 @@ class LocustSettings(BaseSettings): LOCUST_PRINT_STATS: bool = Field(default=True) LOCUST_RUN_TIME: timedelta LOCUST_SPAWN_RATE: PositiveInt = Field(default=20) + + # Options for Timescale + Grafana Dashboards + # SEE https://github.com/SvenskaSpel/locust-plugins/blob/master/locust_plugins/timescale/ + # LOCUST_TIMESCALE: NonNegativeInt = Field( default=1, ge=0, @@ -50,7 +54,8 @@ class LocustSettings(BaseSettings): description="Send locust data to Timescale db for reading in Grafana dashboards", ) LOCUST_USERS: PositiveInt = Field( - default=..., description="Number of locust users you want to spawn" + default=..., + description="Number of locust users you want to spawn", ) PGHOST: str = Field(default="postgres") From fb12718a415dde46068fdfd074a1047140cd0b5b Mon Sep 17 00:00:00 2001 From: Pedro Crespo-Valero <32402063+pcrespov@users.noreply.github.com> Date: Tue, 20 Aug 2024 11:57:26 +0200 Subject: [PATCH 16/18] cleanup --- tests/performance/Dockerfile | 2 +- tests/performance/Makefile | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/tests/performance/Dockerfile b/tests/performance/Dockerfile index fab828ca6f4..75c71125f15 100644 --- a/tests/performance/Dockerfile +++ b/tests/performance/Dockerfile @@ -1,6 +1,6 @@ ARG LOCUST_VERSION -FROM locustio/locust:${LOCUST_VERSION} +FROM locustio/locust:${LOCUST_VERSION:-2.29.1} RUN pip3 --version && \ diff --git a/tests/performance/Makefile b/tests/performance/Makefile index 6035b112203..2ceae020ea5 100644 --- a/tests/performance/Makefile +++ b/tests/performance/Makefile @@ -30,7 +30,13 @@ __check_defined = \ .PHONY: build build: ## builds distributed osparc locust docker image - docker buildx build --load --build-arg LOCUST_VERSION=$(LOCUST_VERSION) --tag itisfoundation/locust:$(LOCUST_VERSION) --tag local/locust:latest . + docker --debug \ + buildx build \ + --load \ + --build-arg LOCUST_VERSION=$(LOCUST_VERSION) \ + --tag itisfoundation/locust:$(LOCUST_VERSION) \ + --tag local/locust:latest \ + . .PHONY: push push: From 025c41fc663fbf0d9ca2d8509bc55e0c7f9e4f80 Mon Sep 17 00:00:00 2001 From: Pedro Crespo-Valero <32402063+pcrespov@users.noreply.github.com> Date: Tue, 20 Aug 2024 14:17:54 +0200 Subject: [PATCH 17/18] @sanderegg review: rm flag --- tests/performance/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/performance/Makefile b/tests/performance/Makefile index 2ceae020ea5..3c06c138c64 100644 --- a/tests/performance/Makefile +++ b/tests/performance/Makefile @@ -30,7 +30,7 @@ __check_defined = \ .PHONY: build build: ## builds distributed osparc locust docker image - docker --debug \ + docker \ buildx build \ --load \ --build-arg LOCUST_VERSION=$(LOCUST_VERSION) \ From 52715c7016b367ad79cd9c943236c0a3e28f9eae Mon Sep 17 00:00:00 2001 From: Pedro Crespo-Valero <32402063+pcrespov@users.noreply.github.com> Date: Tue, 20 Aug 2024 17:05:39 +0200 Subject: [PATCH 18/18] @sanderegg review: default --- tests/performance/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/performance/Dockerfile b/tests/performance/Dockerfile index 75c71125f15..5f13ae3a88f 100644 --- a/tests/performance/Dockerfile +++ b/tests/performance/Dockerfile @@ -1,6 +1,6 @@ -ARG LOCUST_VERSION -FROM locustio/locust:${LOCUST_VERSION:-2.29.1} +ARG LOCUST_VERSION=latest +FROM locustio/locust:${LOCUST_VERSION} RUN pip3 --version && \