Skip to content

Commit 6c9b15a

Browse files
authored
♻️ webserver: catalog & api_keys renaming of modules (#7334)
1 parent 60f74ff commit 6c9b15a

21 files changed

+162
-164
lines changed

api/specs/web-server/_auth_api_keys.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@
1010
from models_library.rest_error import EnvelopedError
1111
from simcore_service_webserver._meta import API_VTAG
1212
from simcore_service_webserver.api_keys._controller_rest import ApiKeysPathParams
13-
from simcore_service_webserver.api_keys._exceptions_handlers import _TO_HTTP_ERROR_MAP
13+
from simcore_service_webserver.api_keys._controller_rest_exceptions import (
14+
_TO_HTTP_ERROR_MAP,
15+
)
1416

1517
router = APIRouter(
1618
prefix=f"/{API_VTAG}",

api/specs/web-server/_catalog.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,13 @@
1515
from models_library.generics import Envelope
1616
from models_library.rest_pagination import Page
1717
from simcore_service_webserver._meta import API_VTAG
18-
from simcore_service_webserver.catalog._rest_controller import (
18+
from simcore_service_webserver.catalog._controller_rest_schemas import (
19+
FromServiceOutputQueryParams,
1920
ListServiceParams,
21+
ServiceInputsPathParams,
22+
ServiceOutputsPathParams,
2023
ServicePathParams,
21-
_FromServiceOutputParams,
22-
_ServiceInputsPathParams,
23-
_ServiceOutputsPathParams,
24-
_ToServiceInputsParams,
24+
ToServiceInputsQueryParams,
2525
)
2626

2727
router = APIRouter(
@@ -71,7 +71,7 @@ def list_service_inputs(
7171
response_model=Envelope[ServiceInputGet],
7272
)
7373
def get_service_input(
74-
_path: Annotated[_ServiceInputsPathParams, Depends()],
74+
_path: Annotated[ServiceInputsPathParams, Depends()],
7575
): ...
7676

7777

@@ -81,7 +81,7 @@ def get_service_input(
8181
)
8282
def get_compatible_inputs_given_source_output(
8383
_path: Annotated[ServicePathParams, Depends()],
84-
_query: Annotated[_FromServiceOutputParams, Depends()],
84+
_query: Annotated[FromServiceOutputQueryParams, Depends()],
8585
): ...
8686

8787

@@ -99,7 +99,7 @@ def list_service_outputs(
9999
response_model=Envelope[list[ServiceOutputGet]],
100100
)
101101
def get_service_output(
102-
_path: Annotated[_ServiceOutputsPathParams, Depends()],
102+
_path: Annotated[ServiceOutputsPathParams, Depends()],
103103
): ...
104104

105105

@@ -109,7 +109,7 @@ def get_service_output(
109109
)
110110
def get_compatible_outputs_given_target_input(
111111
_path: Annotated[ServicePathParams, Depends()],
112-
_query: Annotated[_ToServiceInputsParams, Depends()],
112+
_query: Annotated[ToServiceInputsQueryParams, Depends()],
113113
): ...
114114

115115

api/specs/web-server/_catalog_tags.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from models_library.api_schemas_webserver.catalog import CatalogServiceGet
1111
from models_library.generics import Envelope
1212
from simcore_service_webserver._meta import API_VTAG
13-
from simcore_service_webserver.catalog._rest_tags_controller import (
13+
from simcore_service_webserver.catalog._controller_rest_schemas import (
1414
ServicePathParams,
1515
ServiceTagPathParams,
1616
)

packages/models-library/src/models_library/rest_pagination.py

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
int, Field(ge=1, lt=MAXIMUM_NUMBER_OF_ITEMS_PER_PAGE)
2727
]
2828

29+
PageOffsetInt: TypeAlias = NonNegativeInt
30+
2931
DEFAULT_NUMBER_OF_ITEMS_PER_PAGE: Final[PageLimitInt] = TypeAdapter(
3032
PageLimitInt
3133
).validate_python(20)
@@ -51,15 +53,19 @@ class CursorQueryParameters(RequestParameters):
5153
class PageQueryParameters(RequestParameters):
5254
"""Use as pagination options in query parameters"""
5355

54-
limit: PageLimitInt = Field(
55-
default=TypeAdapter(PageLimitInt).validate_python(
56-
DEFAULT_NUMBER_OF_ITEMS_PER_PAGE
56+
limit: Annotated[
57+
PageLimitInt,
58+
Field(
59+
default=TypeAdapter(PageLimitInt).validate_python(
60+
DEFAULT_NUMBER_OF_ITEMS_PER_PAGE
61+
),
62+
description="maximum number of items to return (pagination)",
5763
),
58-
description="maximum number of items to return (pagination)",
59-
)
60-
offset: NonNegativeInt = Field(
61-
default=0, description="index to the first item to return (pagination)"
62-
)
64+
]
65+
offset: Annotated[
66+
PageOffsetInt,
67+
Field(default=0, description="index to the first item to return (pagination)"),
68+
]
6369

6470

6571
class PageMetaInfoLimitOffset(BaseModel):
@@ -120,8 +126,7 @@ class PageLinks(
120126
BeforeValidator(lambda x: str(TypeAdapter(AnyHttpUrl).validate_python(x))),
121127
]
122128
]
123-
):
124-
...
129+
): ...
125130

126131

127132
ItemT = TypeVar("ItemT")

services/web/server/src/simcore_service_webserver/api_keys/_controller_rest.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
from ..security.decorators import permission_required
2424
from ..utils_aiohttp import envelope_json_response
2525
from . import _service
26-
from ._exceptions_handlers import handle_plugin_requests_exceptions
26+
from ._controller_rest_exceptions import handle_plugin_requests_exceptions
2727
from .models import ApiKey
2828

2929
_logger = logging.getLogger(__name__)

services/web/server/src/simcore_service_webserver/catalog/_catalog_rest_client_service.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,11 @@
2121
from servicelib.aiohttp import status
2222
from servicelib.aiohttp.client_session import get_client_session
2323
from servicelib.rest_constants import X_PRODUCT_NAME_HEADER
24-
from settings_library.catalog import CatalogSettings
2524
from yarl import URL
2625

2726
from .._meta import api_version_prefix
2827
from ._constants import MSG_CATALOG_SERVICE_NOT_FOUND, MSG_CATALOG_SERVICE_UNAVAILABLE
29-
from .settings import get_plugin_settings
28+
from .settings import CatalogSettings, get_plugin_settings
3029

3130
_logger = logging.getLogger(__name__)
3231

services/web/server/src/simcore_service_webserver/catalog/_rest_controller.py renamed to services/web/server/src/simcore_service_webserver/catalog/_controller_rest.py

Lines changed: 56 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,14 @@
1414
from models_library.api_schemas_webserver.catalog import (
1515
CatalogServiceGet,
1616
CatalogServiceUpdate,
17-
ServiceInputKey,
18-
ServiceOutputKey,
1917
)
2018
from models_library.api_schemas_webserver.resource_usage import PricingPlanGet
21-
from models_library.rest_pagination import Page, PageQueryParameters
19+
from models_library.rest_pagination import Page
2220
from models_library.rest_pagination_utils import paginate_data
23-
from models_library.services import ServiceKey, ServiceVersion
2421
from models_library.services_resources import (
2522
ServiceResourcesDict,
2623
ServiceResourcesDictHelpers,
2724
)
28-
from pydantic import BaseModel, Field
2925
from servicelib.aiohttp.requests_validation import (
3026
parse_request_body_as,
3127
parse_request_path_parameters_as,
@@ -39,14 +35,19 @@
3935
from ..security.decorators import permission_required
4036
from ..utils_aiohttp import envelope_json_response
4137
from . import _catalog_rest_client_service, _service
42-
from ._exceptions import (
38+
from ._controller_rest_exceptions import (
4339
DefaultPricingUnitForServiceNotFoundError,
4440
handle_plugin_requests_exceptions,
4541
)
46-
from .controller_rest_schemas import (
42+
from ._controller_rest_schemas import (
4743
CatalogRequestContext,
44+
FromServiceOutputQueryParams,
4845
ListServiceParams,
46+
ServiceInputsPathParams,
47+
ServiceOutputsPathParams,
4948
ServicePathParams,
49+
ServiceTagPathParams,
50+
ToServiceInputsQueryParams,
5051
)
5152

5253
_logger = logging.getLogger(__name__)
@@ -75,9 +76,8 @@ async def list_services_latest(request: Request):
7576
user_id=request_ctx.user_id,
7677
product_name=request_ctx.product_name,
7778
unit_registry=request_ctx.unit_registry,
78-
page_params=PageQueryParameters.model_construct(
79-
offset=query_params.offset, limit=query_params.limit
80-
),
79+
offset=query_params.offset,
80+
limit=query_params.limit,
8181
)
8282

8383
assert page_meta.limit == query_params.limit # nosec
@@ -173,10 +173,6 @@ async def list_service_inputs(request: Request):
173173
)
174174

175175

176-
class _ServiceInputsPathParams(ServicePathParams):
177-
input_key: ServiceInputKey
178-
179-
180176
@routes.get(
181177
f"{VTAG}/catalog/services/{{service_key}}/{{service_version}}/inputs/{{input_key}}",
182178
name="get_service_input",
@@ -185,7 +181,7 @@ class _ServiceInputsPathParams(ServicePathParams):
185181
@permission_required("services.catalog.*")
186182
async def get_service_input(request: Request):
187183
ctx = CatalogRequestContext.create(request)
188-
path_params = parse_request_path_parameters_as(_ServiceInputsPathParams, request)
184+
path_params = parse_request_path_parameters_as(ServiceInputsPathParams, request)
189185

190186
# Evaluate and return validated model
191187
response_model = await _service.get_service_input(
@@ -201,12 +197,6 @@ async def get_service_input(request: Request):
201197
)
202198

203199

204-
class _FromServiceOutputParams(BaseModel):
205-
from_service_key: ServiceKey = Field(..., alias="fromService")
206-
from_service_version: ServiceVersion = Field(..., alias="fromVersion")
207-
from_output_key: ServiceOutputKey = Field(..., alias="fromOutput")
208-
209-
210200
@routes.get(
211201
f"{VTAG}/catalog/services/{{service_key}}/{{service_version}}/inputs:match",
212202
name="get_compatible_inputs_given_source_output",
@@ -216,8 +206,8 @@ class _FromServiceOutputParams(BaseModel):
216206
async def get_compatible_inputs_given_source_output(request: Request):
217207
ctx = CatalogRequestContext.create(request)
218208
path_params = parse_request_path_parameters_as(ServicePathParams, request)
219-
query_params: _FromServiceOutputParams = parse_request_query_parameters_as(
220-
_FromServiceOutputParams, request
209+
query_params: FromServiceOutputQueryParams = parse_request_query_parameters_as(
210+
FromServiceOutputQueryParams, request
221211
)
222212

223213
# Evaluate and return validated model
@@ -256,10 +246,6 @@ async def list_service_outputs(request: Request):
256246
)
257247

258248

259-
class _ServiceOutputsPathParams(ServicePathParams):
260-
output_key: ServiceOutputKey
261-
262-
263249
@routes.get(
264250
f"{VTAG}/catalog/services/{{service_key}}/{{service_version}}/outputs/{{output_key}}",
265251
name="get_service_output",
@@ -268,7 +254,7 @@ class _ServiceOutputsPathParams(ServicePathParams):
268254
@permission_required("services.catalog.*")
269255
async def get_service_output(request: Request):
270256
ctx = CatalogRequestContext.create(request)
271-
path_params = parse_request_path_parameters_as(_ServiceOutputsPathParams, request)
257+
path_params = parse_request_path_parameters_as(ServiceOutputsPathParams, request)
272258

273259
# Evaluate and return validated model
274260
response_model = await _service.get_service_output(
@@ -284,12 +270,6 @@ async def get_service_output(request: Request):
284270
)
285271

286272

287-
class _ToServiceInputsParams(BaseModel):
288-
to_service_key: ServiceKey = Field(..., alias="toService")
289-
to_service_version: ServiceVersion = Field(..., alias="toVersion")
290-
to_input_key: ServiceInputKey = Field(..., alias="toInput")
291-
292-
293273
@routes.get(
294274
f"{VTAG}/catalog/services/{{service_key}}/{{service_version}}/outputs:match",
295275
name="get_compatible_outputs_given_target_input",
@@ -304,8 +284,8 @@ async def get_compatible_outputs_given_target_input(request: Request):
304284
"""
305285
ctx = CatalogRequestContext.create(request)
306286
path_params = parse_request_path_parameters_as(ServicePathParams, request)
307-
query_params: _ToServiceInputsParams = parse_request_query_parameters_as(
308-
_ToServiceInputsParams, request
287+
query_params: ToServiceInputsQueryParams = parse_request_query_parameters_as(
288+
ToServiceInputsQueryParams, request
309289
)
310290

311291
data = await _service.get_compatible_outputs_given_target_input(
@@ -377,3 +357,43 @@ async def get_service_pricing_plan(request: Request):
377357
return envelope_json_response(
378358
PricingPlanGet.model_validate(pricing_plan.model_dump())
379359
)
360+
361+
362+
@routes.get(
363+
f"/{API_VTAG}/catalog/services/{{service_key}}/{{service_version}}/tags",
364+
name="list_service_tags",
365+
)
366+
@login_required
367+
@permission_required("service.tag.*")
368+
async def list_service_tags(request: web.Request):
369+
path_params = parse_request_path_parameters_as(ServicePathParams, request)
370+
assert path_params # nosec
371+
raise NotImplementedError
372+
373+
374+
@routes.post(
375+
f"/{API_VTAG}/catalog/services/{{service_key}}/{{service_version}}/tags/{{tag_id}}:add",
376+
name="add_service_tag",
377+
)
378+
@login_required
379+
@permission_required("service.tag.*")
380+
async def add_service_tag(request: web.Request):
381+
path_params = parse_request_path_parameters_as(ServiceTagPathParams, request)
382+
assert path_params # nosec
383+
384+
# responds with parent's resource to get the current state (as with patch/update)
385+
raise NotImplementedError
386+
387+
388+
@routes.post(
389+
f"/{API_VTAG}/catalog/services/{{service_key}}/{{service_version}}/tags/{{tag_id}}:remove",
390+
name="remove_service_tag",
391+
)
392+
@login_required
393+
@permission_required("service.tag.*")
394+
async def remove_service_tag(request: web.Request):
395+
path_params = parse_request_path_parameters_as(ServiceTagPathParams, request)
396+
assert path_params # nosec
397+
398+
# responds with parent's resource to get the current state (as with patch/update)
399+
raise NotImplementedError

services/web/server/src/simcore_service_webserver/catalog/_exceptions.py renamed to services/web/server/src/simcore_service_webserver/catalog/_controller_rest_exceptions.py

Lines changed: 1 addition & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,37 +6,14 @@
66
CatalogItemNotFoundError,
77
)
88

9-
from ..errors import WebServerBaseError
109
from ..exception_handling import (
1110
ExceptionToHttpErrorMap,
1211
HttpErrorInfo,
1312
exception_handling_decorator,
1413
to_exceptions_handlers_map,
1514
)
1615
from ..resource_usage.errors import DefaultPricingPlanNotFoundError
17-
18-
19-
class BaseCatalogError(WebServerBaseError):
20-
msg_template = "Unexpected error occured in catalog submodule"
21-
22-
def __init__(self, msg=None, **ctx):
23-
super().__init__(**ctx)
24-
if msg:
25-
self.msg_template = msg
26-
27-
def debug_message(self):
28-
# Override in subclass
29-
return f"{self.code}: {self}"
30-
31-
32-
class DefaultPricingUnitForServiceNotFoundError(BaseCatalogError):
33-
msg_template = "Default pricing unit not found for service key '{service_key}' and version '{service_version}'"
34-
35-
def __init__(self, *, service_key: str, service_version: str, **ctxs):
36-
super().__init__(**ctxs)
37-
self.service_key = service_key
38-
self.service_version = service_version
39-
16+
from .errors import DefaultPricingUnitForServiceNotFoundError
4017

4118
# mypy: disable-error-code=truthy-function
4219
assert CatalogForbiddenError # nosec

0 commit comments

Comments
 (0)