|
1 | 1 | import os
|
2 | 2 | import pathlib
|
3 |
| -import warnings |
4 |
| -import zipfile |
5 | 3 | from copy import deepcopy
|
6 |
| -from hashlib import sha256 |
7 |
| -from typing import Dict, IO, Optional, Sequence, Tuple, Union |
| 4 | +from typing import Dict, Optional, Sequence, Union |
8 | 5 | from zipfile import ZIP_DEFLATED, ZipFile
|
9 | 6 |
|
10 | 7 | from marshmallow import missing
|
11 | 8 |
|
12 | 9 | from bioimageio import spec
|
13 | 10 | from bioimageio.core.resource_io.nodes import ResourceDescription
|
14 |
| -from bioimageio.spec.io_ import RDF_NAMES, resolve_rdf_source |
| 11 | +from bioimageio.spec import load_raw_resource_description |
15 | 12 | from bioimageio.spec.shared import raw_nodes
|
16 | 13 | from bioimageio.spec.shared.common import BIOIMAGEIO_CACHE_PATH, get_class_name_from_type
|
17 | 14 | from bioimageio.spec.shared.raw_nodes import ResourceDescription as RawResourceDescription
|
18 |
| -from bioimageio.spec.shared.utils import PathToRemoteUriTransformer |
19 | 15 | from . import nodes
|
20 | 16 | from .utils import resolve_raw_resource_description, resolve_source
|
21 | 17 |
|
22 | 18 | serialize_raw_resource_description = spec.io_.serialize_raw_resource_description
|
23 | 19 | save_raw_resource_description = spec.io_.save_raw_resource_description
|
24 | 20 |
|
25 | 21 |
|
26 |
| -def extract_resource_package( |
27 |
| - source: Union[os.PathLike, IO, str, bytes, raw_nodes.URI] |
28 |
| -) -> Tuple[dict, str, pathlib.Path]: |
29 |
| - """extract a zip source to BIOIMAGEIO_CACHE_PATH""" |
30 |
| - source, source_name, root = resolve_rdf_source(source) |
31 |
| - if isinstance(root, bytes): |
32 |
| - raise NotImplementedError("package source was bytes") |
33 |
| - |
34 |
| - cache_folder = BIOIMAGEIO_CACHE_PATH / "extracted_packages" |
35 |
| - cache_folder.mkdir(exist_ok=True, parents=True) |
36 |
| - |
37 |
| - package_path = cache_folder / sha256(str(root).encode("utf-8")).hexdigest() |
38 |
| - if isinstance(root, raw_nodes.URI): |
39 |
| - for rdf_name in RDF_NAMES: |
40 |
| - if (package_path / rdf_name).exists(): |
41 |
| - download = None |
42 |
| - break |
43 |
| - else: |
44 |
| - download = resolve_source(root) |
45 |
| - |
46 |
| - local_source = download |
47 |
| - else: |
48 |
| - download = None |
49 |
| - local_source = root |
50 |
| - |
51 |
| - if local_source is not None: |
52 |
| - with zipfile.ZipFile(local_source) as zf: |
53 |
| - zf.extractall(package_path) |
54 |
| - |
55 |
| - for rdf_name in RDF_NAMES: |
56 |
| - if (package_path / rdf_name).exists(): |
57 |
| - break |
58 |
| - else: |
59 |
| - raise FileNotFoundError(f"Missing 'rdf.yaml' in {root} extracted from {download}") |
60 |
| - |
61 |
| - if download is not None: |
62 |
| - try: |
63 |
| - os.remove(download) |
64 |
| - except Exception as e: |
65 |
| - warnings.warn(f"Could not remove download {download} due to {e}") |
66 |
| - |
67 |
| - assert isinstance(package_path, pathlib.Path) |
68 |
| - return source, source_name, package_path |
69 |
| - |
70 |
| - |
71 |
| -def _replace_relative_paths_for_remote_source( |
72 |
| - raw_rd: RawResourceDescription, root: Union[pathlib.Path, raw_nodes.URI, bytes] |
73 |
| -) -> RawResourceDescription: |
74 |
| - if isinstance(root, raw_nodes.URI): |
75 |
| - # for a remote source relative paths are invalid; replace all relative file paths in source with URLs |
76 |
| - warnings.warn( |
77 |
| - f"changing file paths in RDF to URIs due to a remote {root.scheme} source " |
78 |
| - "(may result in an invalid node)" |
79 |
| - ) |
80 |
| - raw_rd = PathToRemoteUriTransformer(remote_source=root).transform(raw_rd) |
81 |
| - root_path = pathlib.Path() # root_path cannot be URI |
82 |
| - elif isinstance(root, pathlib.Path): |
83 |
| - if zipfile.is_zipfile(root): |
84 |
| - _, _, root_path = extract_resource_package(root) |
85 |
| - else: |
86 |
| - root_path = root |
87 |
| - elif isinstance(root, bytes): |
88 |
| - raise NotImplementedError("root as bytes (io)") |
89 |
| - else: |
90 |
| - raise TypeError(root) |
91 |
| - |
92 |
| - assert isinstance(root_path, pathlib.Path) |
93 |
| - raw_rd.root_path = root_path.resolve() |
94 |
| - return raw_rd |
95 |
| - |
96 |
| - |
97 |
| -def load_raw_resource_description( |
98 |
| - source: Union[dict, os.PathLike, IO, str, bytes, raw_nodes.URI, RawResourceDescription], |
99 |
| - update_to_format: Optional[str] = "latest", |
100 |
| -) -> RawResourceDescription: |
101 |
| - """load a raw python representation from a BioImage.IO resource description file (RDF). |
102 |
| - Use `load_resource_description` for a more convenient representation. |
103 |
| -
|
104 |
| - Args: |
105 |
| - source: resource description file (RDF) |
106 |
| - update_to_format: update resource to specific "major.minor" or "latest" format version; ignoring patch version. |
107 |
| -
|
108 |
| - Returns: |
109 |
| - raw BioImage.IO resource |
110 |
| - """ |
111 |
| - if isinstance(source, RawResourceDescription): |
112 |
| - return source |
113 |
| - |
114 |
| - raw_rd = spec.load_raw_resource_description(source, update_to_format=update_to_format) |
115 |
| - raw_rd = _replace_relative_paths_for_remote_source(raw_rd, raw_rd.root_path) |
116 |
| - return raw_rd |
117 |
| - |
118 |
| - |
119 | 22 | def load_resource_description(
|
120 | 23 | source: Union[RawResourceDescription, ResourceDescription, os.PathLike, str, dict, raw_nodes.URI],
|
121 | 24 | *,
|
@@ -152,20 +55,23 @@ def load_resource_description(
|
152 | 55 |
|
153 | 56 |
|
154 | 57 | def get_local_resource_package_content(
|
155 |
| - source: RawResourceDescription, weights_priority_order: Optional[Sequence[Union[str]]] |
| 58 | + source: RawResourceDescription, |
| 59 | + weights_priority_order: Optional[Sequence[Union[str]]], |
| 60 | + update_to_format: Optional[str] = None, |
156 | 61 | ) -> Dict[str, Union[pathlib.Path, str]]:
|
157 | 62 | """
|
158 | 63 |
|
159 | 64 | Args:
|
160 | 65 | source: raw resource description
|
161 | 66 | weights_priority_order: If given only the first weights format present in the model is included.
|
162 | 67 | If none of the prioritized weights formats is found all are included.
|
| 68 | + update_to_format: update resource to specific major.minor format version; ignoring patch version. |
163 | 69 |
|
164 | 70 | Returns:
|
165 | 71 | Package content of local file paths or text content keyed by file names.
|
166 | 72 |
|
167 | 73 | """
|
168 |
| - raw_rd = load_raw_resource_description(source) |
| 74 | + raw_rd = load_raw_resource_description(source, update_to_format=update_to_format) |
169 | 75 | package_content = spec.get_resource_package_content(raw_rd, weights_priority_order=weights_priority_order)
|
170 | 76 |
|
171 | 77 | local_package_content = {}
|
@@ -205,7 +111,9 @@ def export_resource_package(
|
205 | 111 | path to zipped BioImage.IO package in BIOIMAGEIO_CACHE_PATH or 'output_path'
|
206 | 112 | """
|
207 | 113 | raw_rd = load_raw_resource_description(source, update_to_format=update_to_format)
|
208 |
| - package_content = get_local_resource_package_content(raw_rd, weights_priority_order) |
| 114 | + package_content = get_local_resource_package_content( |
| 115 | + raw_rd, weights_priority_order, update_to_format=update_to_format |
| 116 | + ) |
209 | 117 | if output_path is None:
|
210 | 118 | package_path = _get_tmp_package_path(raw_rd, weights_priority_order)
|
211 | 119 | else:
|
|
0 commit comments