Skip to content

Commit 55a7d06

Browse files
committed
moved simcore dependent files to services_metadata_runtime.py
1 parent 227bf8b commit 55a7d06

File tree

24 files changed

+270
-236
lines changed

24 files changed

+270
-236
lines changed

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

Lines changed: 1 addition & 200 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,12 @@
1-
import contextlib
21
import re
3-
from typing import Annotated, Any, Final, TypeAlias
2+
from typing import Annotated, TypeAlias
43

54
from pydantic import (
6-
BaseModel,
7-
ByteSize,
8-
ConfigDict,
9-
Field,
105
StringConstraints,
11-
TypeAdapter,
12-
ValidationError,
13-
model_validator,
146
)
157

168
from .basic_regex import DOCKER_GENERIC_TAG_KEY_RE, DOCKER_LABEL_KEY_REGEX
179
from .basic_types import ConstrainedStr
18-
from .generated_models.docker_rest_api import Task
19-
from .products import ProductName
20-
from .projects import ProjectID
21-
from .projects_nodes_io import NodeID
22-
from .users import UserID
2310

2411

2512
class DockerLabelKey(ConstrainedStr):
@@ -47,192 +34,6 @@ def from_key(cls, key: str) -> "DockerLabelKey":
4734
),
4835
]
4936

50-
_SIMCORE_RUNTIME_DOCKER_LABEL_PREFIX: Final[str] = "io.simcore.runtime."
51-
_BACKWARDS_COMPATIBILITY_SIMCORE_RUNTIME_DOCKER_LABELS_MAP: Final[dict[str, str]] = {
52-
"node_id": f"{_SIMCORE_RUNTIME_DOCKER_LABEL_PREFIX}node-id",
53-
"product_name": f"{_SIMCORE_RUNTIME_DOCKER_LABEL_PREFIX}product-name",
54-
"project_id": f"{_SIMCORE_RUNTIME_DOCKER_LABEL_PREFIX}project-id",
55-
"simcore_user_agent": f"{_SIMCORE_RUNTIME_DOCKER_LABEL_PREFIX}simcore-user-agent",
56-
"study_id": f"{_SIMCORE_RUNTIME_DOCKER_LABEL_PREFIX}project-id",
57-
"user_id": f"{_SIMCORE_RUNTIME_DOCKER_LABEL_PREFIX}user-id",
58-
"uuid": f"{_SIMCORE_RUNTIME_DOCKER_LABEL_PREFIX}node-id",
59-
"mem_limit": f"{_SIMCORE_RUNTIME_DOCKER_LABEL_PREFIX}memory-limit",
60-
"swarm_stack_name": f"{_SIMCORE_RUNTIME_DOCKER_LABEL_PREFIX}swarm-stack-name",
61-
}
62-
_UNDEFINED_LABEL_VALUE_STR: Final[str] = "undefined"
63-
_UNDEFINED_LABEL_VALUE_INT: Final[str] = "0"
64-
65-
66-
DOCKER_TASK_EC2_INSTANCE_TYPE_PLACEMENT_CONSTRAINT_KEY: Final[DockerLabelKey] = (
67-
TypeAdapter(DockerLabelKey).validate_python("ec2-instance-type")
68-
)
69-
70-
71-
def to_simcore_runtime_docker_label_key(key: str) -> DockerLabelKey:
72-
return DockerLabelKey(
73-
f"{_SIMCORE_RUNTIME_DOCKER_LABEL_PREFIX}{key.replace('_', '-').lower()}"
74-
)
75-
76-
77-
class StandardSimcoreDockerLabels(BaseModel):
78-
"""
79-
Represents the standard label on oSparc created containers (not yet services)
80-
In order to create this object in code, please use model_construct() method!
81-
"""
82-
83-
user_id: UserID = Field(..., alias=f"{_SIMCORE_RUNTIME_DOCKER_LABEL_PREFIX}user-id") # type: ignore[literal-required]
84-
project_id: ProjectID = Field( # type: ignore[literal-required]
85-
..., alias=f"{_SIMCORE_RUNTIME_DOCKER_LABEL_PREFIX}project-id"
86-
)
87-
node_id: NodeID = Field(..., alias=f"{_SIMCORE_RUNTIME_DOCKER_LABEL_PREFIX}node-id") # type: ignore[literal-required]
88-
89-
product_name: ProductName = Field( # type: ignore[literal-required]
90-
..., alias=f"{_SIMCORE_RUNTIME_DOCKER_LABEL_PREFIX}product-name"
91-
)
92-
simcore_user_agent: str = Field( # type: ignore[literal-required]
93-
..., alias=f"{_SIMCORE_RUNTIME_DOCKER_LABEL_PREFIX}simcore-user-agent"
94-
)
95-
96-
swarm_stack_name: str = Field( # type: ignore[literal-required]
97-
..., alias=f"{_SIMCORE_RUNTIME_DOCKER_LABEL_PREFIX}swarm-stack-name"
98-
)
99-
100-
memory_limit: ByteSize = Field( # type: ignore[literal-required]
101-
..., alias=f"{_SIMCORE_RUNTIME_DOCKER_LABEL_PREFIX}memory-limit"
102-
)
103-
cpu_limit: float = Field( # type: ignore[literal-required]
104-
..., alias=f"{_SIMCORE_RUNTIME_DOCKER_LABEL_PREFIX}cpu-limit"
105-
)
106-
107-
@model_validator(mode="before")
108-
@classmethod
109-
def _backwards_compatibility(cls, values: dict[str, Any]) -> dict[str, Any]:
110-
# NOTE: this is necessary for dy-sidecar and legacy service until they are adjusted
111-
if mapped_values := {
112-
_BACKWARDS_COMPATIBILITY_SIMCORE_RUNTIME_DOCKER_LABELS_MAP[k]: v
113-
for k, v in values.items()
114-
if k in _BACKWARDS_COMPATIBILITY_SIMCORE_RUNTIME_DOCKER_LABELS_MAP
115-
}:
116-
# these values were sometimes omitted, so let's provide some defaults
117-
for key in ["product-name", "simcore-user-agent", "swarm-stack-name"]:
118-
mapped_values.setdefault(
119-
f"{_SIMCORE_RUNTIME_DOCKER_LABEL_PREFIX}{key}",
120-
_UNDEFINED_LABEL_VALUE_STR,
121-
)
122-
123-
mapped_values.setdefault(
124-
f"{_SIMCORE_RUNTIME_DOCKER_LABEL_PREFIX}memory-limit",
125-
values.get("memory_limit", _UNDEFINED_LABEL_VALUE_INT),
126-
)
127-
128-
def _convert_nano_cpus_to_cpus(nano_cpu: str) -> str:
129-
with contextlib.suppress(ValidationError):
130-
return f"{TypeAdapter(float).validate_python(nano_cpu) / (1.0 * 10**9):.2f}"
131-
return _UNDEFINED_LABEL_VALUE_INT
132-
133-
mapped_values.setdefault(
134-
f"{_SIMCORE_RUNTIME_DOCKER_LABEL_PREFIX}cpu-limit",
135-
values.get(
136-
"cpu_limit",
137-
_convert_nano_cpus_to_cpus(
138-
values.get(
139-
"nano_cpus_limit",
140-
_UNDEFINED_LABEL_VALUE_INT,
141-
)
142-
),
143-
),
144-
)
145-
return mapped_values
146-
return values
147-
148-
def to_simcore_runtime_docker_labels(self) -> dict[DockerLabelKey, str]:
149-
"""returns a dictionary of strings as required by docker"""
150-
return {
151-
to_simcore_runtime_docker_label_key(k): f"{v}"
152-
for k, v in sorted(self.model_dump().items())
153-
}
154-
155-
@classmethod
156-
def from_docker_task(cls, docker_task: Task) -> "StandardSimcoreDockerLabels":
157-
assert docker_task.spec # nosec
158-
assert docker_task.spec.container_spec # nosec
159-
task_labels = docker_task.spec.container_spec.labels or {}
160-
return cls.model_validate(task_labels)
161-
162-
model_config = ConfigDict(
163-
populate_by_name=True,
164-
json_schema_extra={
165-
"examples": [
166-
# legacy service labels
167-
{
168-
"study_id": "29f393fc-1410-47b3-b4b9-61dfce21a2a6",
169-
"swarm_stack_name": "devel-simcore",
170-
"user_id": "5",
171-
"uuid": "1f963626-66e1-43f1-a777-33955c08b909",
172-
},
173-
# legacy container labels
174-
{
175-
"mem_limit": "1073741824",
176-
"nano_cpus_limit": "4000000000",
177-
"node_id": "1f963626-66e1-43f1-a777-33955c08b909",
178-
"simcore_user_agent": "puppeteer",
179-
"study_id": "29f393fc-1410-47b3-b4b9-61dfce21a2a6",
180-
"swarm_stack_name": "devel-simcore",
181-
"user_id": "5",
182-
},
183-
# dy-sidecar service labels
184-
{
185-
"study_id": "29f393fc-1410-47b3-b4b9-61dfce21a2a6",
186-
"swarm_stack_name": "devel-simcore",
187-
"user_id": "5",
188-
"uuid": "1f963626-66e1-43f1-a777-33955c08b909",
189-
},
190-
# dy-sidecar container labels
191-
{
192-
"mem_limit": "1073741824",
193-
"nano_cpus_limit": "4000000000",
194-
"study_id": "29f393fc-1410-47b3-b4b9-61dfce21a2a6",
195-
"user_id": "5",
196-
"uuid": "1f963626-66e1-43f1-a777-33955c08b909",
197-
},
198-
# dy-proxy service labels
199-
{
200-
"dynamic-type": "dynamic-sidecar",
201-
"study_id": "29f393fc-1410-47b3-b4b9-61dfce21a2a6",
202-
"swarm_stack_name": "devel-simcore",
203-
"type": "dependency-v2",
204-
"user_id": "5",
205-
"uuid": "1f963626-66e1-43f1-a777-33955c08b909",
206-
},
207-
# dy-proxy container labels
208-
{
209-
"study_id": "29f393fc-1410-47b3-b4b9-61dfce21a2a6",
210-
"user_id": "5",
211-
"uuid": "1f963626-66e1-43f1-a777-33955c08b909",
212-
},
213-
# dy-sidecar user-services labels
214-
{
215-
"product_name": "osparc",
216-
"simcore_user_agent": "puppeteer",
217-
"study_id": "29f393fc-1410-47b3-b4b9-61dfce21a2a6",
218-
"user_id": "5",
219-
"uuid": "1f963626-66e1-43f1-a777-33955c08b909",
220-
},
221-
# modern both dynamic-sidecar services and computational services
222-
{
223-
"io.simcore.runtime.cpu-limit": "2.4",
224-
"io.simcore.runtime.memory-limit": "1073741824",
225-
"io.simcore.runtime.node-id": "1f963626-66e1-43f1-a777-33955c08b909",
226-
"io.simcore.runtime.product-name": "osparc",
227-
"io.simcore.runtime.project-id": "29f393fc-1410-47b3-b4b9-61dfce21a2a6",
228-
"io.simcore.runtime.simcore-user-agent": "puppeteer",
229-
"io.simcore.runtime.swarm-stack-name": "devel-osparc",
230-
"io.simcore.runtime.user-id": "5",
231-
},
232-
]
233-
},
234-
)
235-
23637

23738
DockerNodeID: TypeAlias = Annotated[
23839
str, StringConstraints(strip_whitespace=True, pattern=re.compile(r"[a-zA-Z0-9]"))

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

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from .basic_types import SemanticVersionStr
77
from .boot_options import BootOption, BootOptions
88
from .emails import LowerCaseEmailStr
9+
from .service_settings_labels import SimcoreServiceLabels
910
from .services_authoring import Author, Badge
1011
from .services_base import ServiceBaseDisplay, ServiceKeyVersion
1112
from .services_constants import ANY_FILETYPE
@@ -76,14 +77,24 @@
7677
}
7778
},
7879
"boot-options": {
79-
"example_service_defined_boot_mode": BootOption.model_config["json_schema_extra"]["examples"][0], # type: ignore [index]
80-
"example_service_defined_theme_selection": BootOption.model_config["json_schema_extra"]["examples"][1], # type: ignore [index]
80+
"example_service_defined_boot_mode": BootOption.model_config[
81+
"json_schema_extra"
82+
]["examples"][
83+
0
84+
], # type: ignore [index]
85+
"example_service_defined_theme_selection": BootOption.model_config[
86+
"json_schema_extra"
87+
]["examples"][
88+
1
89+
], # type: ignore [index]
8190
},
8291
"min-visible-inputs": 2,
8392
}
8493

8594

86-
class ServiceMetaDataPublished(ServiceKeyVersion, ServiceBaseDisplay):
95+
class ServiceMetaDataPublished(
96+
ServiceKeyVersion, ServiceBaseDisplay, SimcoreServiceLabels
97+
):
8798
"""
8899
Service metadata at publication time
89100

0 commit comments

Comments
 (0)