Coverage for src / bioimageio / core / _collection.py: 0%
67 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-15 23:26 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-15 23:26 +0000
1"""Collection utilities for bioimageio"""
3import json
4import warnings
5from functools import cache
6from typing import Literal, Mapping, Sequence, TypedDict
8from bioimageio.spec.common import Sha256
9from bioimageio.spec.utils import get_reader
11from ._settings import settings
14class IndexItemVersion(TypedDict):
15 version: str
16 source: str
17 sha256: Sha256
20class IndexItem(TypedDict):
21 id: str
22 type: str
23 versions: Sequence[IndexItemVersion]
26class Index(TypedDict):
27 items: Sequence[IndexItem]
28 total: int
29 count_per_type: Mapping[str, int]
30 timestamp: str
33class IdPartsEntry(TypedDict):
34 nouns: Mapping[str, str]
35 adjectives: Sequence[str]
38class CollectionConfig(TypedDict):
39 id_parts: Mapping[Literal["model", "dataset", "notebook"], IdPartsEntry]
40 reviewers: Mapping[str, Sequence[str]]
43@cache
44def load_json(url: str):
45 reader = get_reader(url)
46 return json.load(reader)
49def load_index() -> Index:
50 return load_json(settings.collection_index_url)
53def load_collection_config() -> CollectionConfig:
54 return load_json(settings.collection_config_url)
57@cache
58def load_hypened_nouns() -> set[str]:
59 """get all nouns with hyphens that could be part of a nickname, e.g. 't-rex'"""
60 return {
61 noun
62 for id_parts in load_collection_config()["id_parts"].values()
63 for noun in id_parts.get("nouns", [])
64 if "-" in noun
65 }
68def lookup_from_index(source: str) -> tuple[str, dict[Literal["sha256"], Sha256]]:
69 index = load_index()
70 if source.startswith("bioimage-io/") and source.count("/") == 2:
71 version = source.split("/")[-1]
72 source = source[: -(len(version) + 1)]
73 else:
74 version = None
76 for item in index["items"]:
77 if item["id"] in (source, f"bioimage-io/{source}"):
78 v = item["versions"][-1]
79 if version is not None:
80 for v in item["versions"]:
81 if v["version"] == version:
82 break
83 else:
84 warnings.warn(
85 f"Version {version} not found in index, using latest version."
86 )
87 else:
88 continue
90 return v["source"], {"sha256": v["sha256"]}
92 return source, {}
95def get_resource_icon(nickname: str, rtype: str) -> str:
96 """Get emoji for a resource, matching to its nickname noun. nicknames are of the form "{adjective}-{noun}", e.g. "affable-shark"."""
97 if "-" not in nickname:
98 return " "
100 # remove hyphen from noun part of nickname, e.g. "laid-back-t-rex" -> "laid-back-trex"
101 for hyphened_noun in load_hypened_nouns():
102 if nickname.endswith(hyphened_noun):
103 nickname = nickname[: -len(hyphened_noun)] + hyphened_noun.replace("-", "")
105 # last hyphen now sparates adjective and noun, e.g. "laid-back-trex" -> "laid-back" and "trex"
106 noun = nickname[nickname.rfind("-") + 1 :].replace("-", "")
107 try:
108 ret = {
109 k.replace("-", ""): v
110 for k, v in load_collection_config()["id_parts"][
111 rtype if rtype in ("model", "dataset", "notebook") else "notebook"
112 ]
113 .get("nouns", {})
114 .items()
115 }.get(noun, " ")
116 except Exception as e:
117 warnings.warn(f"Error getting icon for {rtype} {nickname}: {e}")
118 ret = " "
120 return ret