Coverage for src/bioimageio/spec/_description.py: 86%
57 statements
« prev ^ index » next coverage.py v7.10.7, created at 2025-10-07 08:37 +0000
« prev ^ index » next coverage.py v7.10.7, created at 2025-10-07 08:37 +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, BioimageioYamlContentView
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 "latest": GenericDescr,
104 }
105 ),
106 "generic": MappingProxyType(
107 {
108 "0.2": GenericDescr_v0_2,
109 "0.3": GenericDescr_v0_3,
110 "latest": GenericDescr,
111 }
112 ),
113 "application": MappingProxyType(
114 {
115 "0.2": ApplicationDescr_v0_2,
116 "0.3": ApplicationDescr_v0_3,
117 "latest": ApplicationDescr,
118 }
119 ),
120 "dataset": MappingProxyType(
121 {
122 "0.2": DatasetDescr_v0_2,
123 "0.3": DatasetDescr_v0_3,
124 "latest": DatasetDescr,
125 }
126 ),
127 "notebook": MappingProxyType(
128 {
129 "0.2": NotebookDescr_v0_2,
130 "0.3": NotebookDescr_v0_3,
131 "latest": 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 "latest": 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, fallback_to_latest: bool):
149 return get_rd_class_impl(
150 typ, format_version, DESCRIPTIONS_MAP, fallback_to_latest=fallback_to_latest
151 )
154@overload
155def build_description(
156 content: BioimageioYamlContentView,
157 /,
158 *,
159 context: Optional[ValidationContext] = None,
160 format_version: Literal["latest"],
161) -> Union[LatestResourceDescr, InvalidDescr]: ...
164@overload
165def build_description(
166 content: BioimageioYamlContentView,
167 /,
168 *,
169 context: Optional[ValidationContext] = None,
170 format_version: Union[FormatVersionPlaceholder, str] = DISCOVER,
171) -> Union[ResourceDescr, InvalidDescr]: ...
174def build_description(
175 content: BioimageioYamlContentView,
176 /,
177 *,
178 context: Optional[ValidationContext] = None,
179 format_version: Union[FormatVersionPlaceholder, str] = DISCOVER,
180) -> Union[ResourceDescr, InvalidDescr]:
181 """build a bioimage.io resource description from an RDF's content.
183 Use `load_description` if you want to build a resource description from an rdf.yaml
184 or bioimage.io zip-package.
186 Args:
187 content: loaded rdf.yaml file (loaded with YAML, not bioimageio.spec)
188 context: validation context to use during validation
189 format_version:
190 (optional) use this argument to load the resource and
191 convert its metadata to a higher format_version.
192 Note:
193 - Use "latest" to convert to the latest available format version.
194 - Use "discover" to use the format version specified in the RDF.
195 - Only considers major.minor format version, ignores patch version.
196 - Conversion to lower format versions is not supported.
198 Returns:
199 An object holding all metadata of the bioimage.io resource
201 """
203 return build_description_impl(
204 content,
205 context=context,
206 format_version=format_version,
207 get_rd_class=_get_rd_class,
208 )
211def validate_format(
212 data: BioimageioYamlContent,
213 /,
214 *,
215 format_version: Union[Literal["discover", "latest"], str] = DISCOVER,
216 context: Optional[ValidationContext] = None,
217) -> ValidationSummary:
218 """Validate a dictionary holding a bioimageio description.
219 See `bioimagieo.spec.load_description_and_validate_format_only`
220 to validate a file source.
222 Args:
223 data: Dictionary holding the raw bioimageio.yaml content.
224 format_version:
225 Format version to (update to and) use for validation.
226 Note:
227 - Use "latest" to convert to the latest available format version.
228 - Use "discover" to use the format version specified in the RDF.
229 - Only considers major.minor format version, ignores patch version.
230 - Conversion to lower format versions is not supported.
231 context: Validation context, see `bioimagieo.spec.ValidationContext`
233 Note:
234 Use `bioimagieo.spec.load_description_and_validate_format_only` to validate a
235 file source instead of loading the YAML content and creating the appropriate
236 `ValidationContext`.
238 Alternatively you can use `bioimagieo.spec.load_description` and access the
239 `validation_summary` attribute of the returned object.
240 """
241 with context or get_validation_context():
242 rd = build_description(data, format_version=format_version)
244 assert rd.validation_summary is not None
245 return rd.validation_summary
248def ensure_description_is_model(
249 rd: Union[InvalidDescr, ResourceDescr],
250) -> AnyModelDescr:
251 """
252 Raises:
253 ValueError: for invalid or non-model resources
254 """
255 if isinstance(rd, InvalidDescr):
256 rd.validation_summary.display()
257 raise ValueError(f"Invalid {rd.type} description")
259 if rd.type != "model":
260 rd.validation_summary.display()
261 raise ValueError(
262 f"Expected a model resource, but got resource type '{rd.type}'"
263 )
265 assert not isinstance(
266 rd,
267 (
268 GenericDescr_v0_2,
269 GenericDescr_v0_3,
270 ),
271 )
273 return rd
276def ensure_description_is_dataset(
277 rd: Union[InvalidDescr, ResourceDescr],
278) -> AnyDatasetDescr:
279 if isinstance(rd, InvalidDescr):
280 rd.validation_summary.display()
281 raise ValueError(f"Invalid {rd.type} description.")
283 if rd.type != "dataset":
284 rd.validation_summary.display()
285 raise ValueError(
286 f"Expected a dataset resource, but got resource type '{rd.type}'"
287 )
289 assert not isinstance(
290 rd,
291 (
292 GenericDescr_v0_2,
293 GenericDescr_v0_3,
294 ),
295 )
297 return rd