Skip to content

Commit f994227

Browse files
authored
Retrieve more states (backend) (#2107)
* compute modified state and dependencies * moved ComputationTask model to models-library * modified project json schema * bugfix: issue webserver wrongly retrieves templates running state, creating log pollution #2108 * removed thumbnail as str in Project * bugfix: downgrading the projects table now works * fix node hashes after import based on original hash * moved ProjectAtDB to the models_library * fix model to use python snake case * @pcrespov bonus: sidecar says which mode it uses in the logo * migration of workbench according to new state object * small fixes to export/import (ensure new eTag are generated, ensure new runHash are generated if needed) * silence logs. sometimes exceptions from requesting are expected and set as a warning
1 parent 40f981f commit f994227

File tree

46 files changed

+2045
-855
lines changed

Some content is hidden

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

46 files changed

+2045
-855
lines changed

api/specs/common/schemas/project-v0.0.1-converted.yaml

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -286,20 +286,42 @@ properties:
286286
- '15'
287287
deprecated: true
288288
state:
289-
title: RunningState
290-
description: the node's running state
291-
default: NOT_STARTED
292-
enum:
293-
- UNKNOWN
294-
- NOT_STARTED
295-
- PUBLISHED
296-
- PENDING
297-
- STARTED
298-
- RETRY
299-
- SUCCESS
300-
- FAILED
301-
- ABORTED
302-
type: string
289+
title: NodeState
290+
type: object
291+
properties:
292+
modified:
293+
title: Modified
294+
description: true if the node's outputs need to be re-computed
295+
default: true
296+
type: boolean
297+
dependencies:
298+
title: Dependencies
299+
description: >-
300+
contains the node inputs dependencies if they need to be
301+
computed first
302+
type: array
303+
uniqueItems: true
304+
items:
305+
type: string
306+
format: uuid
307+
currentStatus:
308+
description: the node's current state
309+
default: NOT_STARTED
310+
example:
311+
- RUNNING
312+
- FAILED
313+
enum:
314+
- UNKNOWN
315+
- PUBLISHED
316+
- NOT_STARTED
317+
- PENDING
318+
- STARTED
319+
- RETRY
320+
- SUCCESS
321+
- FAILED
322+
- ABORTED
323+
type: string
324+
additionalProperties: false
303325
additionalProperties: true
304326
ui:
305327
type: object

api/specs/common/schemas/project-v0.0.1.json

Lines changed: 41 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -397,21 +397,47 @@
397397
"deprecated": true
398398
},
399399
"state": {
400-
"title": "RunningState",
401-
"description": "the node's running state",
402-
"default": "NOT_STARTED",
403-
"enum": [
404-
"UNKNOWN",
405-
"NOT_STARTED",
406-
"PUBLISHED",
407-
"PENDING",
408-
"STARTED",
409-
"RETRY",
410-
"SUCCESS",
411-
"FAILED",
412-
"ABORTED"
413-
],
414-
"type": "string"
400+
"title": "NodeState",
401+
"type": "object",
402+
"properties": {
403+
"modified": {
404+
"title": "Modified",
405+
"description": "true if the node's outputs need to be re-computed",
406+
"default": true,
407+
"type": "boolean"
408+
},
409+
"dependencies": {
410+
"title": "Dependencies",
411+
"description": "contains the node inputs dependencies if they need to be computed first",
412+
"type": "array",
413+
"uniqueItems": true,
414+
"items": {
415+
"type": "string",
416+
"format": "uuid"
417+
}
418+
},
419+
"currentStatus": {
420+
"description": "the node's current state",
421+
"default": "NOT_STARTED",
422+
"examples": [
423+
"RUNNING",
424+
"FAILED"
425+
],
426+
"enum": [
427+
"UNKNOWN",
428+
"PUBLISHED",
429+
"NOT_STARTED",
430+
"PENDING",
431+
"STARTED",
432+
"RETRY",
433+
"SUCCESS",
434+
"FAILED",
435+
"ABORTED"
436+
],
437+
"type": "string"
438+
}
439+
},
440+
"additionalProperties": false
415441
}
416442
}
417443
}

packages/models-library/requirements/ci.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
# installs this repo's packages
1414
../pytest-simcore/
15+
../postgres-database/
1516

1617
# current module
1718
.

packages/models-library/requirements/dev.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
# installs this repo's packages
1515
-e ../pytest-simcore/
16+
-e ../postgres-database/[migration]
1617

1718
# current module
1819
-e .

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

Lines changed: 66 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
Models a study's project document
33
"""
44
from copy import deepcopy
5-
from typing import Any, Dict, List, Optional, Union
5+
from datetime import datetime
6+
from enum import Enum
7+
from typing import Any, Dict, List, Optional
68
from uuid import UUID
79

810
from pydantic import BaseModel, EmailStr, Extra, Field, HttpUrl, validator
@@ -21,7 +23,19 @@
2123
Workbench = Dict[NodeID_AsDictKey, Node]
2224

2325

24-
class Project(BaseModel):
26+
# NOTE: careful this is in sync with packages/postgres-database/src/simcore_postgres_database/models/projects.py!!!
27+
class ProjectType(str, Enum):
28+
"""
29+
template: template project
30+
standard: standard project
31+
"""
32+
33+
TEMPLATE = "TEMPLATE"
34+
STANDARD = "STANDARD"
35+
36+
37+
class ProjectCommons(BaseModel):
38+
# Description of the project
2539
uuid: ProjectID = Field(
2640
...,
2741
description="project unique identifier",
@@ -30,8 +44,6 @@ class Project(BaseModel):
3044
"9bcf8feb-c1b1-41b6-b201-639cd6ccdba8",
3145
],
3246
)
33-
34-
# Description of the project
3547
name: str = Field(
3648
..., description="project name", examples=["Temporal Distortion Simulator"]
3749
)
@@ -40,33 +52,73 @@ class Project(BaseModel):
4052
description="longer one-line description about the project",
4153
examples=["Dabbling in temporal transitions ..."],
4254
)
43-
# NOTE: str is necessary because HttpUrl will not accept and empty string and the
44-
# frontend sometimes sends this empty string, which is removed by the validator
45-
thumbnail: Union[str, HttpUrl] = Field(
55+
thumbnail: Optional[HttpUrl] = Field(
4656
...,
4757
description="url of the project thumbnail",
4858
examples=["https://placeimg.com/171/96/tech/grayscale/?0.jpg"],
4959
)
5060

51-
# Ownership and Access (SEE projects_access.py)
52-
prjOwner: EmailStr = Field(..., description="user email")
53-
accessRights: Dict[GroupID, AccessRights] = Field(
54-
...,
55-
description="object containing the GroupID as key and read/write/execution permissions as value",
61+
creation_date: datetime = Field(...)
62+
last_change_date: datetime = Field(...)
63+
64+
# Pipeline of nodes (SEE projects_nodes.py)
65+
workbench: Workbench = Field(...)
66+
67+
@validator("thumbnail", always=True, pre=True)
68+
@classmethod
69+
def convert_empty_str_to_none(v):
70+
if isinstance(v, str) and v == "":
71+
return None
72+
return v
73+
74+
75+
class ProjectAtDB(ProjectCommons):
76+
# specific DB fields
77+
id: int = Field(..., description="The table primary index")
78+
project_type: ProjectType = Field(..., alias="type", description="The project type")
79+
prj_owner: Optional[int] = Field(..., description="The project owner id")
80+
published: Optional[bool] = Field(
81+
False, description="Defines if a study is available publicly"
5682
)
5783

84+
@validator("project_type", pre=True)
85+
@classmethod
86+
def convert_sql_alchemy_enum(cls, v):
87+
if isinstance(v, Enum):
88+
return v.value
89+
return v
90+
91+
class Config:
92+
orm_mode = True
93+
use_enum_values = True
94+
95+
96+
class Project(ProjectCommons):
97+
# NOTE: This is the pydantic pendant of project-v0.0.1.json used in the API of the webserver/webclient
98+
# NOT for usage with DB!!
99+
100+
# Ownership and Access (SEE projects_access.py)
101+
prj_owner: EmailStr = Field(..., description="user email", alias="prjOwner")
102+
58103
# Timestamps TODO: should we use datetime??
59-
creationDate: str = Field(
104+
creation_date: str = Field(
60105
...,
61106
regex=DATE_RE,
62107
description="project creation date",
63108
examples=["2018-07-01T11:13:43Z"],
109+
alias="creationDate",
64110
)
65-
lastChangeDate: str = Field(
111+
last_change_date: str = Field(
66112
...,
67113
regex=DATE_RE,
68114
description="last save date",
69115
examples=["2018-07-01T11:13:43Z"],
116+
alias="lastChangeDate",
117+
)
118+
access_rights: Dict[GroupID, AccessRights] = Field(
119+
...,
120+
description="object containing the GroupID as key and read/write/execution permissions as value",
121+
alias="accessRights",
70122
)
71123

72124
# Classification
@@ -77,9 +129,6 @@ class Project(BaseModel):
77129
examples=["some:id:to:a:classifier"],
78130
)
79131

80-
# Pipeline of nodes (SEE projects_nodes.py)
81-
workbench: Workbench = ...
82-
83132
# Project state (SEE projects_state.py)
84133
state: Optional[ProjectState] = None
85134

@@ -94,13 +143,6 @@ class Project(BaseModel):
94143
# Dev only
95144
dev: Optional[Dict] = Field(description="object used for development purposes only")
96145

97-
@classmethod
98-
@validator("thumbnail")
99-
def null_thumbnail(cls, v):
100-
if isinstance(v, str) and v == "":
101-
return None
102-
return v
103-
104146
class Config:
105147
description = "Document that stores metadata, pipeline and UI setup of a study"
106148
title = "osparc-simcore project"

0 commit comments

Comments
 (0)