Coverage for bioimageio/spec/_description.py: 74%
61 statements
« prev ^ index » next coverage.py v7.8.0, created at 2025-04-02 14:21 +0000
« prev ^ index » next coverage.py v7.8.0, created at 2025-04-02 14:21 +0000
1from types import MappingProxyType
2from typing import Any, Literal, Optional, TypeVar, Union, overload
4from pydantic import Discriminator
5from typing_extensions import Annotated
7from bioimageio.spec._internal.validation_context import ValidationContext
9from ._description_impl import DISCOVER, build_description_impl, get_rd_class_impl
10from ._internal.common_nodes import InvalidDescr
11from ._internal.io import BioimageioYamlContent
12from ._internal.types import FormatVersionPlaceholder
13from ._internal.validation_context import get_validation_context
14from .application import (
15 AnyApplicationDescr,
16 ApplicationDescr,
17 ApplicationDescr_v0_2,
18 ApplicationDescr_v0_3,
19)
20from .dataset import AnyDatasetDescr, DatasetDescr, DatasetDescr_v0_2, DatasetDescr_v0_3
21from .generic import AnyGenericDescr, GenericDescr, GenericDescr_v0_2, GenericDescr_v0_3
22from .model import AnyModelDescr, ModelDescr, ModelDescr_v0_4, ModelDescr_v0_5
23from .notebook import (
24 AnyNotebookDescr,
25 NotebookDescr,
26 NotebookDescr_v0_2,
27 NotebookDescr_v0_3,
28)
29from .summary import ValidationSummary
31LATEST: Literal["latest"] = "latest"
32"""placeholder for the latest available format version"""
35LatestResourceDescr = Union[
36 Annotated[
37 Union[
38 ApplicationDescr,
39 DatasetDescr,
40 ModelDescr,
41 NotebookDescr,
42 ],
43 Discriminator("type"),
44 ],
45 GenericDescr,
46]
47"""A resource description following the latest specification format"""
50SpecificResourceDescr = Annotated[
51 Union[
52 AnyApplicationDescr,
53 AnyDatasetDescr,
54 AnyModelDescr,
55 AnyNotebookDescr,
56 ],
57 Discriminator("type"),
58]
59"""Any of the implemented, non-generic resource descriptions"""
61ResourceDescr = Union[SpecificResourceDescr, AnyGenericDescr]
62"""Any of the implemented resource descriptions"""
65def dump_description(
66 rd: Union[ResourceDescr, InvalidDescr],
67 /,
68 *,
69 exclude_unset: bool = True,
70 exclude_defaults: bool = False,
71) -> BioimageioYamlContent:
72 """Converts a resource to a dictionary containing only simple types that can directly be serialzed to YAML.
74 Args:
75 rd: bioimageio resource description
76 exclude_unset: Exclude fields that have not explicitly be set.
77 exclude_defaults: Exclude fields that have the default value (even if set explicitly).
78 """
79 return rd.model_dump(
80 mode="json", exclude_unset=exclude_unset, exclude_defaults=exclude_defaults
81 )
84RD = TypeVar("RD", bound=ResourceDescr)
87LATEST_DESCRIPTIONS_MAP = MappingProxyType(
88 {
89 None: GenericDescr,
90 "generic": GenericDescr,
91 "application": ApplicationDescr,
92 "dataset": DatasetDescr,
93 "notebook": NotebookDescr,
94 "model": ModelDescr,
95 }
96)
97DESCRIPTIONS_MAP = MappingProxyType(
98 {
99 None: MappingProxyType(
100 {
101 "0.2": GenericDescr_v0_2,
102 "0.3": GenericDescr_v0_3,
103 None: GenericDescr,
104 }
105 ),
106 "generic": MappingProxyType(
107 {
108 "0.2": GenericDescr_v0_2,
109 "0.3": GenericDescr_v0_3,
110 None: GenericDescr,
111 }
112 ),
113 "application": MappingProxyType(
114 {
115 "0.2": ApplicationDescr_v0_2,
116 "0.3": ApplicationDescr_v0_3,
117 None: ApplicationDescr,
118 }
119 ),
120 "dataset": MappingProxyType(
121 {
122 "0.2": DatasetDescr_v0_2,
123 "0.3": DatasetDescr_v0_3,
124 None: DatasetDescr,
125 }
126 ),
127 "notebook": MappingProxyType(
128 {
129 "0.2": NotebookDescr_v0_2,
130 "0.3": NotebookDescr_v0_3,
131 None: NotebookDescr,
132 }
133 ),
134 "model": MappingProxyType(
135 {
136 "0.3": ModelDescr_v0_4,
137 "0.4": ModelDescr_v0_4,
138 "0.5": ModelDescr_v0_5,
139 None: ModelDescr,
140 }
141 ),
142 }
143)
144"""A mapping to determine the appropriate Description class
145 for a given **type** and **format_version**."""
148def _get_rd_class(typ: Any, format_version: Any):
149 return get_rd_class_impl(typ, format_version, DESCRIPTIONS_MAP)
152@overload
153def build_description(
154 content: BioimageioYamlContent,
155 /,
156 *,
157 context: Optional[ValidationContext] = None,
158 format_version: Literal["latest"],
159) -> Union[LatestResourceDescr, InvalidDescr]: ...
162@overload
163def build_description(
164 content: BioimageioYamlContent,
165 /,
166 *,
167 context: Optional[ValidationContext] = None,
168 format_version: Union[FormatVersionPlaceholder, str] = DISCOVER,
169) -> Union[ResourceDescr, InvalidDescr]: ...
172def build_description(
173 content: BioimageioYamlContent,
174 /,
175 *,
176 context: Optional[ValidationContext] = None,
177 format_version: Union[FormatVersionPlaceholder, str] = DISCOVER,
178) -> Union[ResourceDescr, InvalidDescr]:
179 """build a bioimage.io resource description from an RDF's content.
181 Use `load_description` if you want to build a resource description from an rdf.yaml
182 or bioimage.io zip-package.
184 Args:
185 content: loaded rdf.yaml file (loaded with YAML, not bioimageio.spec)
186 context: validation context to use during validation
187 format_version: (optional) use this argument to load the resource and
188 convert its metadata to a higher format_version
190 Returns:
191 An object holding all metadata of the bioimage.io resource
193 """
195 return build_description_impl(
196 content,
197 context=context,
198 format_version=format_version,
199 get_rd_class=_get_rd_class,
200 )
203def validate_format(
204 data: BioimageioYamlContent,
205 /,
206 *,
207 format_version: Union[Literal["discover", "latest"], str] = DISCOVER,
208 context: Optional[ValidationContext] = None,
209) -> ValidationSummary:
210 """Validate a dictionary holding a bioimageio description.
211 See `bioimagieo.spec.load_description_and_validate_format_only`
212 to validate a file source.
214 Args:
215 data: Dictionary holding the raw bioimageio.yaml content.
216 format_version: Format version to (update to and) use for validation.
217 context: Validation context, see `bioimagieo.spec.ValidationContext`
219 Note:
220 Use `bioimagieo.spec.load_description_and_validate_format_only` to validate a
221 file source instead of loading the YAML content and creating the appropriate
222 `ValidationContext`.
224 Alternatively you can use `bioimagieo.spec.load_description` and access the
225 `validation_summary` attribute of the returned object.
226 """
227 with context or get_validation_context():
228 rd = build_description(data, format_version=format_version)
230 assert rd.validation_summary is not None
231 return rd.validation_summary
234def ensure_description_is_model(
235 rd: Union[InvalidDescr, ResourceDescr],
236) -> AnyModelDescr:
237 """
238 Raises:
239 ValueError: for invalid or non-model resources
240 """
241 if isinstance(rd, InvalidDescr):
242 rd.validation_summary.display()
243 raise ValueError(f"Invalid {rd.type} description")
245 if rd.type != "model":
246 rd.validation_summary.display()
247 raise ValueError(
248 f"Expected a model resource, but got resource type '{rd.type}'"
249 )
251 assert not isinstance(
252 rd,
253 (
254 GenericDescr_v0_2,
255 GenericDescr_v0_3,
256 ),
257 )
259 return rd
262def ensure_description_is_dataset(
263 rd: Union[InvalidDescr, ResourceDescr],
264) -> AnyDatasetDescr:
265 if isinstance(rd, InvalidDescr):
266 rd.validation_summary.display()
267 raise ValueError(f"Invalid {rd.type} description.")
269 if rd.type != "dataset":
270 rd.validation_summary.display()
271 raise ValueError(
272 f"Expected a dataset resource, but got resource type '{rd.type}'"
273 )
275 assert not isinstance(
276 rd,
277 (
278 GenericDescr_v0_2,
279 GenericDescr_v0_3,
280 ),
281 )
283 return rd