Skip to content

Commit 7e218eb

Browse files
committed
@GitHK review: example assert
1 parent e39a580 commit 7e218eb

File tree

3 files changed

+66
-63
lines changed

3 files changed

+66
-63
lines changed

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

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
Models Node as a central element in a project's pipeline
33
"""
44

5-
from copy import deepcopy
65
from typing import Annotated, Any, TypeAlias, Union
76

87
from common_library.basic_types import Undefined
@@ -116,16 +115,6 @@ class NodeState(BaseModel):
116115
)
117116

118117

119-
def _patch_json_schema_extra(schema: dict) -> None:
120-
# NOTE: exporting without this trick does not make runHash as nullable.
121-
# It is a Pydantic issue see https://github.com/samuelcolvin/pydantic/issues/1270
122-
for prop_name in ["parent", "runHash"]:
123-
if prop_name in schema.get("properties", {}):
124-
prop = deepcopy(schema["properties"][prop_name])
125-
prop["nullable"] = True
126-
schema["properties"][prop_name] = prop
127-
128-
129118
class Node(BaseModel):
130119
key: ServiceKey = Field(
131120
...,
@@ -285,6 +274,5 @@ def _convert_from_enum(cls, v):
285274

286275
model_config = ConfigDict(
287276
extra="forbid",
288-
json_schema_extra=_patch_json_schema_extra,
289277
populate_by_name=True,
290278
)

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

Lines changed: 47 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
field_validator,
2020
model_validator,
2121
)
22+
from pydantic.config import JsonDict
2223

2324
from .callbacks_mapping import CallbacksMapping
2425
from .generics import ListModel
@@ -490,57 +491,29 @@ def _not_allowed_in_both_specs(self):
490491
model_config = _BaseConfig
491492

492493

493-
class SimcoreServiceLabels(DynamicSidecarServiceLabels):
494-
"""
495-
Validate all the simcores.services.* labels on a service.
496-
497-
When no other fields expect `settings` are present
498-
the service will be started as legacy by director-v0.
499-
500-
If `paths_mapping` is present the service will be started
501-
via dynamic-sidecar by director-v2.
502-
503-
When starting via dynamic-sidecar, if `compose_spec` is
504-
present, also `container_http_entry` must be present.
505-
When both of these fields are missing a docker-compose
506-
spec will be generated before starting the service.
507-
"""
508-
509-
settings: Annotated[
510-
Json[SimcoreServiceSettingsLabel],
511-
Field(
512-
default_factory=dict,
513-
alias="simcore.service.settings",
514-
description=(
515-
"Json encoded. Contains setting like environment variables and "
516-
"resource constraints which are required by the service. "
517-
"Should be compatible with Docker REST API."
518-
),
519-
),
520-
]
494+
def _simcore_service_labels_json_schema_extra(json_schema_extra: JsonDict):
521495

522496
assert "json_schema_extra" in SimcoreServiceSettingLabelEntry.model_config # nosec
523-
assert isinstance(
497+
assert isinstance( # nosec
524498
SimcoreServiceSettingLabelEntry.model_config["json_schema_extra"], dict
525-
) # nosec
499+
)
526500

527501
assert "json_schema_extra" in PathMappingsLabel.model_config # nosec
528-
assert isinstance(
502+
assert isinstance( # nosec
529503
PathMappingsLabel.model_config["json_schema_extra"], dict
530-
) # nosec
531-
assert isinstance(
504+
)
505+
assert isinstance( # nosec
532506
PathMappingsLabel.model_config["json_schema_extra"]["examples"], list
533-
) # nosec
507+
)
534508

535509
assert "json_schema_extra" in CallbacksMapping.model_config # nosec
536510
assert isinstance(CallbacksMapping.model_config["json_schema_extra"], dict) # nosec
537-
assert isinstance(
511+
assert isinstance( # nosec
538512
CallbacksMapping.model_config["json_schema_extra"]["examples"], list
539-
) # nosec
513+
)
540514

541-
model_config = _BaseConfig | ConfigDict(
542-
extra="allow",
543-
json_schema_extra={
515+
json_schema_extra.update(
516+
{
544517
"examples": [
545518
# WARNING: do not change order. Used in tests!
546519
# legacy service
@@ -623,3 +596,38 @@ class SimcoreServiceLabels(DynamicSidecarServiceLabels):
623596
]
624597
},
625598
)
599+
600+
601+
class SimcoreServiceLabels(DynamicSidecarServiceLabels):
602+
"""
603+
Validate all the simcores.services.* labels on a service.
604+
605+
When no other fields expect `settings` are present
606+
the service will be started as legacy by director-v0.
607+
608+
If `paths_mapping` is present the service will be started
609+
via dynamic-sidecar by director-v2.
610+
611+
When starting via dynamic-sidecar, if `compose_spec` is
612+
present, also `container_http_entry` must be present.
613+
When both of these fields are missing a docker-compose
614+
spec will be generated before starting the service.
615+
"""
616+
617+
settings: Annotated[
618+
Json[SimcoreServiceSettingsLabel],
619+
Field(
620+
default_factory=dict,
621+
alias="simcore.service.settings",
622+
description=(
623+
"Json encoded. Contains setting like environment variables and "
624+
"resource constraints which are required by the service. "
625+
"Should be compatible with Docker REST API."
626+
),
627+
),
628+
]
629+
630+
model_config = _BaseConfig | ConfigDict(
631+
extra="allow",
632+
json_schema_extra=_simcore_service_labels_json_schema_extra,
633+
)

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

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -98,23 +98,30 @@ def _is_model_cls(obj) -> bool:
9898
(model_config := model_cls.model_config)
9999
and isinstance(model_config, dict)
100100
and (json_schema_extra := model_config.get("json_schema_extra", {}))
101-
and isinstance(json_schema_extra, dict)
102101
):
103-
if "example" in json_schema_extra:
104-
yield ModelExample(
105-
model_cls=model_cls,
106-
example_name="example",
107-
example_data=json_schema_extra["example"],
108-
)
109-
110-
elif "examples" in json_schema_extra:
111-
for index, example in enumerate(json_schema_extra["examples"]):
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:
112111
yield ModelExample(
113112
model_cls=model_cls,
114-
example_name=f"examples_{index}",
115-
example_data=example,
113+
example_name="example",
114+
example_data=processed_schema_extra["example"],
116115
)
117116

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+
)
124+
118125

119126
## PYDANTIC MODELS & SCHEMAS -----------------------------------------------------
120127

0 commit comments

Comments
 (0)