diff --git a/services/director-v2/openapi.json b/services/director-v2/openapi.json index 5f57b836564b..b73eea273ef4 100644 --- a/services/director-v2/openapi.json +++ b/services/director-v2/openapi.json @@ -65,9 +65,9 @@ "tags": [ "computations" ], - "summary": "Create Computation", + "summary": "Create Or Update Or Start Computation", "description": "Create and optionally start a new computation", - "operationId": "create_computation_v2_computations_post", + "operationId": "create_or_update_or_start_computation_v2_computations_post", "requestBody": { "content": { "application/json": { diff --git a/services/director-v2/src/simcore_service_director_v2/api/routes/computations.py b/services/director-v2/src/simcore_service_director_v2/api/routes/computations.py index 9f096911030a..4a0bd5dfc20a 100644 --- a/services/director-v2/src/simcore_service_director_v2/api/routes/computations.py +++ b/services/director-v2/src/simcore_service_director_v2/api/routes/computations.py @@ -268,7 +268,8 @@ async def _try_start_pipeline( ) # NOTE: in case of a burst of calls to that endpoint, we might end up in a weird state. @run_sequentially_in_context(target_args=["computation.project_id"]) -async def create_computation( # noqa: PLR0913 # pylint: disable=too-many-positional-arguments +# NOTE: This endpoint is historically used for CREATE, UPDATE or START a computation! +async def create_or_update_or_start_computation( # noqa: PLR0913 # pylint: disable=too-many-positional-arguments computation: ComputationCreate, request: Request, project_repo: Annotated[ diff --git a/services/web/server/src/simcore_service_webserver/director_v2/_director_v2_service.py b/services/web/server/src/simcore_service_webserver/director_v2/_director_v2_service.py index fa8f98f0c6b6..0670781c281c 100644 --- a/services/web/server/src/simcore_service_webserver/director_v2/_director_v2_service.py +++ b/services/web/server/src/simcore_service_webserver/director_v2/_director_v2_service.py @@ -66,6 +66,7 @@ async def create_or_update_pipeline( user_id=user_id, project_id=project_id, product_name=product_name, + check_user_wallet_permission=False, ), } @@ -203,6 +204,7 @@ async def get_wallet_info( user_id: UserID, project_id: ProjectID, product_name: ProductName, + check_user_wallet_permission: bool = True, ) -> WalletInfo | None: app_settings = get_application_settings(app) if not ( @@ -234,13 +236,24 @@ async def get_wallet_info( else: project_wallet_id = project_wallet.wallet_id - # Check whether user has access to the wallet - wallet = await wallets_service.get_wallet_with_available_credits_by_user_and_wallet( - app, - user_id=user_id, - wallet_id=project_wallet_id, - product_name=product_name, - ) + if check_user_wallet_permission: + # Check whether user has access to the wallet + wallet = ( + await wallets_service.get_wallet_with_available_credits_by_user_and_wallet( + app, + user_id=user_id, + wallet_id=project_wallet_id, + product_name=product_name, + ) + ) + else: + # This function is used also when we are synchronizing the projects/projects_nodes with the comp_pipelines/comp_tasks tables in director-v2 + # In situations where a project is connected to a wallet, but the user does not have access to it and is performing an action such as + # upgrading the service version, we still want to retrieve the wallet info and pass it to director-v2. + wallet = await wallets_service.get_wallet_with_available_credits( + app, wallet_id=project_wallet_id, product_name=product_name + ) + return WalletInfo( wallet_id=project_wallet_id, wallet_name=wallet.name, diff --git a/services/web/server/src/simcore_service_webserver/projects/_projects_service.py b/services/web/server/src/simcore_service_webserver/projects/_projects_service.py index 7797ba4bf0ef..c7007a8c5311 100644 --- a/services/web/server/src/simcore_service_webserver/projects/_projects_service.py +++ b/services/web/server/src/simcore_service_webserver/projects/_projects_service.py @@ -1153,7 +1153,7 @@ async def patch_project_node( partial_node=partial_node, ) - # 4. Make calls to director-v2 to keep data in sync (ex. comp_tasks DB table) + # 4. Make calls to director-v2 to keep data in sync (ex. comp_* DB tables) await director_v2_service.create_or_update_pipeline( app, user_id, diff --git a/services/web/server/src/simcore_service_webserver/wallets/_api.py b/services/web/server/src/simcore_service_webserver/wallets/_api.py index dd092e2a39fc..de52fdda769a 100644 --- a/services/web/server/src/simcore_service_webserver/wallets/_api.py +++ b/services/web/server/src/simcore_service_webserver/wallets/_api.py @@ -108,6 +108,33 @@ async def get_wallet_with_available_credits_by_user_and_wallet( ) +async def get_wallet_with_available_credits( + app: web.Application, + *, + wallet_id: WalletID, + product_name: ProductName, +) -> WalletGetWithAvailableCredits: + wallet_db: WalletDB = await db.get_wallet( + app=app, wallet_id=wallet_id, product_name=product_name + ) + + available_credits: WalletTotalCredits = await get_wallet_total_available_credits( + app, product_name, wallet_db.wallet_id + ) + + return WalletGetWithAvailableCredits( + wallet_id=wallet_db.wallet_id, + name=IDStr(wallet_db.name), + description=wallet_db.description, + owner=wallet_db.owner, + thumbnail=wallet_db.thumbnail, + status=wallet_db.status, + created=wallet_db.created, + modified=wallet_db.modified, + available_credits=available_credits.available_osparc_credits, + ) + + async def get_user_default_wallet_with_available_credits( app: web.Application, *, diff --git a/services/web/server/src/simcore_service_webserver/wallets/api.py b/services/web/server/src/simcore_service_webserver/wallets/api.py index 8df130d49059..bdeabab0f29d 100644 --- a/services/web/server/src/simcore_service_webserver/wallets/api.py +++ b/services/web/server/src/simcore_service_webserver/wallets/api.py @@ -1,5 +1,6 @@ from ._api import ( get_wallet_by_user, + get_wallet_with_available_credits, get_wallet_with_available_credits_by_user_and_wallet, get_wallet_with_permissions_by_user, list_wallets_for_user, @@ -8,6 +9,7 @@ __all__: tuple[str, ...] = ( "get_wallet_by_user", + "get_wallet_with_available_credits", "get_wallet_with_permissions_by_user", "get_wallet_with_available_credits_by_user_and_wallet", "list_wallets_for_user",