Skip to content

Commit ab0a810

Browse files
fix: projects states handlers
1 parent 30b2b7f commit ab0a810

File tree

4 files changed

+62
-28
lines changed

4 files changed

+62
-28
lines changed

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

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
from ..resource_manager.registry import get_registry
3131
from ..resource_manager.service import list_opened_project_ids
3232
from ..socketio._utils import get_socket_server
33-
from . import _projects_repository
33+
from . import _projects_nodes_repository, _projects_repository
3434

3535
_logger = logging.getLogger(__name__)
3636

@@ -64,26 +64,29 @@ async def _create_project_document_and_increment_version() -> (
6464
- the project document and its version must be kept in sync
6565
"""
6666
# Get the full project with workbench for document creation
67-
project_with_workbench = await _projects_repository.get_project_with_workbench(
67+
project = await _projects_repository.get_project(
6868
app=app, project_uuid=project_uuid
6969
)
70+
project_nodes = await _projects_nodes_repository.get_by_project(
71+
app=app, project_id=project_uuid
72+
)
73+
workbench = {f"{node_id}": node for node_id, node in project_nodes}
74+
7075
# Create project document
7176
project_document = ProjectDocument(
72-
uuid=project_with_workbench.uuid,
73-
workspace_id=project_with_workbench.workspace_id,
74-
name=project_with_workbench.name,
75-
description=project_with_workbench.description,
76-
thumbnail=project_with_workbench.thumbnail,
77-
last_change_date=project_with_workbench.last_change_date,
78-
classifiers=project_with_workbench.classifiers,
79-
dev=project_with_workbench.dev,
80-
quality=project_with_workbench.quality,
81-
workbench=project_with_workbench.workbench,
82-
ui=project_with_workbench.ui,
83-
type=cast(ProjectTypeAPI, project_with_workbench.type),
84-
template_type=cast(
85-
ProjectTemplateType, project_with_workbench.template_type
86-
),
77+
uuid=project.uuid,
78+
workspace_id=project.workspace_id,
79+
name=project.name,
80+
description=project.description,
81+
thumbnail=project.thumbnail,
82+
last_change_date=project.last_change_date,
83+
classifiers=project.classifiers,
84+
dev=project.dev,
85+
quality=project.quality,
86+
workbench=workbench,
87+
ui=project.ui,
88+
type=cast(ProjectTypeAPI, project.type),
89+
template_type=cast(ProjectTemplateType, project.template_type),
8790
)
8891
# Increment document version
8992
redis_client_sdk = get_redis_document_manager_client_sdk(app)

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

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -122,9 +122,7 @@ async def get_project_with_workbench(
122122
project_uuid: ProjectID,
123123
) -> ProjectWithWorkbenchDBGet:
124124
async with pass_or_acquire_connection(get_asyncpg_engine(app), connection) as conn:
125-
query = sql.select(*PROJECT_DB_COLS, projects.c.workbench).where(
126-
projects.c.uuid == f"{project_uuid}"
127-
)
125+
query = sql.select(*PROJECT_DB_COLS).where(projects.c.uuid == f"{project_uuid}")
128126
result = await conn.execute(query)
129127
row = result.one_or_none()
130128
if row is None:

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

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ def _reraise_if_not_unique_uuid_error(err: UniqueViolation):
177177
with attempt:
178178
async with conn.begin():
179179
project_index = None
180-
project_uuid = ProjectID(f"{insert_values['uuid']}")
180+
project_uuid = ProjectID(insert_values["uuid"])
181181

182182
try:
183183
result: ResultProxy = await conn.execute(
@@ -296,12 +296,22 @@ async def insert_project(
296296

297297
# must be valid uuid
298298
try:
299-
ProjectID(str(insert_values.get("uuid")))
299+
ProjectID(f"{insert_values.get('uuid')}")
300300
except ValueError:
301301
if force_project_uuid:
302302
raise
303303
insert_values["uuid"] = f"{uuid1()}"
304304

305+
# extract workbench nodes
306+
workbench: dict[str, Any] = insert_values.pop("workbench", {})
307+
project_nodes = project_nodes or {}
308+
project_nodes |= {
309+
NodeID(node_id): ProjectNodeCreate(
310+
node_id=NodeID(node_id), **project_workbench_node
311+
)
312+
for node_id, project_workbench_node in workbench.items()
313+
}
314+
305315
inserted_project = await self._insert_project_in_db(
306316
insert_values,
307317
force_project_uuid=force_project_uuid,
@@ -310,6 +320,8 @@ async def insert_project(
310320
project_nodes=project_nodes,
311321
)
312322

323+
inserted_project["workbench"] = workbench
324+
313325
async with self.engine.acquire() as conn:
314326
# Returns created project with names as in the project schema
315327
user_email = await self._get_user_email(conn, user_id)
@@ -365,7 +377,6 @@ def _create_private_workspace_query(
365377
private_workspace_query = (
366378
sa.select(
367379
*PROJECT_DB_COLS,
368-
projects.c.workbench,
369380
projects_to_products.c.product_name,
370381
projects_to_folders.c.folder_id,
371382
)
@@ -648,8 +659,11 @@ async def list_projects_dicts( # pylint: disable=too-many-arguments,too-many-st
648659
# Therefore, if we use this model, it will return those default values, which is not backward-compatible
649660
# with the frontend. The frontend would need to check and adapt how it handles default values in
650661
# Workbench nodes, which are currently not returned if not set in the DB.
651-
ProjectListAtDB.model_validate(row)
652-
prjs_output.append(dict(row.items()))
662+
prj_dict = dict(row.items()) | {
663+
"workbench": await self._get_workbench(conn, row.uuid),
664+
}
665+
ProjectListAtDB.model_validate(prj_dict)
666+
prjs_output.append(prj_dict)
653667

654668
return (
655669
prjs_output,
@@ -847,7 +861,7 @@ async def update_project_node_data(
847861
extra=get_log_record_extra(user_id=user_id),
848862
):
849863
partial_workbench_data: dict[NodeIDStr, Any] = {
850-
NodeIDStr(f"{node_id}"): new_node_data,
864+
f"{node_id}": new_node_data,
851865
}
852866
return await self._update_project_workbench_with_lock_and_notify(
853867
partial_workbench_data,
@@ -1021,7 +1035,7 @@ async def add_project_node(
10211035
) -> None:
10221036
# NOTE: permission check is done currently in update_project_workbench!
10231037
partial_workbench_data: dict[NodeIDStr, Any] = {
1024-
NodeIDStr(f"{node.node_id}"): jsonable_encoder(
1038+
f"{node.node_id}": jsonable_encoder(
10251039
old_struct_node,
10261040
exclude_unset=True,
10271041
),

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

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
from simcore_postgres_database.webserver_models import (
2222
projects,
2323
)
24+
from simcore_service_webserver.projects._nodes_repository import ProjectNodesRepo
2425
from sqlalchemy.dialects.postgresql import insert as pg_insert
2526

2627
from ..db.models import GroupType, groups, projects_tags, user_to_groups, users
@@ -32,7 +33,7 @@
3233
ProjectInvalidUsageError,
3334
ProjectNotFoundError,
3435
)
35-
from .models import ProjectDict
36+
from .models import NodesDict, ProjectDict
3637
from .utils import find_changed_node_keys
3738

3839
logger = logging.getLogger(__name__)
@@ -187,6 +188,23 @@ async def _upsert_tags_in_project(
187188
.on_conflict_do_nothing()
188189
)
189190

191+
async def _get_workbench(
192+
self,
193+
connection: SAConnection,
194+
project_uuid: str,
195+
) -> NodesDict:
196+
project_nodes_repo = ProjectNodesRepo(project_uuid=ProjectID(project_uuid))
197+
exclude_fields = {"node_id", "required_resources", "created", "modified"}
198+
workbench: NodesDict = {}
199+
200+
project_nodes = await project_nodes_repo.list(connection)
201+
for project_node in project_nodes:
202+
node_data = project_node.model_dump(
203+
exclude=exclude_fields, exclude_none=True, exclude_unset=True
204+
)
205+
workbench[f"{project_node.node_id}"] = Node.model_validate(node_data)
206+
return workbench
207+
190208
async def _get_project(
191209
self,
192210
connection: SAConnection,
@@ -263,6 +281,7 @@ async def _get_project(
263281
)
264282

265283
project: dict[str, Any] = dict(project_row.items())
284+
project["workbench"] = await self._get_workbench(connection, project_uuid)
266285

267286
if "tags" not in exclude_foreign:
268287
tags = await self._get_tags_by_project(

0 commit comments

Comments
 (0)