Coverage for pepdbagent/models.py: 98%
178 statements
« prev ^ index » next coverage.py v7.16.2, created at 2026-10-01 22:07 +0000
« prev ^ index » next coverage.py v7.16.2, created at 2026-10-01 22:07 +0000
1# file with pydantic models
2import datetime
4from peprs.const import CONFIG_KEY, SAMPLE_RAW_DICT_KEY, SUBSAMPLE_RAW_DICT_KEY
5from pydantic import BaseModel, ConfigDict, Field, field_validator
7from pepdbagent.const import DEFAULT_TAG
10class ProjectDict(BaseModel):
11 """
12 Project dict (raw) model
13 """
15 config: dict = Field(alias=CONFIG_KEY)
16 subsample_list: list | None = Field(alias=SUBSAMPLE_RAW_DICT_KEY)
17 sample_dict: list = Field(alias=SAMPLE_RAW_DICT_KEY)
19 model_config = ConfigDict(populate_by_name=True, extra="forbid")
22class AnnotationModel(BaseModel):
23 """
24 Project Annotation model. All meta metadata
25 """
27 namespace: str | None = None
28 name: str | None = None
29 tag: str | None = None
30 is_private: bool | None = None
31 number_of_samples: int | None = None
32 description: str | None = None
33 last_update_date: str | None = None
34 submission_date: str | None = None
35 digest: str | None = None
36 pep_schema: str | None = None
37 pop: bool | None = False
38 stars_number: int | None = 0
39 forked_from: str | None = None
41 model_config = ConfigDict(
42 validate_assignment=True,
43 populate_by_name=True,
44 )
46 @field_validator("is_private")
47 def is_private_should_be_bool(cls, v) -> bool:
48 if not isinstance(v, bool):
49 return False
50 else:
51 return v
54class PaginationResult(BaseModel):
55 page: int = 0
56 page_size: int = 10
57 total: int
60class AnnotationList(BaseModel):
61 """
62 Annotation return model.
63 """
65 count: int
66 limit: int
67 offset: int
68 results: list[AnnotationModel | None]
71class Namespace(BaseModel):
72 """
73 Model of single namespace search result
74 """
76 namespace: str
77 number_of_projects: int
78 number_of_samples: int
81class NamespaceList(BaseModel):
82 """
83 Model of combined namespace search results
84 """
86 count: int
87 limit: int
88 offset: int
89 results: list[Namespace]
92class UpdateItems(BaseModel):
93 """
94 Model used for updating individual items in db
95 """
97 name: str | None = None
98 description: str | None = None
99 tag: str | None = None
100 is_private: bool | None = None
101 pep_schema: str | None = None
102 digest: str | None = None
103 config: dict | None = None
104 samples: list[dict] | None = None
105 subsamples: list[list[dict]] | None = None
106 pop: bool | None = None
107 schema_id: int | None = None
109 model_config = ConfigDict(
110 arbitrary_types_allowed=True,
111 extra="forbid",
112 )
114 @property
115 def number_of_samples(self) -> int | None:
116 if self.samples:
117 return len(self.samples)
118 return None
121class UpdateModel(BaseModel):
122 """
123 !! is Used only by pepdbagent. Don't use it outside
124 Model used for updating individual items and creating sql string in the code
125 """
127 config: dict | None = None
128 name: str | None = None
129 tag: str | None = None
130 private: bool | None = Field(alias="is_private", default=None)
131 digest: str | None = None
132 number_of_samples: int | None = None
133 pep_schema: str | None = None
134 description: str | None = ""
135 # last_update_date: datetime.datetime | None = datetime.datetime.now(datetime.timezone.utc)
136 pop: bool | None = False
138 @field_validator("tag", "name")
139 def value_must_not_be_empty(cls, v) -> str | None:
140 if "" == v:
141 return None
142 return v
144 @field_validator("tag", "name")
145 def value_must_be_lowercase(cls, v) -> str | None:
146 if v:
147 return v.lower()
148 return v
150 @field_validator("tag", "name")
151 def value_should_not_contain_question(cls, v) -> str:
152 if "?" in v:
153 return ValueError("Question mark (?) is prohibited in name and tag.")
154 return v
156 model_config = ConfigDict(populate_by_name=True, extra="forbid")
159class NamespaceInfo(BaseModel):
160 """
161 Model with information about namespace
162 """
164 namespace_name: str
165 contact_url: str | None = None
166 number_of_projects: int
167 number_of_schemas: int
170class ListOfNamespaceInfo(BaseModel):
171 """
172 Namespace information response model
173 """
175 pagination: PaginationResult
176 results: list[NamespaceInfo]
179class ProjectRegistryPath(BaseModel):
180 """
181 Project Namespace
182 """
184 namespace: str
185 name: str
186 tag: str = DEFAULT_TAG
189class ViewAnnotation(BaseModel):
190 """
191 Project views model
192 """
194 name: str
195 description: str | None = None
196 number_of_samples: int = 0
199class ProjectViews(BaseModel):
200 """
201 View annotation model
202 """
204 namespace: str
205 name: str
206 tag: str = DEFAULT_TAG
207 views: list[ViewAnnotation] = []
210class CreateViewDictModel(BaseModel):
211 """
212 View creation dict model
213 """
215 project_namespace: str
216 project_name: str
217 project_tag: str
218 sample_list: list[str]
221class RegistryPath(BaseModel):
222 namespace: str
223 name: str
224 tag: str | None = "default"
227class NamespaceStats(BaseModel):
228 """
229 Namespace stats model
230 """
232 namespace: str | None = None
233 projects_updated: dict[str, int] | None = None
234 projects_created: dict[str, int] | None = None
237class HistoryChangeModel(BaseModel):
238 """
239 Model for history change
240 """
242 change_id: int
243 change_date: datetime.datetime
244 user: str
247class HistoryAnnotationModel(BaseModel):
248 """
249 History annotation model
250 """
252 namespace: str
253 name: str
254 tag: str = DEFAULT_TAG
255 history: list[HistoryChangeModel]
258class SchemaVersionAnnotation(BaseModel):
259 """
260 Schema version annotation model
261 """
263 namespace: str
264 schema_name: str
265 version: str
266 contributors: str | None = ""
267 release_notes: str | None = ""
268 tags: dict[str, str | None] = {}
269 release_date: datetime.datetime
270 last_update_date: datetime.datetime
273class SchemaRecordAnnotation(BaseModel):
274 """
275 Schema annotation model
276 """
278 namespace: str
279 schema_name: str
280 description: str | None = ""
281 maintainers: str | None = ""
282 lifecycle_stage: str | None = ""
283 latest_released_version: str | None = None
284 private: bool | None = False
285 last_update_date: datetime.datetime
288class SchemaSearchResult(BaseModel):
289 """
290 Schema search result model
291 """
293 pagination: PaginationResult
294 results: list[SchemaRecordAnnotation]
297class SchemaVersionSearchResult(BaseModel):
298 """
299 Schema version search result model
300 """
302 pagination: PaginationResult
303 results: list[SchemaVersionAnnotation]
306class UpdateSchemaRecordFields(BaseModel):
307 maintainers: str | None = None
308 lifecycle_stage: str | None = None
309 private: bool | None = False
310 name: str | None = None
311 description: str | None = None
314class UpdateSchemaVersionFields(BaseModel):
315 contributors: str | None = None
316 schema_value: dict | None = None
317 release_notes: str | None = None
320class TarNamespaceModel(BaseModel):
321 """
322 Namespace archive model
323 """
325 identifier: int | None = None
326 namespace: str
327 file_path: str
328 creation_date: datetime.datetime | None = None
329 number_of_projects: int = 0
330 file_size: int = 0
333class TarNamespaceModelReturn(BaseModel):
334 """
335 Namespace archive search model
336 """
338 count: int
339 results: list[TarNamespaceModel]