Skip to content

Commit 4414212

Browse files
authored
Merge pull request #709 from bioimage-io/dev
Housekeeping
2 parents c4b533c + 41d55dd commit 4414212

18 files changed

+127
-65
lines changed

bioimageio/spec/VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
"version": "0.5.4.3"
2+
"version": "0.5.4.4"
33
}

bioimageio/spec/_internal/common_nodes.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
Any,
1111
ClassVar,
1212
Dict,
13+
Iterable,
1314
List,
1415
Literal,
1516
Mapping,
@@ -149,13 +150,15 @@ def _ignore_future_patch(cls, data: Any, /) -> Any:
149150
@model_validator(mode="after")
150151
def _set_init_validation_summary(self) -> Self:
151152
context = get_validation_context()
153+
152154
self._validation_summary = ValidationSummary(
153155
name="bioimageio format validation",
154156
source_name=context.source_name,
155157
id=getattr(self, "id", None),
156158
type=self.type,
157159
format_version=self.format_version,
158160
status="failed" if isinstance(self, InvalidDescr) else "valid-format",
161+
metadata_completeness=self._get_metadata_completeness(),
159162
details=(
160163
[]
161164
if isinstance(self, InvalidDescr)
@@ -245,6 +248,25 @@ def load(
245248

246249
return rd
247250

251+
def _get_metadata_completeness(self) -> float:
252+
if isinstance(self, InvalidDescr):
253+
return 0.0
254+
255+
given = self.model_dump(mode="json", exclude_unset=True, exclude_defaults=False)
256+
full = self.model_dump(mode="json", exclude_unset=False, exclude_defaults=False)
257+
258+
def extract_flat_keys(d: Dict[Any, Any], key: str = "") -> Iterable[str]:
259+
for k, v in d.items():
260+
if is_dict(v):
261+
yield from extract_flat_keys(v, key=f"{key}.{k}" if key else k)
262+
263+
yield f"{key}.{k}" if key else k
264+
265+
given_keys = set(extract_flat_keys(given))
266+
full_keys = set(extract_flat_keys(full))
267+
assert len(full_keys) >= len(given_keys)
268+
return len(given_keys) / len(full_keys) if full_keys else 0.0
269+
248270
@classmethod
249271
def _load_impl(
250272
cls, data: BioimageioYamlContent

bioimageio/spec/_internal/constants.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -56,29 +56,31 @@ class _DtypeLimit(NamedTuple):
5656
}
5757
)
5858

59-
# TODO: cache/store known gh users in file
60-
KNOWN_GH_USERS: Set[str] = {
61-
"clementcaporal",
62-
"donglaiw",
63-
"jansanrom",
64-
"pedgomgal1",
59+
# TODO: cache/store known GitHub users in file
60+
KNOWN_GITHUB_USERS: Set[str] = {
6561
"aaitorg",
62+
"anwai98",
6663
"bioimageiobot",
6764
"carlosuc3m",
6865
"cfusterbarcelo",
66+
"clementcaporal",
6967
"constantinpape",
7068
"ctr26",
7169
"danifranco",
70+
"donglaiw",
7271
"esgomezm",
7372
"fynnbe",
7473
"githubuser2",
7574
"iarganda",
75+
"ilastik",
7676
"ivanhcenalmor",
7777
"jansanrom",
7878
"k-dominik",
7979
"lenkaback",
8080
"oeway",
81+
"pedgomgal1",
8182
}
82-
N_KNOWN_GH_USERS = len(KNOWN_GH_USERS)
83-
KNOWN_INVALID_GH_USERS: Set[str] = {"arratemunoz", "lmescu"}
84-
N_KNOWN_INVALID_GH_USERS = len(KNOWN_INVALID_GH_USERS)
83+
84+
N_KNOWN_GITHUB_USERS = len(KNOWN_GITHUB_USERS)
85+
KNOWN_INVALID_GITHUB_USERS: Set[str] = {"arratemunoz", "lmescu"}
86+
N_KNOWN_INVALID_GITHUB_USERS = len(KNOWN_INVALID_GITHUB_USERS)

bioimageio/spec/_internal/field_validation.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
import httpx
1313

1414
from ._settings import settings
15-
from .constants import KNOWN_GH_USERS, KNOWN_INVALID_GH_USERS
15+
from .constants import KNOWN_GITHUB_USERS, KNOWN_INVALID_GITHUB_USERS
1616
from .field_warning import issue_warning
1717
from .type_guards import is_mapping, is_sequence, is_tuple
1818
from .validation_context import get_validation_context
@@ -57,18 +57,20 @@ def validate_unique_entries(seq: Sequence[Hashable]):
5757
return seq
5858

5959

60-
def validate_gh_user(username: str, hotfix_known_errorenous_names: bool = True) -> str:
60+
def validate_github_user(
61+
username: str, hotfix_known_errorenous_names: bool = True
62+
) -> str:
6163
if hotfix_known_errorenous_names:
6264
if username == "Constantin Pape":
6365
return "constantinpape"
6466

6567
if (
66-
username.lower() in KNOWN_GH_USERS
68+
username.lower() in KNOWN_GITHUB_USERS
6769
or not get_validation_context().perform_io_checks
6870
):
6971
return username
7072

71-
if username.lower() in KNOWN_INVALID_GH_USERS:
73+
if username.lower() in KNOWN_INVALID_GITHUB_USERS:
7274
raise ValueError(f"Known invalid GitHub user '{username}'")
7375

7476
try:
@@ -89,9 +91,9 @@ def validate_gh_user(username: str, hotfix_known_errorenous_names: bool = True)
8991
value=username,
9092
)
9193
elif r.status_code != 200:
92-
KNOWN_INVALID_GH_USERS.add(username.lower())
94+
KNOWN_INVALID_GITHUB_USERS.add(username.lower())
9395
raise ValueError(f"Could not find GitHub user '{username}'")
9496

95-
KNOWN_GH_USERS.add(username.lower())
97+
KNOWN_GITHUB_USERS.add(username.lower())
9698

9799
return username

bioimageio/spec/_internal/io.py

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -705,18 +705,23 @@ def _open_url(
705705
or hashlib.sha256(str(source).encode(encoding="utf-8")).hexdigest()
706706
)
707707

708-
return BytesReader(
709-
cache.fetch(
708+
try:
709+
reader = cache.fetch(
710710
source,
711711
fetcher=partial(_fetch_url, progressbar=progressbar),
712712
force_refetch=digest,
713-
),
714-
suffix=source_path.suffix,
715-
sha256=sha,
716-
original_file_name=source_path.name,
717-
original_root=source.parent,
718-
is_zipfile=None,
719-
)
713+
)
714+
except Exception as e:
715+
raise ValueError(f"Failed to fetch {source}.") from e
716+
else:
717+
return BytesReader(
718+
reader,
719+
suffix=source_path.suffix,
720+
sha256=sha,
721+
original_file_name=source_path.name,
722+
original_root=source.parent,
723+
is_zipfile=None,
724+
)
720725

721726

722727
def _fetch_url(

bioimageio/spec/conda_env.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ def _ensure_valid_conda_env_name(cls, value: Optional[str]) -> Optional[str]:
5050
def wo_name(self):
5151
return self.model_construct(**{k: v for k, v in self if k != "name"})
5252

53-
def _get_version(self, package: str):
54-
"""Helper to return any verison pin for **package**
53+
def _get_version_pin(self, package: str):
54+
"""Helper to return any version pin for **package**
5555
5656
TODO: improve: interprete version pin and return structured information.
5757
"""
@@ -62,6 +62,10 @@ def _get_version(self, package: str):
6262
return p[len(package) :]
6363
elif d.startswith(package):
6464
return d[len(package) :]
65+
elif "::" in d and (d_wo_channel := d.split("::", 1)[-1]).startswith(
66+
package
67+
):
68+
return d_wo_channel[len(package) :]
6569

6670
def get_pip_deps(self) -> List[str]:
6771
"""Get the pip dependencies of this conda env."""

bioimageio/spec/generic/v0_3.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727

2828
from .._internal.common_nodes import Node, ResourceDescrBase
2929
from .._internal.constants import TAG_CATEGORIES
30-
from .._internal.field_validation import validate_gh_user
30+
from .._internal.field_validation import validate_github_user
3131
from .._internal.field_warning import as_warning, warn
3232
from .._internal.io import (
3333
BioimageioYamlContent,
@@ -112,11 +112,11 @@ class Author(_Author_v0_2):
112112
github_user: Optional[str] = None
113113

114114
@field_validator("github_user", mode="after")
115-
def _validate_gh_user(cls, value: Optional[str]):
115+
def _validate_github_user(cls, value: Optional[str]):
116116
if value is None:
117117
return None
118118
else:
119-
return validate_gh_user(value)
119+
return validate_github_user(value)
120120

121121

122122
class _AuthorConv(Converter[_Author_v0_2, Author]):
@@ -140,8 +140,8 @@ class Maintainer(_Maintainer_v0_2):
140140
github_user: str
141141

142142
@field_validator("github_user", mode="after")
143-
def validate_gh_user(cls, value: str):
144-
return validate_gh_user(value)
143+
def validate_github_user(cls, value: str):
144+
return validate_github_user(value)
145145

146146

147147
class _MaintainerConv(Converter[_Maintainer_v0_2, Maintainer]):

bioimageio/spec/model/v0_5.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
RootModel,
4444
SerializationInfo,
4545
SerializerFunctionWrapHandler,
46+
StrictInt,
4647
Tag,
4748
ValidationInfo,
4849
WrapSerializer,
@@ -382,7 +383,7 @@ class SizeReference(Node):
382383
axis_id: AxisId
383384
"""axis id of the reference axis"""
384385

385-
offset: int = 0
386+
offset: StrictInt = 0
386387

387388
def get_size(
388389
self,
@@ -2488,8 +2489,8 @@ class LinkedModel(LinkedResourceBase):
24882489

24892490

24902491
class _DataDepSize(NamedTuple):
2491-
min: int
2492-
max: Optional[int]
2492+
min: StrictInt
2493+
max: Optional[StrictInt]
24932494

24942495

24952496
class _AxisSizes(NamedTuple):

bioimageio/spec/summary.py

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
no_type_check,
2424
)
2525

26+
import annotated_types
2627
import markdown
2728
import rich.console
2829
import rich.markdown
@@ -36,7 +37,7 @@
3637
model_validator,
3738
)
3839
from pydantic_core.core_schema import ErrorType
39-
from typing_extensions import Self, assert_never
40+
from typing_extensions import Annotated, Self, assert_never
4041

4142
from bioimageio.spec._internal.type_guards import is_dict
4243

@@ -241,25 +242,32 @@ class ValidationSummary(BaseModel, extra="allow"):
241242
for one specific `ResourceDescr` instance."""
242243

243244
name: str
244-
"""name of the validation"""
245+
"""Name of the validation"""
245246
source_name: str
246-
"""source of the validated bioimageio description"""
247+
"""Source of the validated bioimageio description"""
247248
id: Optional[str] = None
248249
"""ID of the resource being validated"""
249250
type: str
250-
"""type of the resource being validated"""
251+
"""Type of the resource being validated"""
251252
format_version: str
252-
"""format version of the resource being validated"""
253+
"""Format version of the resource being validated"""
253254
status: Literal["passed", "valid-format", "failed"]
254255
"""overall status of the bioimageio validation"""
256+
metadata_completeness: Annotated[float, annotated_types.Interval(ge=0, le=1)] = 0.0
257+
"""Estimate of completeness of the metadata in the resource description.
258+
259+
Note: This completeness estimate may change with subsequent releases
260+
and should be considered bioimageio.spec version specific.
261+
"""
262+
255263
details: List[ValidationDetail]
256-
"""list of validation details"""
264+
"""List of validation details"""
257265
env: Set[InstalledPackage] = Field(
258266
default_factory=lambda: {
259267
InstalledPackage(name="bioimageio.spec", version=VERSION)
260268
}
261269
)
262-
"""list of selected, relevant package versions"""
270+
"""List of selected, relevant package versions"""
263271

264272
saved_conda_list: Optional[str] = None
265273

changelog.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,10 @@ In this file we log both:
1010

1111
This changelog includes implementation details and my reference the [changes to the Resource Description Format](#changes-to-the-resource-description-format), e.g. in entry [bioimageio.spec 0.5.2](#bioimageiospec-052).
1212

13-
#### bioimageio.spec (next release)
13+
#### bioimageio.spec 0.5.4.4
1414

1515
- infinity and not-a-number values are no longer allowed (when used in a tensor description under data.range they are replaced with `None`)
16+
- stricter validation of integers; float values no longer allowed for input/output fields `size.offset`, `size.min`, `size.max`
1617

1718
#### bioimageio.spec 0.5.4.3
1819

0 commit comments

Comments
 (0)