Skip to content

Commit a9c4d54

Browse files
authored
♻️ web-server: preparation of trash plugin ⚠️ (#7018)
1 parent 79d19bf commit a9c4d54

File tree

94 files changed

+900
-561
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

94 files changed

+900
-561
lines changed

.env-devel

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,6 @@ LOGIN_ACCOUNT_DELETION_RETENTION_DAYS=31
334334
LOGIN_REGISTRATION_CONFIRMATION_REQUIRED=0
335335
LOGIN_REGISTRATION_INVITATION_REQUIRED=0
336336
PROJECTS_INACTIVITY_INTERVAL=00:00:20
337-
PROJECTS_TRASH_RETENTION_DAYS=7
338337
PROJECTS_MAX_COPY_SIZE_BYTES=30Gib
339338
PROJECTS_MAX_NUM_RUNNING_DYNAMIC_NODES=5
340339
REST_SWAGGER_API_DOC_ENABLED=1
@@ -353,6 +352,7 @@ TRACING_OPENTELEMETRY_COLLECTOR_EXPORTER_ENDPOINT=http://jaeger:4318
353352
TRACING_OPENTELEMETRY_COLLECTOR_PORT=4318
354353
TRACING_OPENTELEMETRY_COLLECTOR_SAMPLING_PERCENTAGE=100
355354
TRAEFIK_SIMCORE_ZONE=internal_simcore_stack
355+
TRASH_RETENTION_DAYS=7
356356
TWILIO_ACCOUNT_SID=DUMMY
357357
TWILIO_AUTH_TOKEN=DUMMY
358358
TWILIO_COUNTRY_CODES_W_ALPHANUMERIC_SID_SUPPORT=["41"]

api/specs/web-server/_folders.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,14 @@
1919
from models_library.generics import Envelope
2020
from models_library.rest_error import EnvelopedError
2121
from simcore_service_webserver._meta import API_VTAG
22-
from simcore_service_webserver.folders._exceptions_handlers import _TO_HTTP_ERROR_MAP
23-
from simcore_service_webserver.folders._models import (
22+
from simcore_service_webserver.folders._common.exceptions_handlers import (
23+
_TO_HTTP_ERROR_MAP,
24+
)
25+
from simcore_service_webserver.folders._common.models import (
2426
FolderSearchQueryParams,
2527
FoldersListQueryParams,
2628
FoldersPathParams,
27-
)
28-
from simcore_service_webserver.folders._workspaces_handlers import (
29-
_FolderWorkspacesPathParams,
29+
FolderWorkspacesPathParams,
3030
)
3131

3232
router = APIRouter(
@@ -109,6 +109,6 @@ async def delete_folder(
109109
tags=["workspaces"],
110110
)
111111
async def move_folder_to_workspace(
112-
_path: Annotated[_FolderWorkspacesPathParams, Depends()],
112+
_path: Annotated[FolderWorkspacesPathParams, Depends()],
113113
):
114114
...

api/specs/web-server/_trash.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@
1010
from fastapi import APIRouter, Depends, status
1111
from models_library.trash import RemoveQueryParams
1212
from simcore_service_webserver._meta import API_VTAG
13-
from simcore_service_webserver.folders._models import (
13+
from simcore_service_webserver.folders._common.models import (
1414
FoldersPathParams,
1515
FolderTrashQueryParams,
1616
)
17-
from simcore_service_webserver.projects._trash_handlers import ProjectPathParams
18-
from simcore_service_webserver.workspaces._models import (
17+
from simcore_service_webserver.projects._trash_rest import ProjectPathParams
18+
from simcore_service_webserver.workspaces._common.models import (
1919
WorkspacesPathParams,
2020
WorkspaceTrashQueryParams,
2121
)

api/specs/web-server/_workspaces.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,16 @@
1919
from models_library.generics import Envelope
2020
from models_library.rest_error import EnvelopedError
2121
from simcore_service_webserver._meta import API_VTAG
22-
from simcore_service_webserver.folders._exceptions_handlers import _TO_HTTP_ERROR_MAP
23-
from simcore_service_webserver.workspaces._groups_api import WorkspaceGroupGet
24-
from simcore_service_webserver.workspaces._models import (
22+
from simcore_service_webserver.folders._common.exceptions_handlers import (
23+
_TO_HTTP_ERROR_MAP,
24+
)
25+
from simcore_service_webserver.workspaces._common.models import (
2526
WorkspacesGroupsBodyParams,
2627
WorkspacesGroupsPathParams,
2728
WorkspacesListQueryParams,
2829
WorkspacesPathParams,
2930
)
31+
from simcore_service_webserver.workspaces._groups_service import WorkspaceGroupGet
3032

3133
router = APIRouter(
3234
prefix=f"/{API_VTAG}",

packages/common-library/src/common_library/exclude.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ class UnSet:
88
UnSet.VALUE = UnSet()
99

1010

11+
def is_unset(v: Any) -> bool:
12+
return isinstance(v, UnSet)
13+
14+
1115
def as_dict_exclude_unset(**params) -> dict[str, Any]:
1216
return {k: v for k, v in params.items() if not isinstance(v, UnSet)}
1317

packages/models-library/src/models_library/api_schemas_webserver/folders.py

Lines changed: 0 additions & 48 deletions
This file was deleted.

packages/models-library/src/models_library/api_schemas_webserver/groups.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ class GroupGet(OutputSchema):
7373
] = DEFAULT_FACTORY
7474

7575
@classmethod
76-
def from_model(cls, group: Group, access_rights: AccessRightsDict) -> Self:
76+
def from_domain_model(cls, group: Group, access_rights: AccessRightsDict) -> Self:
7777
# Adapts these domain models into this schema
7878
return cls.model_validate(
7979
{
@@ -151,7 +151,7 @@ class GroupCreate(InputSchema):
151151
description: str
152152
thumbnail: AnyUrl | None = None
153153

154-
def to_model(self) -> StandardGroupCreate:
154+
def to_domain_model(self) -> StandardGroupCreate:
155155
data = remap_keys(
156156
self.model_dump(
157157
mode="json",
@@ -169,7 +169,7 @@ class GroupUpdate(InputSchema):
169169
description: str | None = None
170170
thumbnail: AnyUrl | None = None
171171

172-
def to_model(self) -> StandardGroupUpdate:
172+
def to_domain_model(self) -> StandardGroupUpdate:
173173
data = remap_keys(
174174
self.model_dump(
175175
mode="json",
@@ -230,7 +230,7 @@ class MyGroupsGet(OutputSchema):
230230
)
231231

232232
@classmethod
233-
def from_model(
233+
def from_domain_model(
234234
cls,
235235
groups_by_type: GroupsByTypeTuple,
236236
my_product_group: tuple[Group, AccessRightsDict] | None,
@@ -239,10 +239,12 @@ def from_model(
239239
assert groups_by_type.everyone # nosec
240240

241241
return cls(
242-
me=GroupGet.from_model(*groups_by_type.primary),
243-
organizations=[GroupGet.from_model(*gi) for gi in groups_by_type.standard],
244-
all=GroupGet.from_model(*groups_by_type.everyone),
245-
product=GroupGet.from_model(*my_product_group)
242+
me=GroupGet.from_domain_model(*groups_by_type.primary),
243+
organizations=[
244+
GroupGet.from_domain_model(*gi) for gi in groups_by_type.standard
245+
],
246+
all=GroupGet.from_domain_model(*groups_by_type.everyone),
247+
product=GroupGet.from_domain_model(*my_product_group)
246248
if my_product_group
247249
else None,
248250
)
@@ -320,7 +322,7 @@ class GroupUserGet(OutputSchemaWithoutCamelCase):
320322
)
321323

322324
@classmethod
323-
def from_model(cls, user: GroupMember) -> Self:
325+
def from_domain_model(cls, user: GroupMember) -> Self:
324326
return cls.model_validate(
325327
{
326328
"id": user.id,

packages/models-library/src/models_library/api_schemas_webserver/projects.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@
66
"""
77

88
from datetime import datetime
9-
from typing import Annotated, Any, Literal, TypeAlias
9+
from typing import Annotated, Any, Literal, Self, TypeAlias
1010

11+
from common_library.dict_tools import remap_keys
1112
from models_library.folders import FolderID
1213
from models_library.utils._original_fastapi_encoders import jsonable_encoder
1314
from models_library.workspaces import WorkspaceID
@@ -95,6 +96,7 @@ class ProjectGet(OutputSchema):
9596
permalink: ProjectPermalink | None = None
9697
workspace_id: WorkspaceID | None
9798
folder_id: FolderID | None
99+
98100
trashed_at: datetime | None
99101

100102
_empty_description = field_validator("description", mode="before")(
@@ -103,6 +105,15 @@ class ProjectGet(OutputSchema):
103105

104106
model_config = ConfigDict(frozen=False)
105107

108+
@classmethod
109+
def from_domain_model(cls, project_data: dict[str, Any]) -> Self:
110+
return cls.model_validate(
111+
remap_keys(
112+
project_data,
113+
rename={"trashed": "trashed_at"},
114+
)
115+
)
116+
106117

107118
TaskProjectGet: TypeAlias = TaskGet
108119

@@ -160,6 +171,9 @@ class ProjectPatch(InputSchema):
160171
] = Field(default=None)
161172
quality: dict[str, Any] | None = Field(default=None)
162173

174+
def to_domain_model(self) -> dict[str, Any]:
175+
return self.model_dump(exclude_unset=True, by_alias=False)
176+
163177

164178
__all__: tuple[str, ...] = (
165179
"EmptyModel",

packages/models-library/src/models_library/api_schemas_webserver/users.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ def _to_upper_string(cls, v):
108108
return v
109109

110110
@classmethod
111-
def from_model(
111+
def from_domain_model(
112112
cls,
113113
my_profile: MyProfile,
114114
my_groups_by_type: GroupsByTypeTuple,
@@ -133,7 +133,7 @@ def from_model(
133133
)
134134
return cls(
135135
**data,
136-
groups=MyGroupsGet.from_model(my_groups_by_type, my_product_group),
136+
groups=MyGroupsGet.from_domain_model(my_groups_by_type, my_product_group),
137137
preferences=my_preferences,
138138
)
139139

@@ -221,7 +221,7 @@ class UserGet(OutputSchema):
221221
email: EmailStr | None = None
222222

223223
@classmethod
224-
def from_model(cls, data):
224+
def from_domain_model(cls, data):
225225
return cls.model_validate(data, from_attributes=True)
226226

227227

@@ -293,7 +293,7 @@ class MyTokenCreate(InputSchemaWithoutCamelCase):
293293
token_key: IDStr
294294
token_secret: IDStr
295295

296-
def to_model(self) -> UserThirdPartyToken:
296+
def to_domain_model(self) -> UserThirdPartyToken:
297297
return UserThirdPartyToken(
298298
service=self.service,
299299
token_key=self.token_key,
@@ -309,7 +309,7 @@ class MyTokenGet(OutputSchemaWithoutCamelCase):
309309
] = None
310310

311311
@classmethod
312-
def from_model(cls, token: UserThirdPartyToken) -> Self:
312+
def from_domain_model(cls, token: UserThirdPartyToken) -> Self:
313313
return cls(
314314
service=token.service, # type: ignore[arg-type]
315315
token_key=token.token_key, # type: ignore[arg-type]
@@ -327,5 +327,5 @@ class MyPermissionGet(OutputSchema):
327327
allowed: bool
328328

329329
@classmethod
330-
def from_model(cls, permission: UserPermission) -> Self:
330+
def from_domain_model(cls, permission: UserPermission) -> Self:
331331
return cls(name=permission.name, allowed=permission.allowed)

packages/models-library/src/models_library/api_schemas_webserver/workspaces.py

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
from datetime import datetime
2-
from typing import NamedTuple
2+
from typing import Self
33

4-
from models_library.basic_types import IDStr
5-
from models_library.groups import GroupID
6-
from models_library.workspaces import WorkspaceID
7-
from pydantic import ConfigDict, PositiveInt
4+
from pydantic import ConfigDict
85

96
from ..access_rights import AccessRights
7+
from ..basic_types import IDStr
8+
from ..groups import GroupID
109
from ..users import UserID
10+
from ..workspaces import UserWorkspaceWithAccessRights, WorkspaceID
1111
from ._base import InputSchema, OutputSchema
1212

1313

@@ -23,10 +23,20 @@ class WorkspaceGet(OutputSchema):
2323
my_access_rights: AccessRights
2424
access_rights: dict[GroupID, AccessRights]
2525

26-
27-
class WorkspaceGetPage(NamedTuple):
28-
items: list[WorkspaceGet]
29-
total: PositiveInt
26+
@classmethod
27+
def from_domain_model(cls, wks: UserWorkspaceWithAccessRights) -> Self:
28+
return cls(
29+
workspace_id=wks.workspace_id,
30+
name=wks.name,
31+
description=wks.description,
32+
thumbnail=wks.thumbnail,
33+
created_at=wks.created,
34+
modified_at=wks.modified,
35+
trashed_at=wks.trashed,
36+
trashed_by=wks.trashed_by if wks.trashed else None,
37+
my_access_rights=wks.my_access_rights,
38+
access_rights=wks.access_rights,
39+
)
3040

3141

3242
class WorkspaceCreateBodyParams(InputSchema):

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ class FolderDB(BaseModel):
6464
...,
6565
description="Timestamp of last modification",
6666
)
67-
trashed_at: datetime | None = Field(
67+
trashed: datetime | None = Field(
6868
...,
6969
)
7070

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

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
from .projects_nodes_io import NodeIDStr
2121
from .projects_state import ProjectState
2222
from .projects_ui import StudyUI
23+
from .users import UserID
2324
from .utils.common_validators import (
2425
empty_str_to_none_pre_validator,
2526
none_to_empty_str_pre_validator,
@@ -182,10 +183,10 @@ class Project(BaseProjectModel):
182183
alias="folderId",
183184
)
184185

185-
trashed_at: datetime | None = Field(
186-
default=None,
187-
alias="trashedAt",
188-
)
189-
trashed_explicitly: bool = Field(default=False, alias="trashedExplicitly")
186+
trashed: datetime | None = None
187+
trashed_by: Annotated[UserID | None, Field(alias="trashedBy")] = None
188+
trashed_explicitly: Annotated[bool, Field(alias="trashedExplicitly")] = False
190189

191-
model_config = ConfigDict(title="osparc-simcore project", extra="forbid")
190+
model_config = ConfigDict(
191+
extra="forbid",
192+
)

0 commit comments

Comments
 (0)