Skip to content

Commit 62f7692

Browse files
authored
Merge pull request #699 from bioimage-io/dev
Fix uncached downloads
2 parents a8f4dae + 7a6a73c commit 62f7692

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+1727
-1006
lines changed

.github/workflows/build.yml

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ jobs:
1212
strategy:
1313
fail-fast: false
1414
matrix:
15-
python-version: ["3.8", "3.9", "3.10", "3.11","3.12", "3.13"]
15+
python-version: ["3.9", "3.10", "3.11","3.12", "3.13"]
16+
pydantic-version: ["2.10.3", "2.11.0"]
1617
include:
1718
- python-version: "3.12"
1819
is-dev-version: true
@@ -26,7 +27,7 @@ jobs:
2627
- name: Install dependencies
2728
run: |
2829
pip install --upgrade pip
29-
pip install -e .[dev]
30+
pip install pydantic~=${{matrix.pydantic-version }} -e .[dev]
3031
- name: Get Date
3132
id: get-date
3233
run: |
@@ -41,20 +42,18 @@ jobs:
4142
run: python scripts/generate_version_submodule_imports.py check
4243
- run: black --check .
4344
if: matrix.is-dev-version
44-
- name: install additinal deps for a full pyright check
45-
run: pip install json_schema_for_humans
46-
if: matrix.is-dev-version
4745
- run: ruff check
4846
if: matrix.is-dev-version
49-
- run: pyright --version
47+
- name: Run Pyright
5048
if: matrix.is-dev-version
51-
- run: pyright -p pyproject.toml --pythonversion ${{ matrix.python-version }}
52-
if: matrix.is-dev-version
53-
- run: pytest
49+
run: |
50+
pyright --version
51+
pyright -p pyproject.toml --pythonversion ${{ matrix.python-version }}
52+
- run: pytest --cov bioimageio --cov-report xml --cov-append --capture no
5453
env:
5554
BIOIMAGEIO_CACHE_PATH: bioimageio_cache
5655
RUN_EXPENSIVE_TESTS: ${{ matrix.run-expensive-tests && 'true' || 'false' }}
57-
- run: pytest --cov-append scripts # also test docstrings in scripts for dev-version
56+
- run: pytest --cov bioimageio --cov-report xml --cov-append --capture no scripts # also test docstrings in scripts for dev-version
5857
if: ${{matrix.is-dev-version}}
5958
env:
6059
BIOIMAGEIO_CACHE_PATH: bioimageio_cache
@@ -110,7 +109,6 @@ jobs:
110109
run: python -m interactive_docs
111110
- name: Generate JSON schemas
112111
run: python scripts/generate_json_schemas.py
113-
- run: pip install json_schema_for_humans
114112
- name: Generate JSON schema documentation
115113
run: python scripts/generate_json_schema_documentation.py
116114
- name: Generate developer docs

bioimageio/spec/_description.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
from ._description_impl import DISCOVER, build_description_impl, get_rd_class_impl
1010
from ._internal.common_nodes import InvalidDescr
11-
from ._internal.io import BioimageioYamlContent
11+
from ._internal.io import BioimageioYamlContent, BioimageioYamlContentView
1212
from ._internal.types import FormatVersionPlaceholder
1313
from ._internal.validation_context import get_validation_context
1414
from .application import (
@@ -151,7 +151,7 @@ def _get_rd_class(typ: Any, format_version: Any):
151151

152152
@overload
153153
def build_description(
154-
content: BioimageioYamlContent,
154+
content: BioimageioYamlContentView,
155155
/,
156156
*,
157157
context: Optional[ValidationContext] = None,
@@ -161,7 +161,7 @@ def build_description(
161161

162162
@overload
163163
def build_description(
164-
content: BioimageioYamlContent,
164+
content: BioimageioYamlContentView,
165165
/,
166166
*,
167167
context: Optional[ValidationContext] = None,
@@ -170,7 +170,7 @@ def build_description(
170170

171171

172172
def build_description(
173-
content: BioimageioYamlContent,
173+
content: BioimageioYamlContentView,
174174
/,
175175
*,
176176
context: Optional[ValidationContext] = None,

bioimageio/spec/_description_impl.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
"""implementation details for building a bioimage.io resource description"""
22

3+
import collections.abc
34
from typing import Any, Callable, List, Literal, Mapping, Optional, Type, TypeVar, Union
45

56
from ._internal.common_nodes import InvalidDescr, ResourceDescrBase
6-
from ._internal.io import BioimageioYamlContent
7+
from ._internal.io import BioimageioYamlContentView
78
from ._internal.types import FormatVersionPlaceholder
89
from ._internal.validation_context import ValidationContext, get_validation_context
910
from .summary import (
@@ -48,7 +49,7 @@ def get_rd_class_impl(
4849

4950

5051
def build_description_impl(
51-
content: BioimageioYamlContent,
52+
content: BioimageioYamlContentView,
5253
/,
5354
*,
5455
context: Optional[ValidationContext] = None,
@@ -57,7 +58,7 @@ def build_description_impl(
5758
) -> Union[ResourceDescrT, InvalidDescr]:
5859
context = context or get_validation_context()
5960
errors: List[ErrorEntry] = []
60-
if isinstance(content, dict):
61+
if isinstance(content, collections.abc.Mapping):
6162
for minimum in ("type", "format_version"):
6263
if minimum not in content:
6364
errors.append(

bioimageio/spec/_get_conda_env.py

Lines changed: 12 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,11 @@
33
from typing_extensions import assert_never
44

55
from ._internal.gh_utils import set_github_warning
6-
from ._internal.io_utils import ZipPath, read_yaml
7-
from .common import RelativeFilePath
6+
from ._internal.io import FileDescr, get_reader
7+
from ._internal.io_utils import read_yaml
88
from .conda_env import BioimageioCondaEnv, PipDeps
99
from .model import v0_4, v0_5
1010
from .model.v0_5 import Version
11-
from .utils import download
1211

1312
SupportedWeightsEntry = Union[
1413
v0_4.KerasHdf5WeightsDescr,
@@ -202,35 +201,26 @@ def _get_default_tf_env(tensorflow_version: Optional[Version]) -> BioimageioCond
202201

203202

204203
def _get_env_from_deps(
205-
deps: Union[v0_4.Dependencies, v0_5.EnvironmentFileDescr],
204+
deps: Union[v0_4.Dependencies, FileDescr],
206205
) -> BioimageioCondaEnv:
207206
if isinstance(deps, v0_4.Dependencies):
207+
deps_reader = get_reader(deps.file)
208208
if deps.manager == "pip":
209-
pip_deps_str = download(deps.file).path.read_text(encoding="utf-8")
210-
assert isinstance(pip_deps_str, str)
209+
pip_deps_str = deps_reader.read_text()
211210
pip_deps = [d.strip() for d in pip_deps_str.split("\n")]
212211
if "bioimageio.core" not in pip_deps:
213212
pip_deps.append("bioimageio.core")
214213

215214
return BioimageioCondaEnv(
216215
dependencies=[PipDeps(pip=pip_deps)],
217216
)
218-
elif deps.manager not in ("conda", "mamba"):
219-
raise ValueError(f"Dependency manager {deps.manager} not supported")
217+
elif deps.manager in ("conda", "mamba"):
218+
return BioimageioCondaEnv.model_validate(read_yaml(deps_reader))
220219
else:
221-
deps_source = (
222-
deps.file.absolute()
223-
if isinstance(deps.file, RelativeFilePath)
224-
else deps.file
225-
)
226-
if isinstance(deps_source, ZipPath):
227-
local = deps_source
228-
else:
229-
local = download(deps_source).path
230-
231-
return BioimageioCondaEnv.model_validate(read_yaml(local))
232-
elif isinstance(deps, v0_5.EnvironmentFileDescr):
233-
local = download(deps.source).path
234-
return BioimageioCondaEnv.model_validate(read_yaml(local))
220+
raise ValueError(f"Dependency manager {deps.manager} not supported")
221+
222+
elif isinstance(deps, FileDescr):
223+
deps_reader = deps.get_reader()
224+
return BioimageioCondaEnv.model_validate(read_yaml(deps_reader))
235225
else:
236226
assert_never(deps)

bioimageio/spec/_internal/_settings.py

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
1+
import os
2+
from functools import cached_property
13
from pathlib import Path
24
from typing import Optional, Union
35

46
import pooch # pyright: ignore [reportMissingTypeStubs]
5-
from pydantic import Field
7+
from genericache import DiskCache
8+
from genericache.digest import UrlDigest
9+
from pydantic import Field, field_validator
610
from pydantic_settings import BaseSettings, SettingsConfigDict
711
from typing_extensions import Annotated
812

13+
from .root_url import RootHttpUrl
14+
915

1016
class Settings(BaseSettings, extra="ignore"):
1117
"""environment variables for bioimageio.spec"""
@@ -15,11 +21,16 @@ class Settings(BaseSettings, extra="ignore"):
1521
)
1622

1723
allow_pickle: bool = False
18-
"""Sets the `allow_pickle` argument for `numpy.load()`/`numpy.save()`"""
24+
"""Sets the `allow_pickle` argument for `numpy.load()`"""
1925

2026
cache_path: Path = pooch.os_cache("bioimageio")
2127
"""bioimageio cache location"""
2228

29+
@field_validator("cache_path", mode="after")
30+
@classmethod
31+
def _expand_user(cls, value: Path):
32+
return Path(os.path.expanduser(str(value)))
33+
2334
collection_http_pattern: str = (
2435
"https://hypha.aicell.io/bioimage-io/artifacts/{bioimageio_id}/files/rdf.yaml"
2536
)
@@ -41,20 +52,21 @@ class Settings(BaseSettings, extra="ignore"):
4152
)
4253
"""URL to bioimageio id_map_draft.json to resolve draft IDs ending with '/draft'."""
4354

55+
perform_io_checks: bool = True
56+
"""Wether or not to perform validation that requires file io,
57+
e.g. downloading a remote files.
58+
59+
Existence of any local absolute file paths is still being checked."""
60+
4461
resolve_draft: bool = True
4562
"""Flag to resolve draft resource versions following the pattern
4663
<resource id>/draft.
64+
4765
Note that anyone may stage a new draft and that such a draft version
4866
may not have been reviewed yet.
4967
Set this flag to False to avoid this potential security risk
5068
and disallow loading draft versions."""
5169

52-
perform_io_checks: bool = True
53-
"""Wether or not to perform validation that requires file io,
54-
e.g. downloading a remote files.
55-
56-
Existence of any local absolute file paths is still being checked."""
57-
5870
log_warnings: bool = True
5971
"""Log validation warnings to console."""
6072

@@ -77,6 +89,15 @@ def github_auth(self):
7789
else:
7890
return (self.github_username, self.github_token)
7991

92+
@cached_property
93+
def disk_cache(self):
94+
cache = DiskCache[RootHttpUrl].create(
95+
url_type=RootHttpUrl,
96+
cache_dir=self.cache_path,
97+
url_hasher=UrlDigest.from_str,
98+
)
99+
return cache
100+
80101

81102
settings = Settings()
82103
"""parsed environment variables for bioimageio.spec"""

0 commit comments

Comments
 (0)