Skip to content

Commit 034d607

Browse files
committed
refactor
1 parent da3be5f commit 034d607

File tree

1 file changed

+104
-89
lines changed

1 file changed

+104
-89
lines changed

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

Lines changed: 104 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
from models_library.folders import FolderID
1313
from models_library.workspaces import WorkspaceID
1414
from pydantic import BaseModel, ConfigDict, Field, HttpUrl, field_validator
15-
from typing_extensions import TypedDict
1615

1716
from .basic_regex import DATE_RE, UUID_RE_BASE
1817
from .emails import LowerCaseEmailStr
@@ -54,33 +53,41 @@ class ProjectType(str, Enum):
5453

5554
class BaseProjectModel(BaseModel):
5655
# Description of the project
57-
uuid: ProjectID = Field(
58-
...,
59-
description="project unique identifier",
60-
examples=[
61-
"07640335-a91f-468c-ab69-a374fa82078d",
62-
"9bcf8feb-c1b1-41b6-b201-639cd6ccdba8",
63-
],
64-
)
65-
name: str = Field(
66-
..., description="project name", examples=["Temporal Distortion Simulator"]
67-
)
68-
description: str = Field(
69-
...,
70-
description="longer one-line description about the project",
71-
examples=["Dabbling in temporal transitions ..."],
72-
)
73-
thumbnail: HttpUrl | None = Field(
74-
...,
75-
description="url of the project thumbnail",
76-
examples=["https://placeimg.com/171/96/tech/grayscale/?0.jpg"],
77-
)
56+
uuid: Annotated[
57+
ProjectID,
58+
Field(
59+
description="project unique identifier",
60+
examples=[
61+
"07640335-a91f-468c-ab69-a374fa82078d",
62+
"9bcf8feb-c1b1-41b6-b201-639cd6ccdba8",
63+
],
64+
),
65+
]
66+
67+
name: Annotated[
68+
str,
69+
Field(description="project name", examples=["Temporal Distortion Simulator"]),
70+
]
71+
description: Annotated[
72+
str,
73+
Field(
74+
description="longer one-line description about the project",
75+
examples=["Dabbling in temporal transitions ..."],
76+
),
77+
]
78+
thumbnail: Annotated[
79+
HttpUrl | None,
80+
Field(
81+
description="url of the project thumbnail",
82+
examples=["https://placeimg.com/171/96/tech/grayscale/?0.jpg"],
83+
),
84+
]
7885

79-
creation_date: datetime = Field(...)
80-
last_change_date: datetime = Field(...)
86+
creation_date: datetime
87+
last_change_date: datetime
8188

8289
# Pipeline of nodes (SEE projects_nodes.py)
83-
workbench: Annotated[NodesDict, Field(..., description="Project's pipeline")]
90+
workbench: Annotated[NodesDict, Field(description="Project's pipeline")]
8491

8592
# validators
8693
_empty_thumbnail_is_none = field_validator("thumbnail", mode="before")(
@@ -95,15 +102,18 @@ class BaseProjectModel(BaseModel):
95102
class ProjectAtDB(BaseProjectModel):
96103
# Model used to READ from database
97104

98-
id: int = Field(..., description="The table primary index")
105+
id: Annotated[int, Field(description="The table primary index")]
99106

100-
project_type: ProjectType = Field(..., alias="type", description="The project type")
107+
project_type: Annotated[
108+
ProjectType, Field(alias="type", description="The project type")
109+
]
101110

102-
prj_owner: int | None = Field(..., description="The project owner id")
111+
prj_owner: Annotated[int | None, Field(description="The project owner id")]
103112

104-
published: bool | None = Field(
105-
default=False, description="Defines if a study is available publicly"
106-
)
113+
published: Annotated[
114+
bool | None,
115+
Field(default=False, description="Defines if a study is available publicly"),
116+
]
107117

108118
@field_validator("project_type", mode="before")
109119
@classmethod
@@ -117,85 +127,90 @@ def _convert_sql_alchemy_enum(cls, v):
117127
)
118128

119129

120-
class StudyUIDict(TypedDict, total=False):
121-
icon: HttpUrl | None
122-
workbench: dict[str, Any]
123-
124-
125130
class Project(BaseProjectModel):
126131
# NOTE: This is the pydantic pendant of project-v0.0.1.json used in the API of the webserver/webclient
127132
# NOT for usage with DB!!
128133

129134
# Ownership and Access (SEE projects_access.py)
130-
prj_owner: LowerCaseEmailStr = Field(
131-
..., description="user email", alias="prjOwner"
132-
)
133-
134-
# Timestamps
135-
creation_date: DateTimeStr = Field( # type: ignore[assignment]
136-
...,
137-
description="project creation date",
138-
examples=["2018-07-01T11:13:43Z"],
139-
alias="creationDate",
140-
)
141-
last_change_date: DateTimeStr = Field( # type: ignore[assignment]
142-
...,
143-
description="last save date",
144-
examples=["2018-07-01T11:13:43Z"],
145-
alias="lastChangeDate",
146-
)
147-
access_rights: dict[GroupIDStr, AccessRights] = Field(
148-
...,
149-
description="object containing the GroupID as key and read/write/execution permissions as value",
150-
alias="accessRights",
151-
)
152-
153-
# Classification
154-
tags: list[int] | None = []
155-
classifiers: Annotated[
156-
list[ClassifierID] | None,
135+
prj_owner: Annotated[
136+
LowerCaseEmailStr, Field(description="user email", alias="prjOwner")
137+
]
138+
access_rights: Annotated[
139+
dict[GroupIDStr, AccessRights],
157140
Field(
158-
default_factory=list,
159-
description="Contains the reference to the project classifiers",
160-
examples=["some:id:to:a:classifier"],
141+
description="object containing the GroupID as key and read/write/execution permissions as value",
142+
alias="accessRights",
161143
),
162-
] = DEFAULT_FACTORY
144+
]
145+
146+
# Lifecycle
147+
creation_date: Annotated[
148+
DateTimeStr,
149+
Field( # type: ignore[assignment]
150+
description="project creation date",
151+
examples=["2018-07-01T11:13:43Z"],
152+
alias="creationDate",
153+
),
154+
]
155+
last_change_date: Annotated[
156+
DateTimeStr,
157+
Field( # type: ignore[assignment]
158+
description="last save date",
159+
examples=["2018-07-01T11:13:43Z"],
160+
alias="lastChangeDate",
161+
),
162+
]
163163

164164
# Project state (SEE projects_state.py)
165165
state: ProjectState | None = None
166166

167-
# UI front-end setup (SEE projects_ui.py)
168-
ui: StudyUIDict | None = None
169-
170-
# Quality
171-
quality: dict[str, Any] = Field(
172-
default_factory=dict,
173-
description="stores the study quality assessment",
174-
)
167+
# UI front-end fields (SEE projects_ui.py)
168+
ui: dict[str, Any] | None = None
169+
dev: dict[str, Any] | None = None
175170

176-
# Dev only
177-
dev: dict | None = Field(
178-
default=None, description="object used for development purposes only"
179-
)
171+
# Parenthood
172+
workspace_id: Annotated[
173+
WorkspaceID | None,
174+
Field(
175+
description="To which workspace project belongs. If None, belongs to private user workspace.",
176+
alias="workspaceId",
177+
),
178+
] = None
180179

181-
workspace_id: WorkspaceID | None = Field(
182-
default=None,
183-
description="To which workspace project belongs. If None, belongs to private user workspace.",
184-
alias="workspaceId",
185-
)
186-
folder_id: FolderID | None = Field(
187-
default=None,
188-
description="To which folder project belongs. If None, belongs to root folder.",
189-
alias="folderId",
190-
)
180+
folder_id: Annotated[
181+
FolderID | None,
182+
Field(
183+
description="To which folder project belongs. If None, belongs to root folder.",
184+
alias="folderId",
185+
),
186+
] = None
191187

188+
# trash state
192189
trashed: datetime | None = None
193190
trashed_by: Annotated[UserID | None, Field(alias="trashedBy")] = None
194191
trashed_by_primary_gid: Annotated[
195192
GroupID | None, Field(alias="trashedByPrimaryGid")
196193
] = None
197194
trashed_explicitly: Annotated[bool, Field(alias="trashedExplicitly")] = False
198195

196+
# Labeling
197+
tags: Annotated[list[int] | None, Field(default_factory=list)] = DEFAULT_FACTORY
198+
classifiers: Annotated[
199+
list[ClassifierID] | None,
200+
Field(
201+
default_factory=list,
202+
description="Contains the reference to the project classifiers",
203+
examples=["some:id:to:a:classifier"],
204+
),
205+
] = DEFAULT_FACTORY
206+
quality: Annotated[
207+
dict[str, Any],
208+
Field(
209+
default_factory=dict,
210+
description="stores the study quality assessment",
211+
),
212+
] = DEFAULT_FACTORY
213+
199214
model_config = ConfigDict(
200215
# NOTE: this is a security measure until we get rid of the ProjectDict variants
201216
extra="forbid",

0 commit comments

Comments
 (0)