bioimageio.spec.generic.v0_3
1from __future__ import annotations 2 3import string 4from functools import partial 5from typing import ( 6 Any, 7 ClassVar, 8 Dict, 9 List, 10 Literal, 11 Optional, 12 Sequence, 13 Type, 14 TypeVar, 15 Union, 16) 17 18import annotated_types 19from annotated_types import Len, LowerCase, MaxLen, MinLen 20from pydantic import Field, RootModel, ValidationInfo, field_validator, model_validator 21from typing_extensions import Annotated 22 23from .._internal.common_nodes import ( 24 Converter, 25 Node, 26 ResourceDescrBase, 27) 28from .._internal.constants import ( 29 TAG_CATEGORIES, 30) 31from .._internal.field_validation import validate_gh_user 32from .._internal.field_warning import as_warning, warn 33from .._internal.io import ( 34 BioimageioYamlContent, 35 V_suffix, 36 YamlValue, 37 include_in_package_serializer, 38 validate_suffix, 39) 40from .._internal.io import FileDescr as FileDescr 41from .._internal.io_basics import AbsoluteFilePath 42from .._internal.io_basics import Sha256 as Sha256 43from .._internal.license_id import DeprecatedLicenseId as DeprecatedLicenseId 44from .._internal.license_id import LicenseId as LicenseId 45from .._internal.types import ( 46 ImportantFileSource, 47 NotEmpty, 48) 49from .._internal.types import RelativeFilePath as RelativeFilePath 50from .._internal.url import HttpUrl as HttpUrl 51from .._internal.validated_string import ValidatedString 52from .._internal.validator_annotations import ( 53 AfterValidator, 54 Predicate, 55 RestrictCharacters, 56) 57from .._internal.version_type import Version as Version 58from .._internal.warning_levels import ALERT, INFO 59from ._v0_3_converter import convert_from_older_format 60from .v0_2 import Author as _Author_v0_2 61from .v0_2 import BadgeDescr as BadgeDescr 62from .v0_2 import CoverImageSource 63from .v0_2 import Doi as Doi 64from .v0_2 import Maintainer as _Maintainer_v0_2 65from .v0_2 import OrcidId as OrcidId 66from .v0_2 import Uploader as Uploader 67 68KNOWN_SPECIFIC_RESOURCE_TYPES = ( 69 "application", 70 "collection", 71 "dataset", 72 "model", 73 "notebook", 74) 75VALID_COVER_IMAGE_EXTENSIONS = ( 76 ".gif", 77 ".jpeg", 78 ".jpg", 79 ".png", 80 ".svg", 81) 82 83 84class ResourceId(ValidatedString): 85 root_model: ClassVar[Type[RootModel[Any]]] = RootModel[ 86 Annotated[ 87 NotEmpty[str], 88 RestrictCharacters(string.ascii_lowercase + string.digits + "_-/."), 89 annotated_types.Predicate( 90 lambda s: not (s.startswith("/") or s.endswith("/")) 91 ), 92 ] 93 ] 94 95 96def _validate_md_suffix(value: V_suffix) -> V_suffix: 97 return validate_suffix(value, suffix=".md", case_sensitive=True) 98 99 100DocumentationSource = Annotated[ 101 Union[AbsoluteFilePath, RelativeFilePath, HttpUrl], 102 Field(union_mode="left_to_right"), 103 AfterValidator(_validate_md_suffix), 104 include_in_package_serializer, 105] 106 107 108def _has_no_slash(s: str) -> bool: 109 return "/" not in s and "\\" not in s 110 111 112class Author(_Author_v0_2): 113 name: Annotated[str, Predicate(_has_no_slash)] 114 github_user: Optional[str] = None 115 116 @field_validator("github_user", mode="after") 117 def _validate_gh_user(cls, value: Optional[str]): 118 if value is None: 119 return None 120 else: 121 return validate_gh_user(value) 122 123 124class _AuthorConv(Converter[_Author_v0_2, Author]): 125 def _convert( 126 self, src: _Author_v0_2, tgt: "type[Author] | type[dict[str, Any]]" 127 ) -> "Author | dict[str, Any]": 128 return tgt( 129 name=src.name, 130 github_user=src.github_user, 131 affiliation=src.affiliation, 132 email=src.email, 133 orcid=src.orcid, 134 ) 135 136 137_author_conv = _AuthorConv(_Author_v0_2, Author) 138 139 140class Maintainer(_Maintainer_v0_2): 141 name: Optional[Annotated[str, Predicate(_has_no_slash)]] = None 142 github_user: str 143 144 @field_validator("github_user", mode="after") 145 def validate_gh_user(cls, value: str): 146 return validate_gh_user(value) 147 148 149class _MaintainerConv(Converter[_Maintainer_v0_2, Maintainer]): 150 def _convert( 151 self, src: _Maintainer_v0_2, tgt: "type[Maintainer | dict[str, Any]]" 152 ) -> "Maintainer | dict[str, Any]": 153 return tgt( 154 name=src.name, 155 github_user=src.github_user, 156 affiliation=src.affiliation, 157 email=src.email, 158 orcid=src.orcid, 159 ) 160 161 162_maintainer_conv = _MaintainerConv(_Maintainer_v0_2, Maintainer) 163 164 165class CiteEntry(Node): 166 text: str 167 """free text description""" 168 169 doi: Optional[Doi] = None 170 """A digital object identifier (DOI) is the prefered citation reference. 171 See https://www.doi.org/ for details. (alternatively specify `url`)""" 172 173 url: Optional[HttpUrl] = None 174 """URL to cite (preferably specify a `doi` instead)""" 175 176 @model_validator(mode="after") 177 def _check_doi_or_url(self): 178 if not self.doi and not self.url: 179 raise ValueError("Either 'doi' or 'url' is required") 180 181 return self 182 183 184class LinkedResource(Node): 185 """Reference to a bioimage.io resource""" 186 187 id: ResourceId 188 """A valid resource `id` from the official bioimage.io collection.""" 189 190 191class GenericModelDescrBase(ResourceDescrBase): 192 """Base for all resource descriptions including of model descriptions""" 193 194 name: Annotated[ 195 Annotated[ 196 str, RestrictCharacters(string.ascii_letters + string.digits + "_- ()") 197 ], 198 MinLen(5), 199 MaxLen(128), 200 warn(MaxLen(64), "Name longer than 64 characters.", INFO), 201 ] 202 name: Annotated[NotEmpty[str], MaxLen(128)] 203 """A human-friendly name of the resource description. 204 May only contains letters, digits, underscore, minus, parentheses and spaces.""" 205 206 description: Annotated[ 207 str, MaxLen(1024), warn(MaxLen(512), "Description longer than 512 characters.") 208 ] 209 """A string containing a brief description.""" 210 211 covers: Annotated[ 212 List[CoverImageSource], 213 Field( 214 examples=[], 215 description=( 216 "Cover images. Please use an image smaller than 500KB and an aspect" 217 " ratio width to height of 2:1 or 1:1.\nThe supported image formats" 218 f" are: {VALID_COVER_IMAGE_EXTENSIONS}" 219 ), 220 ), 221 ] = Field(default_factory=list) 222 """∈📦 Cover images.""" 223 224 id_emoji: Optional[Annotated[str, Len(min_length=1, max_length=2)]] = None 225 """UTF-8 emoji for display alongside the `id`.""" 226 227 authors: NotEmpty[List[Author]] 228 """The authors are the creators of this resource description and the primary points of contact.""" 229 230 attachments: List[FileDescr] = Field(default_factory=list) 231 """file attachments""" 232 233 cite: NotEmpty[List[CiteEntry]] 234 """citations""" 235 236 license: Annotated[ 237 Annotated[ 238 Union[LicenseId, DeprecatedLicenseId], Field(union_mode="left_to_right") 239 ], 240 warn( 241 LicenseId, 242 "{value} is deprecated, see https://spdx.org/licenses/{value}.html", 243 ), 244 Field(examples=["CC0-1.0", "MIT", "BSD-2-Clause"]), 245 ] 246 """A [SPDX license identifier](https://spdx.org/licenses/). 247 We do not support custom license beyond the SPDX license list, if you need that please 248 [open a GitHub issue](https://github.com/bioimage-io/spec-bioimage-io/issues/new/choose) 249 to discuss your intentions with the community.""" 250 251 config: Annotated[ 252 Dict[str, YamlValue], 253 Field( 254 examples=[ 255 dict( 256 bioimageio={ 257 "my_custom_key": 3837283, 258 "another_key": {"nested": "value"}, 259 }, 260 imagej={"macro_dir": "path/to/macro/file"}, 261 ) 262 ], 263 ), 264 ] = Field(default_factory=dict) 265 """A field for custom configuration that can contain any keys not present in the RDF spec. 266 This means you should not store, for example, a GitHub repo URL in `config` since there is a `git_repo` field. 267 Keys in `config` may be very specific to a tool or consumer software. To avoid conflicting definitions, 268 it is recommended to wrap added configuration into a sub-field named with the specific domain or tool name, 269 for example: 270 ```yaml 271 config: 272 bioimageio: # here is the domain name 273 my_custom_key: 3837283 274 another_key: 275 nested: value 276 imagej: # config specific to ImageJ 277 macro_dir: path/to/macro/file 278 ``` 279 If possible, please use [`snake_case`](https://en.wikipedia.org/wiki/Snake_case) for keys in `config`. 280 You may want to list linked files additionally under `attachments` to include them when packaging a resource. 281 (Packaging a resource means downloading/copying important linked files and creating a ZIP archive that contains 282 an altered rdf.yaml file with local references to the downloaded files.)""" 283 284 git_repo: Annotated[ 285 Optional[HttpUrl], 286 Field( 287 examples=[ 288 "https://github.com/bioimage-io/spec-bioimage-io/tree/main/example_descriptions/models/unet2d_nuclei_broad" 289 ], 290 ), 291 ] = None 292 """A URL to the Git repository where the resource is being developed.""" 293 294 icon: Union[ 295 Annotated[str, Len(min_length=1, max_length=2)], ImportantFileSource, None 296 ] = None 297 """An icon for illustration, e.g. on bioimage.io""" 298 299 links: Annotated[ 300 List[str], 301 Field( 302 examples=[ 303 ( 304 "ilastik/ilastik", 305 "deepimagej/deepimagej", 306 "zero/notebook_u-net_3d_zerocostdl4mic", 307 ) 308 ], 309 ), 310 ] = Field(default_factory=list) 311 """IDs of other bioimage.io resources""" 312 313 uploader: Optional[Uploader] = None 314 """The person who uploaded the model (e.g. to bioimage.io)""" 315 316 maintainers: List[Maintainer] = Field(default_factory=list) 317 """Maintainers of this resource. 318 If not specified, `authors` are maintainers and at least some of them has to specify their `github_user` name""" 319 320 @partial(as_warning, severity=ALERT) 321 @field_validator("maintainers", mode="after") 322 @classmethod 323 def check_maintainers_exist( 324 cls, maintainers: List[Maintainer], info: ValidationInfo 325 ) -> List[Maintainer]: 326 if not maintainers and "authors" in info.data: 327 authors: List[Author] = info.data["authors"] 328 if all(a.github_user is None for a in authors): 329 raise ValueError( 330 "Missing `maintainers` or any author in `authors` with a specified" 331 + " `github_user` name." 332 ) 333 334 return maintainers 335 336 tags: Annotated[ 337 List[str], 338 Field(examples=[("unet2d", "pytorch", "nucleus", "segmentation", "dsb2018")]), 339 ] = Field(default_factory=list) 340 """Associated tags""" 341 342 @as_warning 343 @field_validator("tags") 344 @classmethod 345 def warn_about_tag_categories( 346 cls, value: List[str], info: ValidationInfo 347 ) -> List[str]: 348 categories = TAG_CATEGORIES.get(info.data["type"], {}) 349 missing_categories: List[Dict[str, Sequence[str]]] = [] 350 for cat, entries in categories.items(): 351 if not any(e in value for e in entries): 352 missing_categories.append({cat: entries}) 353 354 if missing_categories: 355 raise ValueError( 356 f"Missing tags from bioimage.io categories: {missing_categories}" 357 ) 358 359 return value 360 361 version: Optional[Version] = None 362 """The version of the resource following SemVer 2.0.""" 363 364 @model_validator(mode="before") 365 def _remove_version_number( # pyright: ignore[reportUnknownParameterType] 366 cls, value: Union[Any, Dict[Any, Any]] 367 ): 368 if isinstance(value, dict): 369 vn: Any = value.pop("version_number", None) 370 if vn is not None and value.get("version") is None: 371 value["version"] = vn 372 373 return value # pyright: ignore[reportUnknownVariableType] 374 375 376class GenericDescrBase(GenericModelDescrBase): 377 """Base for all resource descriptions except for the model descriptions""" 378 379 format_version: Literal["0.3.0"] = "0.3.0" 380 """The **format** version of this resource specification""" 381 382 @model_validator(mode="before") 383 @classmethod 384 def _convert_from_older_format( 385 cls, data: BioimageioYamlContent, / 386 ) -> BioimageioYamlContent: 387 convert_from_older_format(data) 388 return data 389 390 documentation: Annotated[ 391 Optional[DocumentationSource], 392 Field( 393 examples=[ 394 "https://raw.githubusercontent.com/bioimage-io/spec-bioimage-io/main/example_descriptions/models/unet2d_nuclei_broad/README.md", 395 "README.md", 396 ], 397 ), 398 ] = None 399 """∈📦 URL or relative path to a markdown file encoded in UTF-8 with additional documentation. 400 The recommended documentation file name is `README.md`. An `.md` suffix is mandatory.""" 401 402 badges: List[BadgeDescr] = Field(default_factory=list) 403 """badges associated with this resource""" 404 405 406ResourceDescrType = TypeVar("ResourceDescrType", bound=GenericDescrBase) 407 408 409class GenericDescr( 410 GenericDescrBase, extra="ignore", title="bioimage.io generic specification" 411): 412 """Specification of the fields used in a generic bioimage.io-compliant resource description file (RDF). 413 414 An RDF is a YAML file that describes a resource such as a model, a dataset, or a notebook. 415 Note that those resources are described with a type-specific RDF. 416 Use this generic resource description, if none of the known specific types matches your resource. 417 """ 418 419 type: Annotated[str, LowerCase] = Field("generic", frozen=True) 420 """The resource type assigns a broad category to the resource.""" 421 422 id: Optional[ResourceId] = None 423 """bioimage.io-wide unique resource identifier 424 assigned by bioimage.io; version **un**specific.""" 425 426 parent: Optional[ResourceId] = None 427 """The description from which this one is derived""" 428 429 source: Optional[HttpUrl] = None 430 """The primary source of the resource""" 431 432 @field_validator("type", mode="after") 433 @classmethod 434 def check_specific_types(cls, value: str) -> str: 435 if value in KNOWN_SPECIFIC_RESOURCE_TYPES: 436 raise ValueError( 437 f"Use the {value} description instead of this generic description for" 438 + f" your '{value}' resource." 439 ) 440 441 return value 442 443 444class LinkedResourceNode(Node): 445 446 @model_validator(mode="before") 447 def _remove_version_number( # pyright: ignore[reportUnknownParameterType] 448 cls, value: Union[Any, Dict[Any, Any]] 449 ): 450 if isinstance(value, dict): 451 vn: Any = value.pop("version_number", None) 452 if vn is not None and value.get("version") is None: 453 value["version"] = vn 454 455 return value # pyright: ignore[reportUnknownVariableType] 456 457 version: Optional[Version] = None 458 """The version of the linked resource following SemVer 2.0."""
85class ResourceId(ValidatedString): 86 root_model: ClassVar[Type[RootModel[Any]]] = RootModel[ 87 Annotated[ 88 NotEmpty[str], 89 RestrictCharacters(string.ascii_lowercase + string.digits + "_-/."), 90 annotated_types.Predicate( 91 lambda s: not (s.startswith("/") or s.endswith("/")) 92 ), 93 ] 94 ]
str(object='') -> str str(bytes_or_buffer[, encoding[, errors]]) -> str
Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.__str__() (if defined) or repr(object). encoding defaults to sys.getdefaultencoding(). errors defaults to 'strict'.
113class Author(_Author_v0_2): 114 name: Annotated[str, Predicate(_has_no_slash)] 115 github_user: Optional[str] = None 116 117 @field_validator("github_user", mode="after") 118 def _validate_gh_user(cls, value: Optional[str]): 119 if value is None: 120 return None 121 else: 122 return validate_gh_user(value)
Subpart of a resource description
Inherited Members
141class Maintainer(_Maintainer_v0_2): 142 name: Optional[Annotated[str, Predicate(_has_no_slash)]] = None 143 github_user: str 144 145 @field_validator("github_user", mode="after") 146 def validate_gh_user(cls, value: str): 147 return validate_gh_user(value)
Subpart of a resource description
Inherited Members
166class CiteEntry(Node): 167 text: str 168 """free text description""" 169 170 doi: Optional[Doi] = None 171 """A digital object identifier (DOI) is the prefered citation reference. 172 See https://www.doi.org/ for details. (alternatively specify `url`)""" 173 174 url: Optional[HttpUrl] = None 175 """URL to cite (preferably specify a `doi` instead)""" 176 177 @model_validator(mode="after") 178 def _check_doi_or_url(self): 179 if not self.doi and not self.url: 180 raise ValueError("Either 'doi' or 'url' is required") 181 182 return self
Subpart of a resource description
A digital object identifier (DOI) is the prefered citation reference.
See https://www.doi.org/ for details. (alternatively specify url
)
185class LinkedResource(Node): 186 """Reference to a bioimage.io resource""" 187 188 id: ResourceId 189 """A valid resource `id` from the official bioimage.io collection."""
Reference to a bioimage.io resource
192class GenericModelDescrBase(ResourceDescrBase): 193 """Base for all resource descriptions including of model descriptions""" 194 195 name: Annotated[ 196 Annotated[ 197 str, RestrictCharacters(string.ascii_letters + string.digits + "_- ()") 198 ], 199 MinLen(5), 200 MaxLen(128), 201 warn(MaxLen(64), "Name longer than 64 characters.", INFO), 202 ] 203 name: Annotated[NotEmpty[str], MaxLen(128)] 204 """A human-friendly name of the resource description. 205 May only contains letters, digits, underscore, minus, parentheses and spaces.""" 206 207 description: Annotated[ 208 str, MaxLen(1024), warn(MaxLen(512), "Description longer than 512 characters.") 209 ] 210 """A string containing a brief description.""" 211 212 covers: Annotated[ 213 List[CoverImageSource], 214 Field( 215 examples=[], 216 description=( 217 "Cover images. Please use an image smaller than 500KB and an aspect" 218 " ratio width to height of 2:1 or 1:1.\nThe supported image formats" 219 f" are: {VALID_COVER_IMAGE_EXTENSIONS}" 220 ), 221 ), 222 ] = Field(default_factory=list) 223 """∈📦 Cover images.""" 224 225 id_emoji: Optional[Annotated[str, Len(min_length=1, max_length=2)]] = None 226 """UTF-8 emoji for display alongside the `id`.""" 227 228 authors: NotEmpty[List[Author]] 229 """The authors are the creators of this resource description and the primary points of contact.""" 230 231 attachments: List[FileDescr] = Field(default_factory=list) 232 """file attachments""" 233 234 cite: NotEmpty[List[CiteEntry]] 235 """citations""" 236 237 license: Annotated[ 238 Annotated[ 239 Union[LicenseId, DeprecatedLicenseId], Field(union_mode="left_to_right") 240 ], 241 warn( 242 LicenseId, 243 "{value} is deprecated, see https://spdx.org/licenses/{value}.html", 244 ), 245 Field(examples=["CC0-1.0", "MIT", "BSD-2-Clause"]), 246 ] 247 """A [SPDX license identifier](https://spdx.org/licenses/). 248 We do not support custom license beyond the SPDX license list, if you need that please 249 [open a GitHub issue](https://github.com/bioimage-io/spec-bioimage-io/issues/new/choose) 250 to discuss your intentions with the community.""" 251 252 config: Annotated[ 253 Dict[str, YamlValue], 254 Field( 255 examples=[ 256 dict( 257 bioimageio={ 258 "my_custom_key": 3837283, 259 "another_key": {"nested": "value"}, 260 }, 261 imagej={"macro_dir": "path/to/macro/file"}, 262 ) 263 ], 264 ), 265 ] = Field(default_factory=dict) 266 """A field for custom configuration that can contain any keys not present in the RDF spec. 267 This means you should not store, for example, a GitHub repo URL in `config` since there is a `git_repo` field. 268 Keys in `config` may be very specific to a tool or consumer software. To avoid conflicting definitions, 269 it is recommended to wrap added configuration into a sub-field named with the specific domain or tool name, 270 for example: 271 ```yaml 272 config: 273 bioimageio: # here is the domain name 274 my_custom_key: 3837283 275 another_key: 276 nested: value 277 imagej: # config specific to ImageJ 278 macro_dir: path/to/macro/file 279 ``` 280 If possible, please use [`snake_case`](https://en.wikipedia.org/wiki/Snake_case) for keys in `config`. 281 You may want to list linked files additionally under `attachments` to include them when packaging a resource. 282 (Packaging a resource means downloading/copying important linked files and creating a ZIP archive that contains 283 an altered rdf.yaml file with local references to the downloaded files.)""" 284 285 git_repo: Annotated[ 286 Optional[HttpUrl], 287 Field( 288 examples=[ 289 "https://github.com/bioimage-io/spec-bioimage-io/tree/main/example_descriptions/models/unet2d_nuclei_broad" 290 ], 291 ), 292 ] = None 293 """A URL to the Git repository where the resource is being developed.""" 294 295 icon: Union[ 296 Annotated[str, Len(min_length=1, max_length=2)], ImportantFileSource, None 297 ] = None 298 """An icon for illustration, e.g. on bioimage.io""" 299 300 links: Annotated[ 301 List[str], 302 Field( 303 examples=[ 304 ( 305 "ilastik/ilastik", 306 "deepimagej/deepimagej", 307 "zero/notebook_u-net_3d_zerocostdl4mic", 308 ) 309 ], 310 ), 311 ] = Field(default_factory=list) 312 """IDs of other bioimage.io resources""" 313 314 uploader: Optional[Uploader] = None 315 """The person who uploaded the model (e.g. to bioimage.io)""" 316 317 maintainers: List[Maintainer] = Field(default_factory=list) 318 """Maintainers of this resource. 319 If not specified, `authors` are maintainers and at least some of them has to specify their `github_user` name""" 320 321 @partial(as_warning, severity=ALERT) 322 @field_validator("maintainers", mode="after") 323 @classmethod 324 def check_maintainers_exist( 325 cls, maintainers: List[Maintainer], info: ValidationInfo 326 ) -> List[Maintainer]: 327 if not maintainers and "authors" in info.data: 328 authors: List[Author] = info.data["authors"] 329 if all(a.github_user is None for a in authors): 330 raise ValueError( 331 "Missing `maintainers` or any author in `authors` with a specified" 332 + " `github_user` name." 333 ) 334 335 return maintainers 336 337 tags: Annotated[ 338 List[str], 339 Field(examples=[("unet2d", "pytorch", "nucleus", "segmentation", "dsb2018")]), 340 ] = Field(default_factory=list) 341 """Associated tags""" 342 343 @as_warning 344 @field_validator("tags") 345 @classmethod 346 def warn_about_tag_categories( 347 cls, value: List[str], info: ValidationInfo 348 ) -> List[str]: 349 categories = TAG_CATEGORIES.get(info.data["type"], {}) 350 missing_categories: List[Dict[str, Sequence[str]]] = [] 351 for cat, entries in categories.items(): 352 if not any(e in value for e in entries): 353 missing_categories.append({cat: entries}) 354 355 if missing_categories: 356 raise ValueError( 357 f"Missing tags from bioimage.io categories: {missing_categories}" 358 ) 359 360 return value 361 362 version: Optional[Version] = None 363 """The version of the resource following SemVer 2.0.""" 364 365 @model_validator(mode="before") 366 def _remove_version_number( # pyright: ignore[reportUnknownParameterType] 367 cls, value: Union[Any, Dict[Any, Any]] 368 ): 369 if isinstance(value, dict): 370 vn: Any = value.pop("version_number", None) 371 if vn is not None and value.get("version") is None: 372 value["version"] = vn 373 374 return value # pyright: ignore[reportUnknownVariableType]
Base for all resource descriptions including of model descriptions
A human-friendly name of the resource description. May only contains letters, digits, underscore, minus, parentheses and spaces.
A string containing a brief description.
∈📦 Cover images.
UTF-8 emoji for display alongside the id
.
A SPDX license identifier. We do not support custom license beyond the SPDX license list, if you need that please open a GitHub issue to discuss your intentions with the community.
A field for custom configuration that can contain any keys not present in the RDF spec.
This means you should not store, for example, a GitHub repo URL in config
since there is a git_repo
field.
Keys in config
may be very specific to a tool or consumer software. To avoid conflicting definitions,
it is recommended to wrap added configuration into a sub-field named with the specific domain or tool name,
for example:
config:
bioimageio: # here is the domain name
my_custom_key: 3837283
another_key:
nested: value
imagej: # config specific to ImageJ
macro_dir: path/to/macro/file
If possible, please use snake_case
for keys in config
.
You may want to list linked files additionally under attachments
to include them when packaging a resource.
(Packaging a resource means downloading/copying important linked files and creating a ZIP archive that contains
an altered rdf.yaml file with local references to the downloaded files.)
A URL to the Git repository where the resource is being developed.
An icon for illustration, e.g. on bioimage.io
IDs of other bioimage.io resources
The person who uploaded the model (e.g. to bioimage.io)
Maintainers of this resource.
If not specified, authors
are maintainers and at least some of them has to specify their github_user
name
The version of the resource following SemVer 2.0.
124 def wrapped_model_post_init(self: BaseModel, context: Any, /) -> None: 125 """We need to both initialize private attributes and call the user-defined model_post_init 126 method. 127 """ 128 init_private_attributes(self, context) 129 original_model_post_init(self, context)
We need to both initialize private attributes and call the user-defined model_post_init method.
377class GenericDescrBase(GenericModelDescrBase): 378 """Base for all resource descriptions except for the model descriptions""" 379 380 format_version: Literal["0.3.0"] = "0.3.0" 381 """The **format** version of this resource specification""" 382 383 @model_validator(mode="before") 384 @classmethod 385 def _convert_from_older_format( 386 cls, data: BioimageioYamlContent, / 387 ) -> BioimageioYamlContent: 388 convert_from_older_format(data) 389 return data 390 391 documentation: Annotated[ 392 Optional[DocumentationSource], 393 Field( 394 examples=[ 395 "https://raw.githubusercontent.com/bioimage-io/spec-bioimage-io/main/example_descriptions/models/unet2d_nuclei_broad/README.md", 396 "README.md", 397 ], 398 ), 399 ] = None 400 """∈📦 URL or relative path to a markdown file encoded in UTF-8 with additional documentation. 401 The recommended documentation file name is `README.md`. An `.md` suffix is mandatory.""" 402 403 badges: List[BadgeDescr] = Field(default_factory=list) 404 """badges associated with this resource"""
Base for all resource descriptions except for the model descriptions
∈📦 URL or relative path to a markdown file encoded in UTF-8 with additional documentation.
The recommended documentation file name is README.md
. An .md
suffix is mandatory.
124 def wrapped_model_post_init(self: BaseModel, context: Any, /) -> None: 125 """We need to both initialize private attributes and call the user-defined model_post_init 126 method. 127 """ 128 init_private_attributes(self, context) 129 original_model_post_init(self, context)
We need to both initialize private attributes and call the user-defined model_post_init method.
410class GenericDescr( 411 GenericDescrBase, extra="ignore", title="bioimage.io generic specification" 412): 413 """Specification of the fields used in a generic bioimage.io-compliant resource description file (RDF). 414 415 An RDF is a YAML file that describes a resource such as a model, a dataset, or a notebook. 416 Note that those resources are described with a type-specific RDF. 417 Use this generic resource description, if none of the known specific types matches your resource. 418 """ 419 420 type: Annotated[str, LowerCase] = Field("generic", frozen=True) 421 """The resource type assigns a broad category to the resource.""" 422 423 id: Optional[ResourceId] = None 424 """bioimage.io-wide unique resource identifier 425 assigned by bioimage.io; version **un**specific.""" 426 427 parent: Optional[ResourceId] = None 428 """The description from which this one is derived""" 429 430 source: Optional[HttpUrl] = None 431 """The primary source of the resource""" 432 433 @field_validator("type", mode="after") 434 @classmethod 435 def check_specific_types(cls, value: str) -> str: 436 if value in KNOWN_SPECIFIC_RESOURCE_TYPES: 437 raise ValueError( 438 f"Use the {value} description instead of this generic description for" 439 + f" your '{value}' resource." 440 ) 441 442 return value
Specification of the fields used in a generic bioimage.io-compliant resource description file (RDF).
An RDF is a YAML file that describes a resource such as a model, a dataset, or a notebook. Note that those resources are described with a type-specific RDF. Use this generic resource description, if none of the known specific types matches your resource.
The resource type assigns a broad category to the resource.
bioimage.io-wide unique resource identifier assigned by bioimage.io; version unspecific.
433 @field_validator("type", mode="after") 434 @classmethod 435 def check_specific_types(cls, value: str) -> str: 436 if value in KNOWN_SPECIFIC_RESOURCE_TYPES: 437 raise ValueError( 438 f"Use the {value} description instead of this generic description for" 439 + f" your '{value}' resource." 440 ) 441 442 return value
124 def wrapped_model_post_init(self: BaseModel, context: Any, /) -> None: 125 """We need to both initialize private attributes and call the user-defined model_post_init 126 method. 127 """ 128 init_private_attributes(self, context) 129 original_model_post_init(self, context)
We need to both initialize private attributes and call the user-defined model_post_init method.
445class LinkedResourceNode(Node): 446 447 @model_validator(mode="before") 448 def _remove_version_number( # pyright: ignore[reportUnknownParameterType] 449 cls, value: Union[Any, Dict[Any, Any]] 450 ): 451 if isinstance(value, dict): 452 vn: Any = value.pop("version_number", None) 453 if vn is not None and value.get("version") is None: 454 value["version"] = vn 455 456 return value # pyright: ignore[reportUnknownVariableType] 457 458 version: Optional[Version] = None 459 """The version of the linked resource following SemVer 2.0."""
Subpart of a resource description