Skip to content

Commit 7c0291b

Browse files
committed
update
1 parent 36827b1 commit 7c0291b

File tree

11 files changed

+69
-133
lines changed

11 files changed

+69
-133
lines changed

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

Lines changed: 11 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -491,50 +491,28 @@ def _not_allowed_in_both_specs(self):
491491
model_config = _BaseConfig
492492

493493

494-
def _simcore_service_labels_json_schema_extra(json_schema_extra: JsonDict):
494+
def _simcore_service_labels_json_schema_extra(schema: JsonDict):
495+
#
496+
# NOTE: this will be automatically called with SimcoreServiceLabels.model_json_schema
497+
#
495498

496-
assert "json_schema_extra" in SimcoreServiceSettingLabelEntry.model_config # nosec
497-
assert isinstance( # nosec
498-
SimcoreServiceSettingLabelEntry.model_config["json_schema_extra"], dict
499-
)
500-
501-
assert "json_schema_extra" in PathMappingsLabel.model_config # nosec
502-
assert isinstance( # nosec
503-
PathMappingsLabel.model_config["json_schema_extra"], dict
504-
)
505-
assert isinstance( # nosec
506-
PathMappingsLabel.model_config["json_schema_extra"]["examples"], list
507-
)
508-
509-
assert "json_schema_extra" in CallbacksMapping.model_config # nosec
510-
assert isinstance(CallbacksMapping.model_config["json_schema_extra"], dict) # nosec
511-
assert isinstance( # nosec
512-
CallbacksMapping.model_config["json_schema_extra"]["examples"], list
513-
)
514-
515-
json_schema_extra.update(
499+
schema.update(
516500
{
517501
"examples": [
518502
# WARNING: do not change order. Used in tests!
519503
# legacy service
520504
{
521505
"simcore.service.settings": json_dumps(
522-
SimcoreServiceSettingLabelEntry.model_config[
523-
"json_schema_extra"
524-
]["examples"]
506+
SimcoreServiceSettingLabelEntry.model_json_schema()["examples"]
525507
)
526508
},
527509
# dynamic-service
528510
{
529511
"simcore.service.settings": json_dumps(
530-
SimcoreServiceSettingLabelEntry.model_config[
531-
"json_schema_extra"
532-
]["examples"]
512+
SimcoreServiceSettingLabelEntry.model_json_schema()["examples"]
533513
),
534514
"simcore.service.paths-mapping": json_dumps(
535-
PathMappingsLabel.model_config["json_schema_extra"]["examples"][
536-
0
537-
]
515+
PathMappingsLabel.model_json_schema()["examples"][0]
538516
),
539517
"simcore.service.restart-policy": RestartPolicy.NO_RESTART.value,
540518
"simcore.service.callbacks-mapping": json_dumps(
@@ -553,14 +531,10 @@ def _simcore_service_labels_json_schema_extra(json_schema_extra: JsonDict):
553531
# dynamic-service with compose spec
554532
{
555533
"simcore.service.settings": json_dumps(
556-
SimcoreServiceSettingLabelEntry.model_config[
557-
"json_schema_extra"
558-
]["examples"]
534+
SimcoreServiceSettingLabelEntry.model_json_schema()["examples"]
559535
),
560536
"simcore.service.paths-mapping": json_dumps(
561-
PathMappingsLabel.model_config["json_schema_extra"]["examples"][
562-
0
563-
],
537+
PathMappingsLabel.model_json_schema()["examples"][0],
564538
),
565539
"simcore.service.compose-spec": json_dumps(
566540
{
@@ -588,9 +562,7 @@ def _simcore_service_labels_json_schema_extra(json_schema_extra: JsonDict):
588562
"simcore.service.container-http-entrypoint": "rt-web",
589563
"simcore.service.restart-policy": RestartPolicy.ON_INPUTS_DOWNLOADED.value,
590564
"simcore.service.callbacks-mapping": json_dumps(
591-
CallbacksMapping.model_config["json_schema_extra"]["examples"][
592-
3
593-
]
565+
CallbacksMapping.model_json_schema()["examples"][3]
594566
),
595567
},
596568
]

packages/models-library/tests/test_service_settings_labels.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,17 +43,17 @@ class _Parametrization(NamedTuple):
4343

4444
SIMCORE_SERVICE_EXAMPLES = {
4545
"legacy": _Parametrization(
46-
example=SimcoreServiceLabels.model_config["json_schema_extra"]["examples"][0],
46+
example=SimcoreServiceLabels.model_json_schema()["examples"][0],
4747
items=1,
4848
uses_dynamic_sidecar=False,
4949
),
5050
"dynamic-service": _Parametrization(
51-
example=SimcoreServiceLabels.model_config["json_schema_extra"]["examples"][1],
51+
example=SimcoreServiceLabels.model_json_schema()["examples"][1],
5252
items=5,
5353
uses_dynamic_sidecar=True,
5454
),
5555
"dynamic-service-with-compose-spec": _Parametrization(
56-
example=SimcoreServiceLabels.model_config["json_schema_extra"]["examples"][2],
56+
example=SimcoreServiceLabels.model_json_schema()["examples"][2],
5757
items=6,
5858
uses_dynamic_sidecar=True,
5959
),
@@ -104,7 +104,7 @@ def test_correctly_detect_dynamic_sidecar_boot(
104104

105105
def test_raises_error_if_http_entrypoint_is_missing():
106106
simcore_service_labels: dict[str, Any] = deepcopy(
107-
SimcoreServiceLabels.model_config["json_schema_extra"]["examples"][2]
107+
SimcoreServiceLabels.model_json_schema()["examples"][2]
108108
)
109109
del simcore_service_labels["simcore.service.container-http-entrypoint"]
110110

@@ -133,7 +133,7 @@ def test_path_mappings_json_encoding():
133133

134134
def test_simcore_services_labels_compose_spec_null_container_http_entry_provided():
135135
sample_data: dict[str, Any] = deepcopy(
136-
SimcoreServiceLabels.model_config["json_schema_extra"]["examples"][2]
136+
SimcoreServiceLabels.model_json_schema()["examples"][2]
137137
)
138138

139139
assert sample_data["simcore.service.container-http-entrypoint"]
@@ -145,7 +145,7 @@ def test_simcore_services_labels_compose_spec_null_container_http_entry_provided
145145

146146
def test_raises_error_wrong_restart_policy():
147147
simcore_service_labels: dict[str, Any] = deepcopy(
148-
SimcoreServiceLabels.model_config["json_schema_extra"]["examples"][2]
148+
SimcoreServiceLabels.model_json_schema()["examples"][2]
149149
)
150150
simcore_service_labels["simcore.service.restart-policy"] = "__not_a_valid_policy__"
151151

packages/pytest-simcore/src/pytest_simcore/pydantic_models.py

Lines changed: 19 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -93,34 +93,22 @@ def _is_model_cls(obj) -> bool:
9393
assert inspect.ismodule(module)
9494

9595
for model_name, model_cls in inspect.getmembers(module, _is_model_cls):
96-
assert model_name # nosec
97-
if (
98-
(model_config := model_cls.model_config)
99-
and isinstance(model_config, dict)
100-
and (json_schema_extra := model_config.get("json_schema_extra", {}))
101-
):
102-
processed_schema_extra = {}
103-
104-
if callable(json_schema_extra):
105-
json_schema_extra(processed_schema_extra)
106-
else:
107-
processed_schema_extra = json_schema_extra
108-
109-
if isinstance(processed_schema_extra, dict):
110-
if "example" in processed_schema_extra:
111-
yield ModelExample(
112-
model_cls=model_cls,
113-
example_name="example",
114-
example_data=processed_schema_extra["example"],
115-
)
116-
117-
elif "examples" in processed_schema_extra:
118-
for index, example in enumerate(processed_schema_extra["examples"]):
119-
yield ModelExample(
120-
model_cls=model_cls,
121-
example_name=f"examples_{index}",
122-
example_data=example,
123-
)
96+
schema = model_cls.model_json_schema()
97+
98+
if example := schema.get("example"):
99+
yield ModelExample(
100+
model_cls=model_cls,
101+
example_name=f"{model_name}_example",
102+
example_data=example,
103+
)
104+
105+
if many_examples := schema.get("examples"):
106+
for index, example in enumerate(many_examples):
107+
yield ModelExample(
108+
model_cls=model_cls,
109+
example_name=f"{model_name}_examples_{index}",
110+
example_data=example,
111+
)
124112

125113

126114
## PYDANTIC MODELS & SCHEMAS -----------------------------------------------------
@@ -139,10 +127,10 @@ def model_cls_examples(model_cls: type[BaseModel]) -> dict[str, dict[str, Any]]:
139127
"SEE https://pydantic-docs.helpmanual.io/usage/schema/#schema-customization"
140128
)
141129

142-
json_schema_extra: dict = model_cls.model_config.get("json_schema_extra", {})
130+
json_schema: dict = model_cls.model_json_schema()
143131

144132
# checks exampleS setup in schema_extra
145-
examples_list = copy.deepcopy(json_schema_extra.get("examples", []))
133+
examples_list = copy.deepcopy(json_schema.get("examples", []))
146134
assert isinstance(examples_list, list), (
147135
"OpenAPI and json-schema differ regarding the format for exampleS."
148136
"The former is a dict and the latter an array. "
@@ -156,7 +144,7 @@ def model_cls_examples(model_cls: type[BaseModel]) -> dict[str, dict[str, Any]]:
156144
f"{model_cls.__name__}.example[{index}]": example_
157145
for index, example_ in enumerate(examples_list)
158146
}
159-
if example := copy.deepcopy(json_schema_extra.get("example")):
147+
if example := copy.deepcopy(json_schema.get("example")):
160148
examples[f"{model_cls.__name__}.example"] = example
161149

162150
return examples

services/director-v2/src/simcore_service_director_v2/modules/dynamic_sidecar/scheduler/_core/_events_user_services.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,8 @@ async def submit_compose_sepc(app: FastAPI, scheduler_data: SchedulerData) -> No
7474

7575
groups_extra_properties = get_repository(app, GroupsExtraPropertiesRepository)
7676
assert (
77-
scheduler_data.product_name is not None
78-
), "ONLY for legacy. This function should not be called with product_name==None" # nosec
77+
scheduler_data.product_name is not None # nosec
78+
), "ONLY for legacy. This function should not be called with product_name==None"
7979
allow_internet_access: bool = await groups_extra_properties.has_internet_access(
8080
user_id=scheduler_data.user_id, product_name=scheduler_data.product_name
8181
)
@@ -119,6 +119,10 @@ async def submit_compose_sepc(app: FastAPI, scheduler_data: SchedulerData) -> No
119119
async def create_user_services( # pylint: disable=too-many-statements
120120
app: FastAPI, scheduler_data: SchedulerData
121121
) -> None:
122+
assert (
123+
scheduler_data.product_name is not None # nosec
124+
), "ONLY for legacy. This function should not be called with product_name==None"
125+
122126
dynamic_services_scheduler_settings: DynamicServicesSchedulerSettings = (
123127
app.state.settings.DYNAMIC_SERVICES.DYNAMIC_SCHEDULER
124128
)

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ def simcore_services_network_name() -> str:
5252
@pytest.fixture
5353
def simcore_service_labels() -> SimcoreServiceLabels:
5454
json_schema_extra = {}
55-
SimcoreServiceLabels.model_config["json_schema_extra"](json_schema_extra)
55+
SimcoreServiceLabels.model_json_schema()(json_schema_extra)
5656

5757
simcore_service_labels = SimcoreServiceLabels.model_validate(
5858
json_schema_extra["examples"][1]

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

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
from typing import Any
77
from uuid import uuid4
88

9-
from pydantic import TypeAdapter
109
import pytest
1110
import yaml
1211
from models_library.docker import to_simcore_runtime_docker_label_key
@@ -22,6 +21,7 @@
2221
ServiceResourcesDict,
2322
)
2423
from models_library.users import UserID
24+
from pydantic import TypeAdapter
2525
from servicelib.resources import CPU_RESOURCE_LIMIT_KEY, MEM_RESOURCE_LIMIT_KEY
2626
from simcore_service_director_v2.modules.dynamic_sidecar import docker_compose_specs
2727

@@ -149,14 +149,16 @@ async def test_inject_resource_limits_and_reservations(
149149
assert f"{MEM_RESOURCE_LIMIT_KEY}={memory.limit}" in spec["environment"]
150150

151151

152+
_json_schema_extra = {}
153+
SimcoreServiceLabels.model_json_schema()(_json_schema_extra)
154+
155+
152156
@pytest.mark.parametrize(
153157
"compose_spec, storage_opt_count",
154158
[
155159
pytest.param(
156160
json.loads(
157-
SimcoreServiceLabels.model_config["json_schema_extra"]["examples"][2][
158-
"simcore.service.compose-spec"
159-
]
161+
_json_schema_extra["examples"][2]["simcore.service.compose-spec"]
160162
),
161163
2,
162164
id="two_storage_opt_entries",
@@ -198,7 +200,9 @@ def test_regression_service_has_no_reservations():
198200
"version": "3.7",
199201
"services": {DEFAULT_SINGLE_SERVICE_NAME: {}},
200202
}
201-
service_resources: ServiceResourcesDict = TypeAdapter(ServiceResourcesDict).validate_python({})
203+
service_resources: ServiceResourcesDict = TypeAdapter(
204+
ServiceResourcesDict
205+
).validate_python({})
202206

203207
spec_before = deepcopy(service_spec)
204208
docker_compose_specs._update_resource_limits_and_reservations(

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

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -162,11 +162,7 @@ def mocked_director_v0(
162162
),
163163
name="service labels",
164164
).respond(
165-
json={
166-
"data": SimcoreServiceLabels.model_config["json_schema_extra"][
167-
"examples"
168-
][0]
169-
}
165+
json={"data": SimcoreServiceLabels.model_json_schema()["examples"][0]}
170166
)
171167
yield mock
172168

services/director-v2/tests/unit/with_dbs/comp_scheduler/test_api_route_computations.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ def fake_service_resources() -> ServiceResourcesDict:
126126
@pytest.fixture
127127
def fake_service_labels() -> dict[str, Any]:
128128
return choice( # noqa: S311
129-
SimcoreServiceLabels.model_config["json_schema_extra"]["examples"] # type: ignore
129+
SimcoreServiceLabels.model_json_schema()["examples"] # type: ignore
130130
)
131131

132132

0 commit comments

Comments
 (0)