Skip to content

Commit 0cc540f

Browse files
authored
šŸ› Fixes access rights fields in web-api's PATCH services input model (#6180)
1 parent d4e6096 commit 0cc540f

File tree

12 files changed

+79
-106
lines changed

12 files changed

+79
-106
lines changed

ā€Žpackages/models-library/src/models_library/api_schemas_catalog/services.pyā€Ž

Lines changed: 38 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1+
from datetime import datetime
12
from typing import Any, ClassVar, TypeAlias
23

34
from models_library.rpc_pagination import PageRpc
45
from pydantic import BaseModel, Extra, Field, HttpUrl, NonNegativeInt
56

67
from ..boot_options import BootOptions
78
from ..emails import LowerCaseEmailStr
8-
from ..services_access import ServiceAccessRights
9+
from ..services_access import ServiceAccessRights, ServiceGroupAccessRightsV2
910
from ..services_authoring import Author
1011
from ..services_enums import ServiceType
1112
from ..services_history import ServiceRelease
@@ -108,14 +109,22 @@ class Config:
108109
"owner": "[email protected]",
109110
}
110111

112+
_EXAMPLE_FILEPICKER_V2 = {
113+
**_EXAMPLE_FILEPICKER,
114+
"accessRights": {
115+
"1": {"execute": True, "write": False},
116+
"4": {"execute": True, "write": True},
117+
},
118+
}
119+
111120

112121
_EXAMPLE_SLEEPER: dict[str, Any] = {
113122
"name": "sleeper",
114123
"thumbnail": None,
115124
"description": "A service which awaits for time to pass, two times.",
116125
"classifiers": [],
117126
"quality": {},
118-
"accessRights": {"1": {"execute_access": True, "write_access": False}},
127+
"accessRights": {"1": {"execute": True, "write": False}},
119128
"key": "simcore/services/comp/itis/sleeper",
120129
"version": "2.2.1",
121130
"version_display": "2 Xtreme",
@@ -204,15 +213,6 @@ class Config:
204213
}
205214

206215

207-
class ServiceGroupAccessRightsV2(BaseModel):
208-
execute: bool = False
209-
write: bool = False
210-
211-
class Config:
212-
alias_generator = snake_to_camel
213-
allow_population_by_field_name = True
214-
215-
216216
class ServiceGetV2(BaseModel):
217217
key: ServiceKey
218218
version: ServiceVersion
@@ -291,10 +291,10 @@ class Config:
291291
],
292292
},
293293
{
294-
**_EXAMPLE_FILEPICKER,
294+
**_EXAMPLE_FILEPICKER_V2,
295295
"history": [
296296
{
297-
"version": _EXAMPLE_FILEPICKER["version"],
297+
"version": _EXAMPLE_FILEPICKER_V2["version"],
298298
"version_display": "Odei Release",
299299
"released": "2025-03-25T00:00:00",
300300
}
@@ -310,3 +310,28 @@ class Config:
310310
]
311311

312312
ServiceResourcesGet: TypeAlias = ServiceResourcesDict
313+
314+
315+
class ServiceUpdateV2(BaseModel):
316+
name: str | None = None
317+
thumbnail: HttpUrl | None = None
318+
319+
description: str | None = None
320+
version_display: str | None = None
321+
322+
deprecated: datetime | None = None
323+
324+
classifiers: list[str] | None = None
325+
quality: dict[str, Any] = {}
326+
327+
access_rights: dict[GroupID, ServiceGroupAccessRightsV2] | None = None
328+
329+
class Config:
330+
extra = Extra.forbid
331+
alias_generator = snake_to_camel
332+
allow_population_by_field_name = True
333+
334+
335+
assert set(ServiceUpdateV2.__fields__.keys()) - set( # nosec
336+
ServiceGetV2.__fields__.keys()
337+
) == {"deprecated"}

ā€Žpackages/models-library/src/models_library/api_schemas_webserver/catalog.pyā€Ž

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,6 @@ class Config(OutputSchema.Config):
263263
}
264264

265265

266-
class CatalogServiceUpdate(api_schemas_catalog_services.ServiceUpdate):
266+
class CatalogServiceUpdate(api_schemas_catalog_services.ServiceUpdateV2):
267267
class Config(InputSchema.Config):
268268
...

ā€Žpackages/models-library/src/models_library/services_access.pyā€Ž

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
33
"""
44

5-
6-
from pydantic import BaseModel, Field
5+
from pydantic import BaseModel, Extra, Field
76

87
from .users import GroupID
8+
from .utils.change_case import snake_to_camel
99

1010

1111
class ServiceGroupAccessRights(BaseModel):
@@ -18,6 +18,16 @@ class ServiceGroupAccessRights(BaseModel):
1818
)
1919

2020

21+
class ServiceGroupAccessRightsV2(BaseModel):
22+
execute: bool = False
23+
write: bool = False
24+
25+
class Config:
26+
alias_generator = snake_to_camel
27+
allow_population_by_field_name = True
28+
extra = Extra.forbid
29+
30+
2131
class ServiceAccessRights(BaseModel):
2232
access_rights: dict[GroupID, ServiceGroupAccessRights] | None = Field(
2333
None,

ā€Žpackages/service-library/src/servicelib/rabbitmq/rpc_interfaces/catalog/services.pyā€Ž

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from typing import Any, cast
77

88
from models_library.api_schemas_catalog import CATALOG_RPC_NAMESPACE
9-
from models_library.api_schemas_catalog.services import ServiceGetV2, ServiceUpdate
9+
from models_library.api_schemas_catalog.services import ServiceGetV2, ServiceUpdateV2
1010
from models_library.products import ProductName
1111
from models_library.rabbitmq_basic_types import RPCMethodName
1212
from models_library.rpc_pagination import (
@@ -115,7 +115,7 @@ async def update_service(
115115
user_id: UserID,
116116
service_key: ServiceKey,
117117
service_version: ServiceVersion,
118-
update: ServiceUpdate,
118+
update: ServiceUpdateV2,
119119
) -> ServiceGetV2:
120120
"""Updates editable fields of a service
121121
@@ -131,7 +131,7 @@ async def _call(
131131
user_id: UserID,
132132
service_key: ServiceKey,
133133
service_version: ServiceVersion,
134-
update: ServiceUpdate,
134+
update: ServiceUpdateV2,
135135
):
136136
return await rpc_client.request(
137137
CATALOG_RPC_NAMESPACE,

ā€Žservices/catalog/openapi.jsonā€Ž

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2079,7 +2079,7 @@
20792079
"type": "string",
20802080
"format": "date-time",
20812081
"title": "Deprecated",
2082-
"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 marked as dprecated;If now>=deprecated, the service is retired"
2082+
"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 marked as deprecated;If now>=deprecated, the service is retired"
20832083
},
20842084
"classifiers": {
20852085
"items": {
@@ -2558,7 +2558,7 @@
25582558
"type": "string",
25592559
"format": "date-time",
25602560
"title": "Deprecated",
2561-
"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 marked as dprecated;If now>=deprecated, the service is retired"
2561+
"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 marked as deprecated;If now>=deprecated, the service is retired"
25622562
},
25632563
"classifiers": {
25642564
"items": {

ā€Žservices/catalog/src/simcore_service_catalog/api/rpc/_services.pyā€Ž

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from models_library.api_schemas_catalog.services import (
77
PageRpcServicesGetV2,
88
ServiceGetV2,
9-
ServiceUpdate,
9+
ServiceUpdateV2,
1010
)
1111
from models_library.products import ProductName
1212
from models_library.rpc_pagination import DEFAULT_NUMBER_OF_ITEMS_PER_PAGE, PageLimitInt
@@ -124,7 +124,7 @@ async def update_service(
124124
user_id: UserID,
125125
service_key: ServiceKey,
126126
service_version: ServiceVersion,
127-
update: ServiceUpdate,
127+
update: ServiceUpdateV2,
128128
) -> ServiceGetV2:
129129
"""Updates editable fields of a service"""
130130

ā€Žservices/catalog/src/simcore_service_catalog/services/services_api.pyā€Ž

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
11
import logging
22

3-
from models_library.api_schemas_catalog.services import (
4-
ServiceGetV2,
5-
ServiceGroupAccessRightsV2,
6-
ServiceUpdate,
7-
)
3+
from models_library.api_schemas_catalog.services import ServiceGetV2, ServiceUpdateV2
84
from models_library.emails import LowerCaseEmailStr
95
from models_library.products import ProductName
106
from models_library.rest_pagination import PageLimitInt
7+
from models_library.services_access import ServiceGroupAccessRightsV2
118
from models_library.services_enums import ServiceType
129
from models_library.services_history import Compatibility, ServiceRelease
1310
from models_library.services_metadata_published import ServiceMetaDataPublished
@@ -219,7 +216,7 @@ async def update_service(
219216
user_id: UserID,
220217
service_key: ServiceKey,
221218
service_version: ServiceVersion,
222-
update: ServiceUpdate,
219+
update: ServiceUpdateV2,
223220
) -> ServiceGetV2:
224221

225222
if is_function_service(service_key):
@@ -273,8 +270,8 @@ async def update_service(
273270
key=service_key,
274271
version=service_version,
275272
gid=gid,
276-
execute_access=rights.execute_access,
277-
write_access=rights.write_access,
273+
execute_access=rights.execute,
274+
write_access=rights.write,
278275
product_name=product_name,
279276
)
280277
for gid, rights in update.access_rights.items()

ā€Žservices/web/server/VERSIONā€Ž

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.40.5
1+
0.41.0

ā€Žservices/web/server/setup.cfgā€Ž

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[bumpversion]
2-
current_version = 0.40.4
2+
current_version = 0.41.0
33
commit = True
44
message = services/webserver api version: {current_version} → {new_version}
55
tag = False
@@ -12,13 +12,13 @@ commit_args = --no-verify
1212
[tool:pytest]
1313
addopts = --strict-markers
1414
asyncio_mode = auto
15-
markers =
15+
markers =
1616
slow: marks tests as slow (deselect with '-m "not slow"')
1717
acceptance_test: "marks tests as 'acceptance tests' i.e. does the system do what the user expects? Typically those are workflows."
1818
testit: "marks test to run during development"
1919
heavy_load: "mark tests that require large amount of data"
2020

2121
[mypy]
22-
plugins =
22+
plugins =
2323
pydantic.mypy
2424
sqlalchemy.ext.mypy.plugin

ā€Žservices/web/server/src/simcore_service_webserver/api/v0/openapi.yamlā€Ž

Lines changed: 5 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ openapi: 3.0.2
22
info:
33
title: simcore-service-webserver
44
description: Main service with an interface (http-API & websockets) to the web front-end
5-
version: 0.40.5
5+
version: 0.41.0
66
servers:
77
- url: ''
88
description: webserver
@@ -6070,12 +6070,6 @@ components:
60706070
title: CatalogServiceUpdate
60716071
type: object
60726072
properties:
6073-
accessRights:
6074-
title: Accessrights
6075-
type: object
6076-
additionalProperties:
6077-
$ref: '#/components/schemas/ServiceGroupAccessRights'
6078-
description: service access rights per group id
60796073
name:
60806074
title: Name
60816075
type: string
@@ -6094,9 +6088,6 @@ components:
60946088
deprecated:
60956089
title: Deprecated
60966090
type: string
6097-
description: Owner can set the date to retire the service. Three possibilities:If
6098-
None, the service is marked as `published`;If now<deprecated the service
6099-
is marked as deprecated;If now>=deprecated, the service is retired
61006091
format: date-time
61016092
classifiers:
61026093
title: Classifiers
@@ -6107,63 +6098,11 @@ components:
61076098
title: Quality
61086099
type: object
61096100
default: {}
6110-
example:
61116101
accessRights:
6112-
1:
6113-
execute_access: false
6114-
write_access: false
6115-
2:
6116-
execute_access: true
6117-
write_access: true
6118-
44:
6119-
execute_access: false
6120-
write_access: false
6121-
name: My Human Readable Service Name
6122-
description: An interesting service that does something
6123-
classifiers:
6124-
- RRID:SCR_018997
6125-
- RRID:SCR_019001
6126-
quality:
6127-
tsr:
6128-
r01:
6129-
level: 3
6130-
references: ''
6131-
r02:
6132-
level: 2
6133-
references: ''
6134-
r03:
6135-
level: 0
6136-
references: ''
6137-
r04:
6138-
level: 0
6139-
references: ''
6140-
r05:
6141-
level: 2
6142-
references: ''
6143-
r06:
6144-
level: 0
6145-
references: ''
6146-
r07:
6147-
level: 0
6148-
references: ''
6149-
r08:
6150-
level: 1
6151-
references: ''
6152-
r09:
6153-
level: 0
6154-
references: ''
6155-
r10:
6156-
level: 0
6157-
references: ''
6158-
enabled: true
6159-
annotations:
6160-
vandv: ''
6161-
purpose: ''
6162-
standards: ''
6163-
limitations: ''
6164-
documentation: ''
6165-
certificationLink: ''
6166-
certificationStatus: Uncertified
6102+
title: Accessrights
6103+
type: object
6104+
additionalProperties:
6105+
$ref: '#/components/schemas/ServiceGroupAccessRightsV2'
61676106
ChangePasswordBody:
61686107
title: ChangePasswordBody
61696108
required:

0 commit comments

Comments
Ā (0)