Skip to content

Commit b80e0b9

Browse files
authored
Merge pull request #191 from bioimage-io/refactor_io
refactor some io functionality to spec
2 parents 4fdbf4c + 2c1db80 commit b80e0b9

File tree

7 files changed

+36
-352
lines changed

7 files changed

+36
-352
lines changed

bioimageio/core/build_spec/build_model.py

+6-3
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
import bioimageio.spec.model as model_spec
1313
from bioimageio.core import export_resource_package, load_raw_resource_description
1414
from bioimageio.core.resource_io.nodes import URI
15-
from bioimageio.core.resource_io.utils import resolve_local_source, resolve_source
1615
from bioimageio.spec.shared.raw_nodes import ImportableModule, ImportableSourceFile
16+
from bioimageio.spec.shared.utils import resolve_local_source, resolve_source
1717

1818
try:
1919
from typing import get_args
@@ -81,6 +81,7 @@ def _get_weights(
8181
model_kwargs=None,
8282
tensorflow_version=None,
8383
opset_version=None,
84+
dependencies=None,
8485
**kwargs,
8586
):
8687
weight_path = resolve_source(original_weight_source, root)
@@ -100,6 +101,8 @@ def _get_weights(
100101
weights = model_spec.raw_nodes.PytorchStateDictWeightsEntry(
101102
source=weight_source, sha256=weight_hash, **weight_kwargs
102103
)
104+
if dependencies is not None:
105+
weight_kwargs["dependencies"] = _get_dependencies(dependencies, root)
103106

104107
elif weight_type == "onnx":
105108
if opset_version is None:
@@ -745,6 +748,7 @@ def build_model(
745748
model_kwargs,
746749
tensorflow_version=tensorflow_version,
747750
opset_version=opset_version,
751+
dependencies=dependencies,
748752
**weight_kwargs,
749753
)
750754

@@ -813,8 +817,7 @@ def build_model(
813817

814818
if attachments is not None:
815819
kwargs["attachments"] = spec.rdf.raw_nodes.Attachments(**attachments)
816-
if dependencies is not None:
817-
kwargs["dependencies"] = _get_dependencies(dependencies, root)
820+
818821
if maintainers is not None:
819822
kwargs["maintainers"] = [model_spec.raw_nodes.Maintainer(**m) for m in maintainers]
820823
if parent is not None:
+3-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
import bioimageio.spec
12
from .io_ import (
23
export_resource_package,
3-
load_raw_resource_description,
44
load_resource_description,
55
save_raw_resource_description,
66
serialize_raw_resource_description,
77
)
8+
9+
load_raw_resource_description = bioimageio.spec.load_raw_resource_description

bioimageio/core/resource_io/io_.py

+10-102
Original file line numberDiff line numberDiff line change
@@ -1,121 +1,24 @@
11
import os
22
import pathlib
3-
import warnings
4-
import zipfile
53
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
85
from zipfile import ZIP_DEFLATED, ZipFile
96

107
from marshmallow import missing
118

129
from bioimageio import spec
1310
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
1512
from bioimageio.spec.shared import raw_nodes
1613
from bioimageio.spec.shared.common import BIOIMAGEIO_CACHE_PATH, get_class_name_from_type
1714
from bioimageio.spec.shared.raw_nodes import ResourceDescription as RawResourceDescription
18-
from bioimageio.spec.shared.utils import PathToRemoteUriTransformer
1915
from . import nodes
2016
from .utils import resolve_raw_resource_description, resolve_source
2117

2218
serialize_raw_resource_description = spec.io_.serialize_raw_resource_description
2319
save_raw_resource_description = spec.io_.save_raw_resource_description
2420

2521

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-
11922
def load_resource_description(
12023
source: Union[RawResourceDescription, ResourceDescription, os.PathLike, str, dict, raw_nodes.URI],
12124
*,
@@ -152,20 +55,23 @@ def load_resource_description(
15255

15356

15457
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,
15661
) -> Dict[str, Union[pathlib.Path, str]]:
15762
"""
15863
15964
Args:
16065
source: raw resource description
16166
weights_priority_order: If given only the first weights format present in the model is included.
16267
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.
16369
16470
Returns:
16571
Package content of local file paths or text content keyed by file names.
16672
16773
"""
168-
raw_rd = load_raw_resource_description(source)
74+
raw_rd = load_raw_resource_description(source, update_to_format=update_to_format)
16975
package_content = spec.get_resource_package_content(raw_rd, weights_priority_order=weights_priority_order)
17076

17177
local_package_content = {}
@@ -205,7 +111,9 @@ def export_resource_package(
205111
path to zipped BioImage.IO package in BIOIMAGEIO_CACHE_PATH or 'output_path'
206112
"""
207113
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+
)
209117
if output_path is None:
210118
package_path = _get_tmp_package_path(raw_rd, weights_priority_order)
211119
else:

bioimageio/core/resource_io/nodes.py

-14
Original file line numberDiff line numberDiff line change
@@ -42,20 +42,6 @@ class Dependencies(Node, raw_nodes.Dependencies):
4242
file: pathlib.Path = missing
4343

4444

45-
@dataclass
46-
class LocalImportableModule(Node, raw_nodes.ImportableModule):
47-
"""intermediate between raw_nodes.ImportableModule and nodes.ImportedSource. Used by SourceNodeTransformer"""
48-
49-
root_path: pathlib.Path = missing
50-
51-
52-
@dataclass
53-
class ResolvedImportableSourceFile(Node, raw_nodes.ImportableSourceFile):
54-
"""intermediate between raw_nodes.ImportableSourceFile and nodes.ImportedSource. Used by SourceNodeTransformer"""
55-
56-
source_file: pathlib.Path = missing
57-
58-
5945
@dataclass
6046
class CiteEntry(Node, rdf_raw_nodes.CiteEntry):
6147
pass

0 commit comments

Comments
 (0)