Coverage for bioimageio/spec/_io.py: 70%
73 statements
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-27 09:20 +0000
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-27 09:20 +0000
1import collections.abc
2from pathlib import Path
3from typing import Dict, Literal, Optional, TextIO, Union, cast, overload
4from zipfile import ZipFile
6from loguru import logger
7from pydantic import FilePath, NewPath
9from ._description import (
10 DISCOVER,
11 LATEST,
12 InvalidDescr,
13 LatestResourceDescr,
14 ResourceDescr,
15 build_description,
16 dump_description,
17 ensure_description_is_dataset,
18 ensure_description_is_model,
19)
20from ._internal.common_nodes import ResourceDescrBase
21from ._internal.io import BioimageioYamlContent, YamlValue
22from ._internal.io_basics import Sha256
23from ._internal.io_utils import open_bioimageio_yaml, write_yaml
24from ._internal.types import FormatVersionPlaceholder
25from ._internal.validation_context import get_validation_context
26from .common import PermissiveFileSource
27from .dataset import AnyDatasetDescr, DatasetDescr
28from .model import AnyModelDescr, ModelDescr
29from .summary import ValidationSummary
32@overload
33def load_description(
34 source: Union[PermissiveFileSource, ZipFile],
35 /,
36 *,
37 format_version: Literal["latest"],
38 perform_io_checks: Optional[bool] = None,
39 known_files: Optional[Dict[str, Optional[Sha256]]] = None,
40 sha256: Optional[Sha256] = None,
41) -> Union[LatestResourceDescr, InvalidDescr]: ...
44@overload
45def load_description(
46 source: Union[PermissiveFileSource, ZipFile],
47 /,
48 *,
49 format_version: Union[FormatVersionPlaceholder, str] = DISCOVER,
50 perform_io_checks: Optional[bool] = None,
51 known_files: Optional[Dict[str, Optional[Sha256]]] = None,
52 sha256: Optional[Sha256] = None,
53) -> Union[ResourceDescr, InvalidDescr]: ...
56def load_description(
57 source: Union[PermissiveFileSource, ZipFile],
58 /,
59 *,
60 format_version: Union[FormatVersionPlaceholder, str] = DISCOVER,
61 perform_io_checks: Optional[bool] = None,
62 known_files: Optional[Dict[str, Optional[Sha256]]] = None,
63 sha256: Optional[Sha256] = None,
64) -> Union[ResourceDescr, InvalidDescr]:
65 """load a bioimage.io resource description
67 Args:
68 source: Path or URL to an rdf.yaml or a bioimage.io package
69 (zip-file with rdf.yaml in it).
70 format_version: (optional) Use this argument to load the resource and
71 convert its metadata to a higher format_version.
72 perform_io_checks: Wether or not to perform validation that requires file io,
73 e.g. downloading a remote files. The existence of local
74 absolute file paths is still being checked.
75 known_files: Allows to bypass download and hashing of referenced files
76 (even if perform_io_checks is True).
77 Checked files will be added to this dictionary
78 with their SHA-256 value.
79 sha256: Optional SHA-256 value of **source**
81 Returns:
82 An object holding all metadata of the bioimage.io resource
84 """
85 if isinstance(source, ResourceDescrBase):
86 name = getattr(source, "name", f"{str(source)[:10]}...")
87 logger.warning("returning already loaded description '{}' as is", name)
88 return source # pyright: ignore[reportReturnType]
90 opened = open_bioimageio_yaml(source, sha256=sha256)
92 context = get_validation_context().replace(
93 root=opened.original_root,
94 file_name=opened.original_file_name,
95 perform_io_checks=perform_io_checks,
96 known_files=known_files,
97 )
99 return build_description(
100 opened.content,
101 context=context,
102 format_version=format_version,
103 )
106@overload
107def load_model_description(
108 source: Union[PermissiveFileSource, ZipFile],
109 /,
110 *,
111 format_version: Literal["latest"],
112 perform_io_checks: Optional[bool] = None,
113 known_files: Optional[Dict[str, Optional[Sha256]]] = None,
114 sha256: Optional[Sha256] = None,
115) -> ModelDescr: ...
118@overload
119def load_model_description(
120 source: Union[PermissiveFileSource, ZipFile],
121 /,
122 *,
123 format_version: Union[FormatVersionPlaceholder, str] = DISCOVER,
124 perform_io_checks: Optional[bool] = None,
125 known_files: Optional[Dict[str, Optional[Sha256]]] = None,
126 sha256: Optional[Sha256] = None,
127) -> AnyModelDescr: ...
130def load_model_description(
131 source: Union[PermissiveFileSource, ZipFile],
132 /,
133 *,
134 format_version: Union[FormatVersionPlaceholder, str] = DISCOVER,
135 perform_io_checks: Optional[bool] = None,
136 known_files: Optional[Dict[str, Optional[Sha256]]] = None,
137 sha256: Optional[Sha256] = None,
138) -> AnyModelDescr:
139 """same as `load_description`, but addtionally ensures that the loaded
140 description is valid and of type 'model'.
142 Raises:
143 ValueError: for invalid or non-model resources
144 """
145 rd = load_description(
146 source,
147 format_version=format_version,
148 perform_io_checks=perform_io_checks,
149 known_files=known_files,
150 sha256=sha256,
151 )
152 return ensure_description_is_model(rd)
155@overload
156def load_dataset_description(
157 source: Union[PermissiveFileSource, ZipFile],
158 /,
159 *,
160 format_version: Literal["latest"],
161 perform_io_checks: Optional[bool] = None,
162 known_files: Optional[Dict[str, Optional[Sha256]]] = None,
163 sha256: Optional[Sha256] = None,
164) -> DatasetDescr: ...
167@overload
168def load_dataset_description(
169 source: Union[PermissiveFileSource, ZipFile],
170 /,
171 *,
172 format_version: Union[FormatVersionPlaceholder, str] = DISCOVER,
173 perform_io_checks: Optional[bool] = None,
174 known_files: Optional[Dict[str, Optional[Sha256]]] = None,
175 sha256: Optional[Sha256] = None,
176) -> AnyDatasetDescr: ...
179def load_dataset_description(
180 source: Union[PermissiveFileSource, ZipFile],
181 /,
182 *,
183 format_version: Union[FormatVersionPlaceholder, str] = DISCOVER,
184 perform_io_checks: Optional[bool] = None,
185 known_files: Optional[Dict[str, Optional[Sha256]]] = None,
186 sha256: Optional[Sha256] = None,
187) -> AnyDatasetDescr:
188 """same as `load_description`, but addtionally ensures that the loaded
189 description is valid and of type 'dataset'.
190 """
191 rd = load_description(
192 source,
193 format_version=format_version,
194 perform_io_checks=perform_io_checks,
195 known_files=known_files,
196 sha256=sha256,
197 )
198 return ensure_description_is_dataset(rd)
201def save_bioimageio_yaml_only(
202 rd: Union[ResourceDescr, BioimageioYamlContent, InvalidDescr],
203 /,
204 file: Union[NewPath, FilePath, TextIO],
205 *,
206 exclude_unset: bool = True,
207 exclude_defaults: bool = False,
208):
209 """write the metadata of a resource description (`rd`) to `file`
210 without writing any of the referenced files in it.
212 Args:
213 rd: bioimageio resource description
214 file: file or stream to save to
215 exclude_unset: Exclude fields that have not explicitly be set.
216 exclude_defaults: Exclude fields that have the default value (even if set explicitly).
218 Note: To save a resource description with its associated files as a package,
219 use `save_bioimageio_package` or `save_bioimageio_package_as_folder`.
220 """
221 if isinstance(rd, ResourceDescrBase):
222 content = dump_description(
223 rd, exclude_unset=exclude_unset, exclude_defaults=exclude_defaults
224 )
225 else:
226 content = rd
228 write_yaml(cast(YamlValue, content), file)
231def load_description_and_validate_format_only(
232 source: Union[PermissiveFileSource, ZipFile],
233 /,
234 *,
235 format_version: Union[FormatVersionPlaceholder, str] = DISCOVER,
236 perform_io_checks: Optional[bool] = None,
237 known_files: Optional[Dict[str, Optional[Sha256]]] = None,
238 sha256: Optional[Sha256] = None,
239) -> ValidationSummary:
240 """same as `load_description`, but only return the validation summary.
242 Returns:
243 Validation summary of the bioimage.io resource found at `source`.
245 """
246 rd = load_description(
247 source,
248 format_version=format_version,
249 perform_io_checks=perform_io_checks,
250 known_files=known_files,
251 sha256=sha256,
252 )
253 assert rd.validation_summary is not None
254 return rd.validation_summary
257def update_format(
258 source: Union[
259 ResourceDescr,
260 PermissiveFileSource,
261 ZipFile,
262 BioimageioYamlContent,
263 InvalidDescr,
264 ],
265 /,
266 *,
267 output: Union[Path, TextIO, None] = None,
268 exclude_defaults: bool = True,
269 perform_io_checks: Optional[bool] = None,
270) -> Union[LatestResourceDescr, InvalidDescr]:
271 """Update a resource description.
273 Notes:
274 - Invalid **source** descriptions may fail to update.
275 - The updated description might be invalid (even if the **source** was valid).
276 """
278 if isinstance(source, ResourceDescrBase):
279 root = source.root
280 source = dump_description(source)
281 else:
282 root = None
284 if isinstance(source, collections.abc.Mapping):
285 descr = build_description(
286 source,
287 context=get_validation_context().replace(
288 root=root, perform_io_checks=perform_io_checks
289 ),
290 format_version=LATEST,
291 )
293 else:
294 descr = load_description(
295 source,
296 perform_io_checks=perform_io_checks,
297 format_version=LATEST,
298 )
300 if output is not None:
301 save_bioimageio_yaml_only(descr, file=output, exclude_defaults=exclude_defaults)
303 return descr
306def update_hashes(
307 source: Union[PermissiveFileSource, ZipFile, ResourceDescr, BioimageioYamlContent],
308 /,
309) -> Union[ResourceDescr, InvalidDescr]:
310 """Update hash values of the files referenced in **source**."""
311 if isinstance(source, ResourceDescrBase):
312 root = source.root
313 source = dump_description(source)
314 else:
315 root = None
317 context = get_validation_context().replace(
318 update_hashes=True, root=root, perform_io_checks=True
319 )
320 with context:
321 if isinstance(source, collections.abc.Mapping):
322 return build_description(source)
323 else:
324 return load_description(source, perform_io_checks=True)