Coverage for src/bioimageio/spec/_io.py: 89%

38 statements  

« prev     ^ index     » next       coverage.py v7.15.4, created at 2026-08-18 09:17 +0000

1from __future__ import annotations 

2 

3from typing import Literal, TextIO, cast, overload 

4from zipfile import ZipFile 

5 

6from loguru import logger 

7from pydantic import FilePath, NewPath 

8 

9from ._description import ( 

10 DISCOVER, 

11 InvalidDescr, 

12 LatestResourceDescr, 

13 ResourceDescr, 

14 build_description, 

15 dump_description, 

16 ensure_description_is_dataset, 

17 ensure_description_is_model, 

18) 

19from ._internal.common_nodes import ResourceDescrBase 

20from ._internal.io import BioimageioYamlContent, YamlValue 

21from ._internal.io_basics import Sha256 

22from ._internal.io_utils import open_bioimageio_yaml, write_yaml 

23from ._internal.types import FormatVersionPlaceholder, PermissiveFileSource 

24from ._internal.validation_context import get_validation_context 

25from .dataset import AnyDatasetDescr, DatasetDescr 

26from .model import AnyModelDescr, ModelDescr 

27from .summary import ValidationSummary 

28 

29 

30@overload 

31def load_description( 

32 source: PermissiveFileSource | ZipFile, 

33 /, 

34 *, 

35 format_version: Literal["latest"], 

36 perform_io_checks: bool | None = None, 

37 known_files: dict[str, Sha256 | None] | None = None, 

38 sha256: Sha256 | None = None, 

39) -> LatestResourceDescr | InvalidDescr: ... 

40 

41 

42@overload 

43def load_description( 

44 source: PermissiveFileSource | ZipFile, 

45 /, 

46 *, 

47 format_version: FormatVersionPlaceholder | str = DISCOVER, 

48 perform_io_checks: bool | None = None, 

49 known_files: dict[str, Sha256 | None] | None = None, 

50 sha256: Sha256 | None = None, 

51) -> ResourceDescr | InvalidDescr: ... 

52 

53 

54def load_description( 

55 source: PermissiveFileSource | ZipFile, 

56 /, 

57 *, 

58 format_version: FormatVersionPlaceholder | str = DISCOVER, 

59 perform_io_checks: bool | None = None, 

60 known_files: dict[str, Sha256 | None] | None = None, 

61 sha256: Sha256 | None = None, 

62) -> ResourceDescr | InvalidDescr: 

63 """load a bioimage.io resource description 

64 

65 Args: 

66 source: 

67 Path or URL to an rdf.yaml or a bioimage.io package 

68 (zip-file with rdf.yaml in it). 

69 format_version: 

70 (optional) Use this argument to load the resource and 

71 convert its metadata to a higher format_version. 

72 Note: 

73 - Use "latest" to convert to the latest available format version. 

74 - Use "discover" to use the format version specified in the RDF. 

75 - Only considers major.minor format version, ignores patch version. 

76 - Conversion to lower format versions is not supported. 

77 perform_io_checks: 

78 Wether or not to perform validation that requires file io, 

79 e.g. downloading a remote files. The existence of local 

80 absolute file paths is still being checked. 

81 known_files: 

82 Allows to bypass download and hashing of referenced files 

83 (even if perform_io_checks is True). 

84 

85 Keys should be file paths or URL strings as they appear in the 

86 bioimageio.yaml file. 

87 

88 Values are Sha256 values compared to hash values in the description. 

89 For `None` values no hash value comparison is performed. 

90 

91 If `perfrom_io_checks` is True, checked files will be added to 

92 this dictionary with their SHA-256 value. 

93 

94 If `perform_io_checks` is False and `known_files` is not empty, 

95 missing, 'unknown' file references are considered invalid. 

96 sha256: 

97 Optional SHA-256 value of **source** 

98 

99 Returns: 

100 An object holding all metadata of the bioimage.io resource 

101 

102 """ 

103 if isinstance(source, ResourceDescrBase): 

104 name = getattr(source, "name", f"{str(source)[:10]}...") 

105 logger.warning("returning already loaded description '{}' as is", name) 

106 return source # pyright: ignore[reportReturnType] 

107 

108 opened = open_bioimageio_yaml(source, sha256=sha256) 

109 

110 context = get_validation_context().replace( 

111 root=opened.original_root, 

112 file_name=opened.original_file_name, 

113 original_source_name=opened.original_source_name, 

114 perform_io_checks=perform_io_checks, 

115 known_files=known_files, 

116 ) 

117 

118 return build_description( 

119 opened.content, 

120 context=context, 

121 format_version=format_version, 

122 ) 

123 

124 

125@overload 

126def load_model_description( 

127 source: PermissiveFileSource | ZipFile, 

128 /, 

129 *, 

130 format_version: Literal["latest"], 

131 perform_io_checks: bool | None = None, 

132 known_files: dict[str, Sha256 | None] | None = None, 

133 sha256: Sha256 | None = None, 

134) -> ModelDescr: ... 

135 

136 

137@overload 

138def load_model_description( 

139 source: PermissiveFileSource | ZipFile, 

140 /, 

141 *, 

142 format_version: FormatVersionPlaceholder | str = DISCOVER, 

143 perform_io_checks: bool | None = None, 

144 known_files: dict[str, Sha256 | None] | None = None, 

145 sha256: Sha256 | None = None, 

146) -> AnyModelDescr: ... 

147 

148 

149def load_model_description( 

150 source: PermissiveFileSource | ZipFile, 

151 /, 

152 *, 

153 format_version: FormatVersionPlaceholder | str = DISCOVER, 

154 perform_io_checks: bool | None = None, 

155 known_files: dict[str, Sha256 | None] | None = None, 

156 sha256: Sha256 | None = None, 

157) -> AnyModelDescr: 

158 """same as `load_description`, but addtionally ensures that the loaded 

159 description is valid and of type 'model'. 

160 

161 Raises: 

162 ValueError: for invalid or non-model resources 

163 """ 

164 rd = load_description( 

165 source, 

166 format_version=format_version, 

167 perform_io_checks=perform_io_checks, 

168 known_files=known_files, 

169 sha256=sha256, 

170 ) 

171 return ensure_description_is_model(rd) 

172 

173 

174@overload 

175def load_dataset_description( 

176 source: PermissiveFileSource | ZipFile, 

177 /, 

178 *, 

179 format_version: Literal["latest"], 

180 perform_io_checks: bool | None = None, 

181 known_files: dict[str, Sha256 | None] | None = None, 

182 sha256: Sha256 | None = None, 

183) -> DatasetDescr: ... 

184 

185 

186@overload 

187def load_dataset_description( 

188 source: PermissiveFileSource | ZipFile, 

189 /, 

190 *, 

191 format_version: FormatVersionPlaceholder | str = DISCOVER, 

192 perform_io_checks: bool | None = None, 

193 known_files: dict[str, Sha256 | None] | None = None, 

194 sha256: Sha256 | None = None, 

195) -> AnyDatasetDescr: ... 

196 

197 

198def load_dataset_description( 

199 source: PermissiveFileSource | ZipFile, 

200 /, 

201 *, 

202 format_version: FormatVersionPlaceholder | str = DISCOVER, 

203 perform_io_checks: bool | None = None, 

204 known_files: dict[str, Sha256 | None] | None = None, 

205 sha256: Sha256 | None = None, 

206) -> AnyDatasetDescr: 

207 """same as `load_description`, but addtionally ensures that the loaded 

208 description is valid and of type 'dataset'. 

209 """ 

210 rd = load_description( 

211 source, 

212 format_version=format_version, 

213 perform_io_checks=perform_io_checks, 

214 known_files=known_files, 

215 sha256=sha256, 

216 ) 

217 return ensure_description_is_dataset(rd) 

218 

219 

220def save_bioimageio_yaml_only( 

221 rd: ResourceDescr | BioimageioYamlContent | InvalidDescr, 

222 /, 

223 file: NewPath | FilePath | TextIO, 

224 *, 

225 exclude_unset: bool = True, 

226 exclude_defaults: bool = False, 

227): 

228 """write the metadata of a resource description (`rd`) to `file` 

229 without writing any of the referenced files in it. 

230 

231 Args: 

232 rd: bioimageio resource description 

233 file: file or stream to save to 

234 exclude_unset: Exclude fields that have not explicitly be set. 

235 exclude_defaults: Exclude fields that have the default value (even if set explicitly). 

236 

237 Note: To save a resource description with its associated files as a package, 

238 use `save_bioimageio_package` or `save_bioimageio_package_as_folder`. 

239 """ 

240 if isinstance(rd, ResourceDescrBase): 

241 content = dump_description( 

242 rd, exclude_unset=exclude_unset, exclude_defaults=exclude_defaults 

243 ) 

244 else: 

245 content = rd 

246 

247 write_yaml(cast(YamlValue, content), file) 

248 

249 

250def load_description_and_validate_format_only( 

251 source: PermissiveFileSource | ZipFile, 

252 /, 

253 *, 

254 format_version: FormatVersionPlaceholder | str = DISCOVER, 

255 perform_io_checks: bool | None = None, 

256 known_files: dict[str, Sha256 | None] | None = None, 

257 sha256: Sha256 | None = None, 

258) -> ValidationSummary: 

259 """same as `load_description`, but only return the validation summary. 

260 

261 Returns: 

262 Validation summary of the bioimage.io resource found at `source`. 

263 

264 """ 

265 rd = load_description( 

266 source, 

267 format_version=format_version, 

268 perform_io_checks=perform_io_checks, 

269 known_files=known_files, 

270 sha256=sha256, 

271 ) 

272 assert rd.validation_summary is not None 

273 return rd.validation_summary