Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ do not allow start service when credits bellow zero #4905

4 changes: 4 additions & 0 deletions packages/models-library/src/models_library/wallets.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from datetime import datetime
from decimal import Decimal
from enum import auto
from typing import Any, ClassVar, TypeAlias

Expand All @@ -24,6 +25,9 @@ class Config:
}


ZERO_CREDITS = Decimal(0)


### DB


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from models_library.clusters import ClusterID
from models_library.projects import ProjectID
from models_library.users import UserID
from models_library.wallets import WalletID, WalletInfo
from models_library.wallets import ZERO_CREDITS, WalletID, WalletInfo
from pydantic import BaseModel, Field, ValidationError, parse_obj_as
from pydantic.types import NonNegativeInt
from servicelib.aiohttp.rest_responses import create_error_response, get_http_error
Expand All @@ -22,6 +22,7 @@
)
from simcore_service_webserver.db.plugin import get_database_engine
from simcore_service_webserver.users.exceptions import UserDefaultWalletNotFoundError
from simcore_service_webserver.wallets.errors import WalletNotEnoughCreditsError
matusdrobuliak66 marked this conversation as resolved.
Show resolved Hide resolved

from .._constants import RQ_PRODUCT_KEY
from .._meta import API_VTAG as VTAG
Expand Down Expand Up @@ -130,9 +131,13 @@ async def start_computation(request: web.Request) -> web.Response:
project_wallet_id = project_wallet.wallet_id

# Check whether user has access to the wallet
wallet = await wallets_api.get_wallet_by_user(
wallet = await wallets_api.get_wallet_with_available_credits_by_user_and_wallet(
request.app, req_ctx.user_id, project_wallet_id, req_ctx.product_name
)
if wallet.available_credits <= ZERO_CREDITS:
matusdrobuliak66 marked this conversation as resolved.
Show resolved Hide resolved
raise WalletNotEnoughCreditsError(
reason=f"Wallet {wallet.wallet_id} credit balance {wallet.available_credits}"
)
wallet_info = WalletInfo(wallet_id=project_wallet_id, wallet_name=wallet.name)

options = {
Expand Down Expand Up @@ -199,6 +204,8 @@ async def start_computation(request: web.Request) -> web.Response:
)
except UserDefaultWalletNotFoundError as exc:
return create_error_response(exc, http_error_cls=web.HTTPNotFound)
except WalletNotEnoughCreditsError as exc:
return create_error_response(exc, http_error_cls=web.HTTPPaymentRequired)


@routes.post(f"/{VTAG}/computations/{{project_id}}:stop", name="stop_computation")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
from servicelib.json_serialization import json_dumps
from servicelib.mimetype_constants import MIMETYPE_APPLICATION_JSON
from simcore_postgres_database.models.users import UserRole
from simcore_service_webserver.wallets.errors import WalletNotEnoughCreditsError
matusdrobuliak66 marked this conversation as resolved.
Show resolved Hide resolved

from .._meta import API_VTAG as VTAG
from ..catalog import client as catalog_client
Expand Down Expand Up @@ -83,6 +84,8 @@ async def wrapper(request: web.Request) -> web.StreamResponse:
DefaultPricingUnitNotFoundError,
) as exc:
raise web.HTTPNotFound(reason=f"{exc}") from exc
except (WalletNotEnoughCreditsError) as exc:
raise web.HTTPPaymentRequired(reason=f"{exc}") from exc

return wrapper

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
from models_library.services_resources import ServiceResourcesDict
from models_library.users import UserID
from models_library.utils.fastapi_encoders import jsonable_encoder
from models_library.wallets import WalletID, WalletInfo
from models_library.wallets import ZERO_CREDITS, WalletID, WalletInfo
from pydantic import parse_obj_as
from servicelib.aiohttp.application_keys import APP_FIRE_AND_FORGET_TASKS_KEY
from servicelib.common_headers import (
Expand All @@ -57,6 +57,7 @@
ProjectNodesNodeNotFound,
)
from simcore_postgres_database.webserver_models import ProjectType
from simcore_service_webserver.wallets.errors import WalletNotEnoughCreditsError
matusdrobuliak66 marked this conversation as resolved.
Show resolved Hide resolved

from ..application_settings import get_settings
from ..catalog import client as catalog_client
Expand Down Expand Up @@ -337,9 +338,15 @@ async def _start_dynamic_service(
else:
project_wallet_id = project_wallet.wallet_id
# Check whether user has access to the wallet
wallet = await wallets_api.get_wallet_by_user(
request.app, user_id, project_wallet_id, product_name
wallet = (
await wallets_api.get_wallet_with_available_credits_by_user_and_wallet(
request.app, user_id, project_wallet_id, product_name
)
)
if wallet.available_credits <= ZERO_CREDITS:
raise WalletNotEnoughCreditsError(
reason=f"Wallet {wallet.wallet_id} credit balance {wallet.available_credits}"
)
wallet_info = WalletInfo(
wallet_id=project_wallet_id, wallet_name=wallet.name
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from ._api import (
get_wallet_by_user,
get_wallet_with_available_credits_by_user_and_wallet,
get_wallet_with_permissions_by_user,
list_wallets_for_user,
)
Expand All @@ -8,6 +9,7 @@
__all__: tuple[str, ...] = (
"get_wallet_by_user",
"get_wallet_with_permissions_by_user",
"get_wallet_with_available_credits_by_user_and_wallet",
"list_wallets_for_user",
"list_wallet_groups_with_read_access_by_wallet",
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ class WalletAccessForbiddenError(WalletsValueError):
msg_template = "Wallet access forbidden. {reason}"


class WalletNotEnoughCreditsError(WalletsValueError):
msg_template = "Wallet does not have enough credits. {reason}"


# Wallet groups


Expand Down