Skip to content

Commit 00c8cda

Browse files
committed
Cleanup webserver's project_*
1 parent c42e71a commit 00c8cda

File tree

2 files changed

+62
-39
lines changed

2 files changed

+62
-39
lines changed

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

+50-33
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"""
77

88
import logging
9+
import textwrap
910
import uuid as uuidlib
1011
from collections import deque
1112
from datetime import datetime
@@ -170,7 +171,7 @@ async def add_project(
170171
force_project_uuid=False,
171172
force_as_template=False,
172173
) -> Dict:
173-
""" Inserts a new project in the database and, if a user is specified, it assigns ownership
174+
"""Inserts a new project in the database and, if a user is specified, it assigns ownership
174175
175176
- A valid uuid is automaticaly assigned to the project except if force_project_uuid=False. In the latter case,
176177
invalid uuid will raise an exception.
@@ -193,7 +194,10 @@ async def add_project(
193194
# TODO: check best rollback design. see transaction.begin...
194195
# TODO: check if template, otherwise standard (e.g. template- prefix in uuid)
195196
prj.update(
196-
{"creationDate": now_str(), "lastChangeDate": now_str(),}
197+
{
198+
"creationDate": now_str(),
199+
"lastChangeDate": now_str(),
200+
}
197201
)
198202
kargs = _convert_to_db_names(prj)
199203
kargs.update(
@@ -249,13 +253,15 @@ async def load_user_projects(self, user_id: int) -> List[Dict]:
249253
log.info("Loading projects for user %s", user_id)
250254
async with self.engine.acquire() as conn:
251255
user_groups: List[RowProxy] = await self.__load_user_groups(conn, user_id)
252-
query = f"""
253-
SELECT *
254-
FROM projects
255-
WHERE projects.type != 'TEMPLATE'
256-
AND (jsonb_exists_any(projects.access_rights, array[{', '.join(f"'{group.gid}'" for group in user_groups)}])
257-
OR prj_owner = {user_id})
258-
"""
256+
query = textwrap.dedent(
257+
f"""\
258+
SELECT *
259+
FROM projects
260+
WHERE projects.type != 'TEMPLATE'
261+
AND (jsonb_exists_any(projects.access_rights, array[{', '.join(f"'{group.gid}'" for group in user_groups)}])
262+
OR prj_owner = {user_id})
263+
"""
264+
)
259265
projects_list = await self.__load_projects(
260266
conn, query, user_id, user_groups
261267
)
@@ -272,16 +278,20 @@ async def load_template_projects(
272278

273279
async with self.engine.acquire() as conn:
274280
user_groups: List[RowProxy] = await self.__load_user_groups(conn, user_id)
281+
275282
# NOTE: in order to use specific postgresql function jsonb_exists_any we use raw call here
276-
query = f"""
277-
SELECT *
278-
FROM projects
279-
WHERE projects.type = 'TEMPLATE'
280-
{'AND projects.published ' if only_published else ''}
281-
AND (jsonb_exists_any(projects.access_rights, array[{', '.join(f"'{group.gid}'" for group in user_groups)}])
282-
OR prj_owner = {user_id})
283-
"""
283+
query = textwrap.dedent(
284+
f"""\
285+
SELECT *
286+
FROM projects
287+
WHERE projects.type = 'TEMPLATE'
288+
{'AND projects.published ' if only_published else ''}
289+
AND (jsonb_exists_any(projects.access_rights, array[{', '.join(f"'{group.gid}'" for group in user_groups)}])
290+
OR prj_owner = {user_id})
291+
"""
292+
)
284293
db_projects = await self.__load_projects(conn, query, user_id, user_groups)
294+
285295
projects_list.extend(db_projects)
286296

287297
return projects_list
@@ -337,15 +347,17 @@ async def _get_project(
337347
user_groups: List[RowProxy] = await self.__load_user_groups(conn, user_id)
338348

339349
# NOTE: in order to use specific postgresql function jsonb_exists_any we use raw call here
340-
query = f"""
341-
SELECT *
342-
FROM projects
343-
WHERE
344-
{"" if include_templates else "projects.type != 'TEMPLATE' AND"}
345-
uuid = '{project_uuid}'
346-
AND (jsonb_exists_any(projects.access_rights, array[{', '.join(f"'{group.gid}'" for group in user_groups)}])
347-
OR prj_owner = {user_id})
348-
"""
350+
query = textwrap.dedent(
351+
f"""\
352+
SELECT *
353+
FROM projects
354+
WHERE
355+
{"" if include_templates else "projects.type != 'TEMPLATE' AND"}
356+
uuid = '{project_uuid}'
357+
AND (jsonb_exists_any(projects.access_rights, array[{', '.join(f"'{group.gid}'" for group in user_groups)}])
358+
OR prj_owner = {user_id})
359+
"""
360+
)
349361
result = await conn.execute(query)
350362
project_row = await result.first()
351363

@@ -392,7 +404,7 @@ async def remove_tag(self, user_id: int, project_uuid: str, tag_id: int) -> Dict
392404
return _convert_to_schema_names(project, user_email)
393405

394406
async def get_user_project(self, user_id: int, project_uuid: str) -> Dict:
395-
""" Returns all projects *owned* by the user
407+
"""Returns all projects *owned* by the user
396408
397409
- prj_owner
398410
- Notice that a user can have access to a template but he might not onw it
@@ -448,16 +460,21 @@ async def get_template_project(
448460
return template_prj
449461

450462
async def update_user_project(
451-
self, project_data: Dict, user_id: int, project_uuid: str, include_templates: Optional[bool] = False
463+
self,
464+
project_data: Dict,
465+
user_id: int,
466+
project_uuid: str,
467+
include_templates: Optional[bool] = False,
452468
):
453-
""" updates a project from a user
454-
455-
"""
469+
"""updates a project from a user"""
456470
log.info("Updating project %s for user %s", project_uuid, user_id)
457471

458472
async with self.engine.acquire() as conn:
459473
row = await self._get_project(
460-
user_id, project_uuid, exclude_foreign=["tags"], include_templates=include_templates
474+
user_id,
475+
project_uuid,
476+
exclude_foreign=["tags"],
477+
include_templates=include_templates,
461478
)
462479
user_groups: List[RowProxy] = await self.__load_user_groups(conn, user_id)
463480
_check_project_permissions(row, user_id, user_groups, "write")
@@ -505,7 +522,7 @@ async def delete_user_project(self, user_id: int, project_uuid: str):
505522
)
506523

507524
async def make_unique_project_uuid(self) -> str:
508-
""" Generates a project identifier still not used in database
525+
"""Generates a project identifier still not used in database
509526
510527
WARNING: this method does not guarantee always unique id due to possible race condition
511528
(i.e. while client gets this uuid and uses it, another client might have used the same id already)

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

+12-6
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,12 @@ async def list_projects(request: web.Request):
143143
projects_api.validate_project(request.app, project)
144144
validated_projects.append(project)
145145
except ValidationError:
146-
log.exception("Skipping invalid project from list")
146+
log.warning(
147+
"Invalid project with id='%s' in database."
148+
"Skipping project from listed response."
149+
"RECOMMENDED db data diagnose and cleanup",
150+
project.get("uuid", "undefined"),
151+
)
147152
continue
148153

149154
return {"data": validated_projects}
@@ -152,9 +157,7 @@ async def list_projects(request: web.Request):
152157
@login_required
153158
@permission_required("project.read")
154159
async def get_project(request: web.Request):
155-
""" Returns all projects accessible to a user (not necesarly owned)
156-
157-
"""
160+
"""Returns all projects accessible to a user (not necesarly owned)"""
158161
# TODO: temporary hidden until get_handlers_from_namespace refactor to seek marked functions instead!
159162
user_id = request[RQT_USERID_KEY]
160163
from .projects_api import get_project_for_user
@@ -180,7 +183,7 @@ async def get_project(request: web.Request):
180183
@login_required
181184
@permission_required("services.pipeline.*") # due to update_pipeline_db
182185
async def replace_project(request: web.Request):
183-
""" Implements PUT /projects
186+
"""Implements PUT /projects
184187
185188
In a PUT request, the enclosed entity is considered to be a modified version of
186189
the resource stored on the origin server, and the client is requesting that the
@@ -410,7 +413,10 @@ async def state_project(request: web.Request) -> web.Response:
410413

411414
# check that project exists
412415
await get_project_for_user(
413-
request.app, project_uuid=project_uuid, user_id=user_id, include_templates=True,
416+
request.app,
417+
project_uuid=project_uuid,
418+
user_id=user_id,
419+
include_templates=True,
414420
)
415421
with managed_resource(user_id, None, request.app) as rt:
416422
users_of_project = await rt.find_users_of_resource("project_id", project_uuid)

0 commit comments

Comments
 (0)