diff --git a/bioimageio_collection_backoffice/common.py b/bioimageio_collection_backoffice/common.py index aa07154..93b83bb 100644 --- a/bioimageio_collection_backoffice/common.py +++ b/bioimageio_collection_backoffice/common.py @@ -1,4 +1,8 @@ +from typing import Any, ClassVar, Dict, FrozenSet, Union + import pydantic +from pydantic_core import PydanticUndefined +from typing_extensions import LiteralString class Node( @@ -12,4 +16,25 @@ class Node( ): """""" # avoid inheriting docstring from `pydantic.BaseModel` - pass + fields_to_set_explicitly: ClassVar[FrozenSet[LiteralString]] = frozenset() + """set set these fields explicitly with their default value if they are not set, + such that they are always included even when dumping with 'exlude_unset'""" + + @pydantic.model_validator(mode="before") + @classmethod + def set_fields_explicitly( + cls, data: Union[Any, Dict[str, Any]] + ) -> Union[Any, Dict[str, Any]]: + if isinstance(data, dict): + for name in cls.fields_to_set_explicitly: + if ( + name not in data + and name in cls.model_fields + and ( + (field_info := cls.model_fields[name]) is not PydanticUndefined + or field_info.default_factory is not None + ) + ): + data[name] = field_info.get_default(call_default_factory=True) + + return data # pyright: ignore[reportUnknownVariableType] diff --git a/bioimageio_collection_backoffice/db_structure/version_info.py b/bioimageio_collection_backoffice/db_structure/version_info.py index 6380777..a59a726 100644 --- a/bioimageio_collection_backoffice/db_structure/version_info.py +++ b/bioimageio_collection_backoffice/db_structure/version_info.py @@ -1,16 +1,27 @@ from __future__ import annotations from datetime import datetime -from typing import ClassVar, List, Literal, Optional, Sequence, Union +from typing import ( + ClassVar, + FrozenSet, + List, + Literal, + Optional, + Sequence, + Union, +) import pydantic -from typing_extensions import Annotated +from typing_extensions import Annotated, LiteralString from .._settings import settings from ..common import Node class _StatusBase(Node, frozen=True): + fields_to_set_explicitly: ClassVar[FrozenSet[LiteralString]] = frozenset( + {"name", "step", "num_steps", "description"} + ) timestamp: datetime = pydantic.Field(default_factory=datetime.now) run_url: Optional[str] = settings.run_url