Skip to content

Commit 61cc89c

Browse files
author
Andrei Neagu
committed
fixed dynamic-sidecar
1 parent df65a49 commit 61cc89c

32 files changed

+453
-207
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import datetime
2+
3+
from pydantic import field_validator
4+
5+
6+
def _get_float_string_as_seconds(
7+
v: datetime.timedelta | str | float,
8+
) -> datetime.timedelta | float | str:
9+
if isinstance(v, str):
10+
try:
11+
return float(v)
12+
except ValueError:
13+
# returns format like "1:00:00"
14+
return v
15+
return v
16+
17+
18+
def validate_timedelta_in_legacy_mode(field: str):
19+
"""Transforms a float/int number into a valid datetime as it used to work in the past"""
20+
return field_validator(field, mode="before")(_get_float_string_as_seconds)
Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
from typing import Final
22

33
from common_library.pydantic_networks_extension import AnyHttpUrlLegacy, AnyUrlLegacy
4-
from pydantic import TypeAdapter
4+
from pydantic import ByteSize, TypeAdapter
55

66
AnyUrlLegacyAdapter: Final[TypeAdapter[AnyUrlLegacy]] = TypeAdapter(AnyUrlLegacy)
77

8-
AnyHttpUrlLegacyAdapter: Final[TypeAdapter[AnyHttpUrlLegacy]] = TypeAdapter(AnyHttpUrlLegacy)
8+
AnyHttpUrlLegacyAdapter: Final[TypeAdapter[AnyHttpUrlLegacy]] = TypeAdapter(
9+
AnyHttpUrlLegacy
10+
)
11+
12+
ByteSizeAdapter = TypeAdapter(ByteSize)
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
from datetime import timedelta
2+
3+
import pytest
4+
from common_library.pydantic_settings_validators import (
5+
validate_timedelta_in_legacy_mode,
6+
)
7+
from faker import Faker
8+
from pydantic import Field
9+
from pydantic_settings import BaseSettings, SettingsConfigDict
10+
from pytest_simcore.helpers.monkeypatch_envs import setenvs_from_dict
11+
12+
13+
def test_validate_timedelta_in_legacy_mode(
14+
monkeypatch: pytest.MonkeyPatch, faker: Faker
15+
):
16+
class Settings(BaseSettings):
17+
APP_NAME: str
18+
REQUEST_TIMEOUT: timedelta = Field(default=timedelta(seconds=40))
19+
20+
_legacy_parsing_request_timeout = validate_timedelta_in_legacy_mode(
21+
"REQUEST_TIMEOUT"
22+
)
23+
24+
model_config = SettingsConfigDict()
25+
26+
app_name = faker.pystr()
27+
env_vars: dict[str, str | bool] = {"APP_NAME": app_name}
28+
29+
# without timedelta
30+
setenvs_from_dict(monkeypatch, env_vars)
31+
settings = Settings()
32+
print(settings.model_dump())
33+
assert app_name == settings.APP_NAME
34+
assert timedelta(seconds=40) == settings.REQUEST_TIMEOUT
35+
36+
# with timedelta in seconds
37+
env_vars["REQUEST_TIMEOUT"] = "5555"
38+
setenvs_from_dict(monkeypatch, env_vars)
39+
settings = Settings()
40+
print(settings.model_dump())
41+
assert app_name == settings.APP_NAME
42+
assert timedelta(seconds=5555) == settings.REQUEST_TIMEOUT

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
SimcoreS3FileID: TypeAlias = Annotated[
4545
str, StringConstraints(pattern=SIMCORE_S3_FILE_ID_RE)
4646
]
47+
SimcoreS3FileIDTypeAdapter = TypeAdapter(SimcoreS3FileID)
4748

4849

4950
class SimcoreS3DirectoryID(ConstrainedStr):

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

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
from typing import Any
22

3-
from pydantic import BaseModel, ConfigDict
3+
from pydantic import BaseModel, ConfigDict, TypeAdapter
44

5-
from .services import ServiceKey, ServiceVersion
65
from .services_resources import ServiceResourcesDict
6+
from .services_types import (
7+
ServiceKey,
8+
ServiceKeyTypeAdapter,
9+
ServiceVersion,
10+
ServiceVersionTypeAdapter,
11+
)
712
from .wallets import WalletID
813

914

@@ -36,10 +41,18 @@ class CreateServiceMetricsAdditionalParams(BaseModel):
3641
"user_email": "[email protected]",
3742
"project_name": "_!New Study",
3843
"node_name": "the service of a lifetime _ *!",
39-
"service_key": ServiceKey("simcore/services/dynamic/test"),
40-
"service_version": ServiceVersion("0.0.1"),
44+
"service_key": ServiceKeyTypeAdapter.validate_python(
45+
"simcore/services/dynamic/test"
46+
),
47+
"service_version": ServiceVersionTypeAdapter.validate_python("0.0.1"),
4148
"service_resources": {},
4249
"service_additional_metadata": {},
50+
"pricing_unit_cost_id": None,
4351
}
4452
}
4553
)
54+
55+
56+
CreateServiceMetricsAdditionalParamsTypeAdapter = TypeAdapter(
57+
CreateServiceMetricsAdditionalParams
58+
)

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
StrictFloat,
99
StrictInt,
1010
StringConstraints,
11+
TypeAdapter,
1112
ValidationInfo,
1213
field_validator,
1314
)
@@ -149,7 +150,6 @@ class ServiceInput(BaseServiceIOModel):
149150
)
150151

151152
model_config = ConfigDict(
152-
**BaseServiceIOModel.model_config,
153153
json_schema_extra={
154154
"examples": [
155155
# file-wo-widget:
@@ -222,7 +222,6 @@ class ServiceOutput(BaseServiceIOModel):
222222
)
223223

224224
model_config = ConfigDict(
225-
**BaseServiceIOModel.model_config,
226225
json_schema_extra={
227226
"examples": [
228227
{
@@ -259,3 +258,6 @@ def from_json_schema(cls, port_schema: dict[str, Any]) -> "ServiceOutput":
259258
"""Creates output port model from a json-schema"""
260259
data = cls._from_json_schema_base_implementation(port_schema)
261260
return cls.model_validate(data)
261+
262+
263+
ServiceOutputTypeAdapter = TypeAdapter(ServiceOutput)

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

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from uuid import uuid4
33

44
import arrow
5-
from pydantic import StringConstraints
5+
from pydantic import StringConstraints, TypeAdapter
66

77
from .basic_regex import PROPERTY_KEY_RE, SIMPLE_VERSION_RE
88
from .services_regex import (
@@ -18,16 +18,22 @@
1818
FileName: TypeAlias = Annotated[str, StringConstraints(pattern=FILENAME_RE)]
1919

2020
ServiceKey: TypeAlias = Annotated[str, StringConstraints(pattern=SERVICE_KEY_RE)]
21+
ServiceKeyTypeAdapter = TypeAdapter(ServiceKey)
2122

22-
ServiceKeyEncoded: TypeAlias = Annotated[str, StringConstraints(pattern=SERVICE_ENCODED_KEY_RE)]
23+
ServiceKeyEncoded: TypeAlias = Annotated[
24+
str, StringConstraints(pattern=SERVICE_ENCODED_KEY_RE)
25+
]
2326

24-
DynamicServiceKey: TypeAlias = Annotated[str, StringConstraints(pattern=DYNAMIC_SERVICE_KEY_RE)]
27+
DynamicServiceKey: TypeAlias = Annotated[
28+
str, StringConstraints(pattern=DYNAMIC_SERVICE_KEY_RE)
29+
]
2530

2631
ComputationalServiceKey: TypeAlias = Annotated[
2732
str, StringConstraints(pattern=COMPUTATIONAL_SERVICE_KEY_RE)
2833
]
2934

3035
ServiceVersion: TypeAlias = Annotated[str, StringConstraints(pattern=SIMPLE_VERSION_RE)]
36+
ServiceVersionTypeAdapter = TypeAdapter(ServiceVersion)
3137

3238

3339
class RunID(str):

services/director-v2/src/simcore_service_director_v2/core/application.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ def create_base_app(settings: AppSettings | None = None) -> FastAPI:
115115
config_all_loggers(
116116
log_format_local_dev_enabled=settings.DIRECTOR_V2_LOG_FORMAT_LOCAL_DEV_ENABLED
117117
)
118-
_logger.debug(settings.json(indent=2))
118+
_logger.debug(settings.model_dump_json(indent=2))
119119

120120
# keep mostly quiet noisy loggers
121121
quiet_level: int = max(

services/director-v2/tests/unit/test_modules_dynamic_sidecar_client_api_thin.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@
99
from faker import Faker
1010
from fastapi import FastAPI, status
1111
from httpx import Response
12-
from models_library.services_creation import CreateServiceMetricsAdditionalParams
12+
from models_library.services_creation import (
13+
CreateServiceMetricsAdditionalParams,
14+
CreateServiceMetricsAdditionalParamsTypeAdapter,
15+
)
1316
from models_library.sidecar_volumes import VolumeCategory, VolumeStatus
1417
from pydantic import AnyHttpUrl, parse_obj_as
1518
from pytest_simcore.helpers.typing_env import EnvVarsDict
@@ -282,9 +285,10 @@ async def test_put_volumes(
282285
"post_containers_tasks",
283286
"/containers",
284287
{
285-
"metrics_params": parse_obj_as(
286-
CreateServiceMetricsAdditionalParams,
287-
CreateServiceMetricsAdditionalParams.Config.schema_extra["example"],
288+
"metrics_params": CreateServiceMetricsAdditionalParamsTypeAdapter.validate_python(
289+
CreateServiceMetricsAdditionalParams.model_config[
290+
"json_schema_extra"
291+
]["example"],
288292
)
289293
},
290294
id="post_containers_tasks",

services/dynamic-sidecar/.env-devel

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ DY_SIDECAR_USER_SERVICES_HAVE_INTERNET_ACCESS=false
2424
# DOCKER REGISTRY
2525
DY_DEPLOYMENT_REGISTRY_SETTINGS='{"REGISTRY_AUTH":"false","REGISTRY_USER":"test","REGISTRY_PW":"test","REGISTRY_SSL":"false"}'
2626

27-
S3_ENDPOINT=http://145.456.25.54:12345
27+
S3_ENDPOINT=http://111.111.111.111:12345
2828
S3_ACCESS_KEY=mocked
2929
S3_REGION=mocked
3030
S3_SECRET_KEY=mocked

0 commit comments

Comments
 (0)