Skip to content

Commit 89a9394

Browse files
review @pcrespov
1 parent 0d5a6c3 commit 89a9394

File tree

8 files changed

+48
-30
lines changed

8 files changed

+48
-30
lines changed

services/web/server/src/simcore_service_webserver/folders/_workspaces_repository.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from simcore_postgres_database.utils_repos import transaction_context
99

1010
from ..db.plugin import get_asyncpg_engine
11+
from ..models import ClientSessionID
1112
from ..projects import _folders_repository as projects_folders_repository
1213
from ..projects import _groups_repository as projects_groups_repository
1314
from ..projects._access_rights_service import check_user_project_permission
@@ -26,7 +27,7 @@ async def move_folder_into_workspace(
2627
folder_id: FolderID,
2728
workspace_id: WorkspaceID | None,
2829
product_name: ProductName,
29-
client_session_id: str | None = None,
30+
client_session_id: ClientSessionID | None = None,
3031
) -> None:
3132
# 1. User needs to have delete permission on source folder
3233
folder_db = await _folders_repository.get(

services/web/server/src/simcore_service_webserver/models.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from models_library.products import ProductName
44
from models_library.rest_base import RequestParameters
55
from models_library.users import UserID
6-
from pydantic import ConfigDict, Field
6+
from pydantic import ConfigDict, Field, StringConstraints
77
from pydantic_extra_types.phone_numbers import PhoneNumberValidator
88
from servicelib.request_keys import RQT_USERID_KEY
99
from servicelib.rest_constants import X_CLIENT_SESSION_ID_HEADER
@@ -17,6 +17,18 @@
1717
]
1818

1919

20+
ClientSessionID: TypeAlias = Annotated[
21+
str,
22+
StringConstraints(
23+
strip_whitespace=True,
24+
min_length=36,
25+
max_length=36,
26+
pattern=r"^[0-9a-fA-F\-]{36}$", # UUID format
27+
strict=True,
28+
),
29+
]
30+
31+
2032
class AuthenticatedRequestContext(RequestParameters):
2133
"""Fields expected in the request context for authenticated endpoints"""
2234

@@ -31,10 +43,10 @@ class AuthenticatedRequestContext(RequestParameters):
3143
class ClientSessionHeaderParams(RequestParameters):
3244
"""Header parameters for client session tracking in collaborative features."""
3345

34-
client_session_id: str | None = Field(
46+
client_session_id: ClientSessionID | None = Field(
3547
default=None,
3648
alias=X_CLIENT_SESSION_ID_HEADER,
37-
description="Client session identifier for collaborative features",
49+
description="Client session identifier for collaborative features (UUID string)",
3850
)
3951

4052
model_config = ConfigDict(

services/web/server/src/simcore_service_webserver/projects/_project_document_utils.py renamed to services/web/server/src/simcore_service_webserver/projects/_project_document_service.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
from . import _projects_repository
2626

2727

28-
async def build_project_document_and_increment_version(
28+
async def create_project_document_and_increment_version(
2929
app: web.Application, project_uuid: ProjectID
3030
) -> tuple[ProjectDocument, ProjectDocumentVersion]:
3131
"""Build project document and increment version with Redis lock protection.
@@ -47,7 +47,7 @@ async def build_project_document_and_increment_version(
4747
blocking=True,
4848
blocking_timeout=None, # NOTE: this is a blocking call, a timeout has undefined effects
4949
)
50-
async def _build_project_document_and_increment_version() -> (
50+
async def _create_project_document_and_increment_version() -> (
5151
tuple[ProjectDocument, int]
5252
):
5353
"""This function is protected because
@@ -83,4 +83,4 @@ async def _build_project_document_and_increment_version() -> (
8383

8484
return project_document, document_version
8585

86-
return await _build_project_document_and_increment_version()
86+
return await _create_project_document_and_increment_version()

services/web/server/src/simcore_service_webserver/projects/_projects_repository_legacy.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
from tenacity.asyncio import AsyncRetrying
7676
from tenacity.retry import retry_if_exception_type
7777

78+
from ..models import ClientSessionID
7879
from ..utils import now_str
7980
from ._comments_repository import (
8081
create_project_comment,
@@ -84,7 +85,7 @@
8485
total_project_comments,
8586
update_project_comment,
8687
)
87-
from ._project_document_utils import build_project_document_and_increment_version
88+
from ._project_document_service import create_project_document_and_increment_version
8889
from ._projects_repository import PROJECT_DB_COLS
8990
from ._projects_repository_legacy_utils import (
9091
ANY_USER_ID_SENTINEL,
@@ -870,7 +871,7 @@ async def update_project_node_data(
870871
node_id: NodeID,
871872
product_name: str | None,
872873
new_node_data: dict[str, Any],
873-
client_session_id: str | None,
874+
client_session_id: ClientSessionID | None,
874875
) -> tuple[ProjectDict, dict[NodeIDStr, Any]]:
875876
with log_context(
876877
_logger,
@@ -897,7 +898,7 @@ async def update_project_multiple_node_data(
897898
project_uuid: ProjectID,
898899
product_name: str | None,
899900
partial_workbench_data: dict[NodeIDStr, dict[str, Any]],
900-
client_session_id: str | None,
901+
client_session_id: ClientSessionID | None,
901902
) -> tuple[ProjectDict, dict[NodeIDStr, Any]]:
902903
"""
903904
Raises:
@@ -926,7 +927,7 @@ async def _update_project_workbench_with_lock_and_notify(
926927
project_uuid: ProjectID,
927928
product_name: str | None = None,
928929
allow_workbench_changes: bool,
929-
client_session_id: str | None,
930+
client_session_id: ClientSessionID | None,
930931
) -> tuple[ProjectDict, dict[NodeIDStr, Any]]:
931932
"""
932933
Updates project workbench with Redis lock and user notification.
@@ -959,7 +960,7 @@ async def _update_project_workbench_with_lock_and_notify(
959960
(
960961
project_document,
961962
document_version,
962-
) = await build_project_document_and_increment_version(self._app, project_uuid)
963+
) = await create_project_document_and_increment_version(self._app, project_uuid)
963964

964965
await notify_project_document_updated(
965966
app=self._app,
@@ -1049,7 +1050,7 @@ async def add_project_node(
10491050
node: ProjectNodeCreate,
10501051
old_struct_node: Node,
10511052
product_name: str,
1052-
client_session_id: str | None,
1053+
client_session_id: ClientSessionID | None,
10531054
) -> None:
10541055
# NOTE: permission check is done currently in update_project_workbench!
10551056
partial_workbench_data: dict[NodeIDStr, Any] = {
@@ -1075,7 +1076,7 @@ async def remove_project_node(
10751076
user_id: UserID,
10761077
project_id: ProjectID,
10771078
node_id: NodeID,
1078-
client_session_id: str | None,
1079+
client_session_id: ClientSessionID | None,
10791080
) -> None:
10801081
# NOTE: permission check is done currently in update_project_workbench!
10811082
partial_workbench_data: dict[NodeIDStr, Any] = {

services/web/server/src/simcore_service_webserver/projects/_projects_service.py

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@
101101
from ..catalog import catalog_service
102102
from ..director_v2 import director_v2_service
103103
from ..dynamic_scheduler import api as dynamic_scheduler_service
104+
from ..models import ClientSessionID
104105
from ..products import products_web
105106
from ..rabbitmq import get_rabbitmq_rpc_client
106107
from ..redis import get_redis_lock_manager_client_sdk
@@ -139,7 +140,7 @@
139140
has_user_project_access_rights,
140141
)
141142
from ._nodes_utils import set_reservation_same_as_limit, validate_new_service_resources
142-
from ._project_document_utils import build_project_document_and_increment_version
143+
from ._project_document_service import create_project_document_and_increment_version
143144
from ._projects_repository_legacy import APP_PROJECT_DBAPI, ProjectDBAPI
144145
from ._projects_repository_legacy_utils import PermissionStr
145146
from ._socketio_service import notify_project_document_updated
@@ -174,7 +175,7 @@ async def patch_project_and_notify_users(
174175
project_uuid: ProjectID,
175176
patch_project_data: dict[str, Any],
176177
user_primary_gid: GroupID,
177-
client_session_id: str | None,
178+
client_session_id: ClientSessionID | None,
178179
) -> None:
179180
"""
180181
Patches a project and notifies users involved in the project with version control.
@@ -204,7 +205,7 @@ async def patch_project_and_notify_users(
204205
)
205206

206207
project_document, document_version = (
207-
await build_project_document_and_increment_version(app, project_uuid)
208+
await create_project_document_and_increment_version(app, project_uuid)
208209
)
209210
await notify_project_document_updated(
210211
app=app,
@@ -357,7 +358,7 @@ async def patch_project_for_user(
357358
project_uuid: ProjectID,
358359
project_patch: ProjectPatch | ProjectPatchInternalExtended,
359360
product_name: ProductName,
360-
client_session_id: str | None,
361+
client_session_id: ClientSessionID | None,
361362
):
362363
# client_session_id (str | None): The session ID of the frontend client making the request.
363364
# This is used to distinguish between multiple sessions a user may have open.
@@ -911,7 +912,7 @@ async def add_project_node(
911912
service_key: ServiceKey,
912913
service_version: ServiceVersion,
913914
service_id: str | None,
914-
client_session_id: str | None,
915+
client_session_id: ClientSessionID | None,
915916
) -> NodeID:
916917
_logger.debug(
917918
"starting node %s:%s in project %s for user %s",
@@ -1048,7 +1049,7 @@ async def delete_project_node(
10481049
node_uuid: NodeIDStr,
10491050
product_name: ProductName,
10501051
product_api_base_url: str,
1051-
client_session_id: str | None,
1052+
client_session_id: ClientSessionID | None,
10521053
) -> None:
10531054
_logger.debug(
10541055
"deleting node %s in project %s for user %s", node_uuid, project_uuid, user_id
@@ -1119,7 +1120,7 @@ async def update_project_node_state(
11191120
project_id: ProjectID,
11201121
node_id: NodeID,
11211122
new_state: str,
1122-
client_session_id: str | None,
1123+
client_session_id: ClientSessionID | None,
11231124
) -> dict:
11241125
_logger.debug(
11251126
"updating node %s current state in project %s for user %s",
@@ -1176,7 +1177,7 @@ async def patch_project_node(
11761177
project_id: ProjectID,
11771178
node_id: NodeID,
11781179
partial_node: PartialNode,
1179-
client_session_id: str | None,
1180+
client_session_id: ClientSessionID | None,
11801181
) -> None:
11811182
_node_patch_exclude_unset: dict[str, Any] = partial_node.model_dump(
11821183
mode="json", exclude_unset=True, by_alias=True
@@ -1264,7 +1265,7 @@ async def update_project_node_outputs(
12641265
node_id: NodeID,
12651266
new_outputs: dict | None,
12661267
new_run_hash: str | None,
1267-
client_session_id: str | None,
1268+
client_session_id: ClientSessionID | None,
12681269
) -> tuple[dict, list[str]]:
12691270
"""
12701271
Updates outputs of a given node in a project with 'data'
@@ -1453,7 +1454,7 @@ async def _leave_project_room(
14531454
*,
14541455
app: web.Application,
14551456
user_id: UserID,
1456-
client_session_id: str,
1457+
client_session_id: ClientSessionID,
14571458
project_uuid: ProjectID,
14581459
user_session,
14591460
) -> None:
@@ -1490,7 +1491,7 @@ async def _notification_cb() -> None:
14901491
async def try_open_project_for_user(
14911492
user_id: UserID,
14921493
project_uuid: ProjectID,
1493-
client_session_id: str,
1494+
client_session_id: ClientSessionID,
14941495
app: web.Application,
14951496
*,
14961497
max_number_of_opened_projects_per_user: int | None,
@@ -1596,7 +1597,7 @@ async def _open_project() -> bool:
15961597
async def close_project_for_user(
15971598
user_id: UserID,
15981599
project_uuid: ProjectID,
1599-
client_session_id: str,
1600+
client_session_id: ClientSessionID,
16001601
app: web.Application,
16011602
simcore_user_agent: str,
16021603
*,

services/web/server/src/simcore_service_webserver/projects/_socketio_service.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from pydantic import AliasGenerator, BaseModel, ConfigDict
99
from pydantic.alias_generators import to_camel
1010

11+
from ..models import ClientSessionID
1112
from ..socketio.messages import send_message_to_project_room
1213

1314
SOCKET_IO_PROJECT_DOCUMENT_UPDATED_EVENT: Final[str] = "projectDocument:updated"
@@ -26,7 +27,7 @@ class BaseEvent(BaseModel):
2627
class ProjectDocumentEvent(BaseEvent):
2728
project_id: ProjectID
2829
user_primary_gid: GroupID
29-
client_session_id: str | None
30+
client_session_id: ClientSessionID | None
3031
version: int
3132
document: ProjectDocument
3233

@@ -36,7 +37,7 @@ async def notify_project_document_updated(
3637
*,
3738
project_id: ProjectID,
3839
user_primary_gid: GroupID,
39-
client_session_id: str | None,
40+
client_session_id: ClientSessionID | None,
4041
version: int,
4142
document: ProjectDocument,
4243
) -> None:

services/web/server/src/simcore_service_webserver/projects/_workspaces_service.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from simcore_postgres_database.utils_repos import transaction_context
99

1010
from ..db.plugin import get_asyncpg_engine
11+
from ..models import ClientSessionID
1112
from ..users import users_service
1213
from ..workspaces.api import check_user_workspace_access
1314
from . import _folders_repository, _groups_repository, _projects_service
@@ -24,7 +25,7 @@ async def move_project_into_workspace(
2425
project_id: ProjectID,
2526
workspace_id: WorkspaceID | None,
2627
product_name: ProductName,
27-
client_session_id: str | None = None,
28+
client_session_id: ClientSessionID | None = None,
2829
) -> None:
2930
# 1. User needs to have delete permission on project
3031
project_access_rights = await get_user_project_access_rights(

services/web/server/src/simcore_service_webserver/projects/nodes_utils.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from servicelib.logging_utils import log_decorator
1010
from servicelib.utils import logged_gather
1111

12+
from ..models import ClientSessionID
1213
from . import _projects_service
1314

1415
log = logging.getLogger(__name__)
@@ -38,7 +39,7 @@ async def update_node_outputs(
3839
outputs: dict,
3940
run_hash: str | None,
4041
node_errors: list[ErrorDict] | None,
41-
client_session_id: str | None,
42+
client_session_id: ClientSessionID | None,
4243
*,
4344
ui_changed_keys: set[str] | None,
4445
) -> None:

0 commit comments

Comments
 (0)