2020from .projects_nodes import Node
2121from .projects_nodes_io import NodeIDStr
2222from .projects_state import ProjectState
23- from .projects_ui import StudyUI
2423from .users import UserID
2524from .utils .common_validators import (
2625 empty_str_to_none_pre_validator ,
@@ -54,33 +53,41 @@ class ProjectType(str, Enum):
5453
5554class 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):
95102class 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
@@ -122,76 +132,87 @@ class Project(BaseProjectModel):
122132 # NOT for usage with DB!!
123133
124134 # Ownership and Access (SEE projects_access.py)
125- prj_owner : LowerCaseEmailStr = Field (
126- ..., description = "user email" , alias = "prjOwner"
127- )
128-
129- # Timestamps
130- creation_date : DateTimeStr = Field ( # type: ignore[assignment]
131- ...,
132- description = "project creation date" ,
133- examples = ["2018-07-01T11:13:43Z" ],
134- alias = "creationDate" ,
135- )
136- last_change_date : DateTimeStr = Field ( # type: ignore[assignment]
137- ...,
138- description = "last save date" ,
139- examples = ["2018-07-01T11:13:43Z" ],
140- alias = "lastChangeDate" ,
141- )
142- access_rights : dict [GroupIDStr , AccessRights ] = Field (
143- ...,
144- description = "object containing the GroupID as key and read/write/execution permissions as value" ,
145- alias = "accessRights" ,
146- )
135+ prj_owner : Annotated [
136+ LowerCaseEmailStr , Field (description = "user email" , alias = "prjOwner" )
137+ ]
138+ access_rights : Annotated [
139+ dict [GroupIDStr , AccessRights ],
140+ Field (
141+ description = "object containing the GroupID as key and read/write/execution permissions as value" ,
142+ alias = "accessRights" ,
143+ ),
144+ ]
147145
148- # Classification
149- tags : list [int ] | None = []
150- classifiers : Annotated [
151- list [ClassifierID ] | None ,
146+ # Lifecycle
147+ creation_date : Annotated [ # type: ignore[assignment]
148+ DateTimeStr ,
152149 Field (
153- default_factory = list ,
154- description = "Contains the reference to the project classifiers" ,
155- examples = [ "some:id:to:a:classifier" ] ,
150+ description = "project creation date" ,
151+ examples = [ "2018-07-01T11:13:43Z" ] ,
152+ alias = "creationDate" ,
156153 ),
157- ] = DEFAULT_FACTORY
154+ ]
155+ last_change_date : Annotated [ # type: ignore[assignment]
156+ DateTimeStr ,
157+ Field (
158+ description = "last save date" ,
159+ examples = ["2018-07-01T11:13:43Z" ],
160+ alias = "lastChangeDate" ,
161+ ),
162+ ]
158163
159164 # Project state (SEE projects_state.py)
160165 state : ProjectState | None = None
161166
162- # UI front-end setup (SEE projects_ui.py)
163- ui : StudyUI | None = None
164-
165- # Quality
166- quality : dict [str , Any ] = Field (
167- default_factory = dict ,
168- description = "stores the study quality assessment" ,
169- )
167+ # UI front-end fields (SEE projects_ui.py)
168+ ui : dict [str , Any ] | None = None
169+ dev : dict [str , Any ] | None = None
170170
171- # Dev only
172- dev : dict | None = Field (
173- default = None , description = "object used for development purposes only"
174- )
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
175179
176- workspace_id : WorkspaceID | None = Field (
177- default = None ,
178- description = "To which workspace project belongs. If None, belongs to private user workspace." ,
179- alias = "workspaceId" ,
180- )
181- folder_id : FolderID | None = Field (
182- default = None ,
183- description = "To which folder project belongs. If None, belongs to root folder." ,
184- alias = "folderId" ,
185- )
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
186187
188+ # trash state
187189 trashed : datetime | None = None
188190 trashed_by : Annotated [UserID | None , Field (alias = "trashedBy" )] = None
189191 trashed_by_primary_gid : Annotated [
190192 GroupID | None , Field (alias = "trashedByPrimaryGid" )
191193 ] = None
192194 trashed_explicitly : Annotated [bool , Field (alias = "trashedExplicitly" )] = False
193195
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+
194214 model_config = ConfigDict (
195215 # NOTE: this is a security measure until we get rid of the ProjectDict variants
196216 extra = "forbid" ,
217+ populate_by_name = True ,
197218 )
0 commit comments