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

A custom badge

label: Annotated[str, FieldInfo(annotation=NoneType, required=True, examples=['Open in Colab'])]

badge label to display on hover

icon: Annotated[Union[Annotated[Union[Annotated[pathlib.Path, PathType(path_type='file'), FieldInfo(annotation=NoneType, required=True, title='FilePath')], RelativeFilePath], AfterValidator(func=<function wo_special_file_name at 0x7fec152e3740>), PlainSerializer(func=<function _package at 0x7fec152e2a20>, return_type=PydanticUndefined, when_used='unless-none')], HttpUrl, Annotated[pydantic_core._pydantic_core.Url, UrlConstraints(max_length=2083, allowed_schemes=['http', 'https'], host_required=None, default_host=None, default_port=None, default_path=None)], NoneType], FieldInfo(annotation=NoneType, required=True, examples=['https://colab.research.google.com/assets/colab-badge.svg'])]

badge icon

url: Annotated[HttpUrl, FieldInfo(annotation=NoneType, required=True, examples=['https://colab.research.google.com/github/HenriquesLab/ZeroCostDL4Mic/blob/master/Colab_notebooks/U-net_2D_ZeroCostDL4Mic.ipynb'])]

target URL

class CiteEntry(bioimageio.spec._internal.node.Node):
173class CiteEntry(Node):
174    text: str
175    """free text description"""
176
177    doi: Optional[Doi] = None
178    """A digital object identifier (DOI) is the prefered citation reference.
179    See https://www.doi.org/ for details. (alternatively specify `url`)"""
180
181    url: Optional[HttpUrl] = None
182    """URL to cite (preferably specify a `doi` instead)"""
183
184    @model_validator(mode="after")
185    def _check_doi_or_url(self):
186        if not self.doi and not self.url:
187            raise ValueError("Either 'doi' or 'url' is required")
188
189        return self
text: str

free text description

doi: Optional[Doi]

A digital object identifier (DOI) is the prefered citation reference. See https://www.doi.org/ for details. (alternatively specify url)

url: Optional[HttpUrl]

URL to cite (preferably specify a doi instead)

class DeprecatedLicenseId(bioimageio.spec._internal.validated_string.ValidatedString):
24class DeprecatedLicenseId(ValidatedString):
25    root_model: ClassVar[Type[RootModel[Any]]] = RootModel[DeprecatedLicenseIdLiteral]

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'.

root_model: ClassVar[Type[pydantic.root_model.RootModel[Any]]] = <class 'pydantic.root_model.RootModel[Literal['AGPL-1.0', 'AGPL-3.0', 'BSD-2-Clause-FreeBSD', 'BSD-2-Clause-NetBSD', 'bzip2-1.0.5', 'eCos-2.0', 'GFDL-1.1', 'GFDL-1.2', 'GFDL-1.3', 'GPL-1.0', 'GPL-1.0+', 'GPL-2.0', 'GPL-2.0+', 'GPL-2.0-with-autoconf-exception', 'GPL-2.0-with-bison-exception', 'GPL-2.0-with-classpath-exception', 'GPL-2.0-with-font-exception', 'GPL-2.0-with-GCC-exception', 'GPL-3.0', 'GPL-3.0+', 'GPL-3.0-with-autoconf-exception', 'GPL-3.0-with-GCC-exception', 'LGPL-2.0', 'LGPL-2.0+', 'LGPL-2.1', 'LGPL-2.1+', 'LGPL-3.0', 'LGPL-3.0+', 'Nunit', 'StandardML-NJ', 'wxWindows']]'>

the pydantic root model to validate the string

109class Doi(ValidatedString):
110    """A digital object identifier, see https://www.doi.org/"""
111
112    root_model: ClassVar[Type[RootModel[Any]]] = RootModel[
113        Annotated[str, StringConstraints(pattern=DOI_REGEX)]
114    ]

A digital object identifier, see https://www.doi.org/

root_model: ClassVar[Type[pydantic.root_model.RootModel[Any]]] = <class 'pydantic.root_model.RootModel[Annotated[str, StringConstraints]]'>

the pydantic root model to validate the string

class FileDescr(bioimageio.spec._internal.node.Node):
768class FileDescr(Node):
769    source: ImportantFileSource
770    """∈📦 file source"""
771
772    sha256: Optional[Sha256] = None
773    """SHA256 checksum of the source file"""
774
775    @model_validator(mode="after")
776    def validate_sha256(self) -> Self:
777        context = validation_context_var.get()
778        if not context.perform_io_checks:
779            return self
780        elif (src_str := str(self.source)) in context.known_files:
781            actual_sha = context.known_files[src_str]
782        else:
783            local_source = download(self.source, sha256=self.sha256).path
784            actual_sha = get_sha256(local_source)
785            context.known_files[str(self.source)] = actual_sha
786
787        if self.sha256 is None:
788            self.sha256 = actual_sha
789        elif self.sha256 != actual_sha:
790            raise ValueError(
791                f"Sha256 mismatch for {self.source}. Expected {self.sha256}, got "
792                + f"{actual_sha}. Update expected `sha256` or point to the matching "
793                + "file."
794            )
795
796        return self
797
798    def download(self):
799
800        return download(self.source, sha256=self.sha256)
source: Annotated[Union[HttpUrl, RelativeFilePath, Annotated[pathlib.Path, PathType(path_type='file'), FieldInfo(annotation=NoneType, required=True, title='FilePath')]], FieldInfo(annotation=NoneType, required=True, metadata=[_PydanticGeneralMetadata(union_mode='left_to_right')]), AfterValidator(func=<function wo_special_file_name at 0x7fec152e3740>), PlainSerializer(func=<function _package at 0x7fec152e2a20>, return_type=PydanticUndefined, when_used='unless-none')]

∈📦 file source

sha256: Optional[Sha256]

SHA256 checksum of the source file

@model_validator(mode='after')
def validate_sha256(self) -> Self:
775    @model_validator(mode="after")
776    def validate_sha256(self) -> Self:
777        context = validation_context_var.get()
778        if not context.perform_io_checks:
779            return self
780        elif (src_str := str(self.source)) in context.known_files:
781            actual_sha = context.known_files[src_str]
782        else:
783            local_source = download(self.source, sha256=self.sha256).path
784            actual_sha = get_sha256(local_source)
785            context.known_files[str(self.source)] = actual_sha
786
787        if self.sha256 is None:
788            self.sha256 = actual_sha
789        elif self.sha256 != actual_sha:
790            raise ValueError(
791                f"Sha256 mismatch for {self.source}. Expected {self.sha256}, got "
792                + f"{actual_sha}. Update expected `sha256` or point to the matching "
793                + "file."
794            )
795
796        return self
def download(self):
798    def download(self):
799
800        return download(self.source, sha256=self.sha256)
class GenericDescr(GenericDescrBase):
436class GenericDescr(GenericDescrBase, extra="ignore"):
437    """Specification of the fields used in a generic bioimage.io-compliant resource description file (RDF).
438
439    An RDF is a YAML file that describes a resource such as a model, a dataset, or a notebook.
440    Note that those resources are described with a type-specific RDF.
441    Use this generic resource description, if none of the known specific types matches your resource.
442    """
443
444    type: Annotated[str, LowerCase] = Field("generic", frozen=True)
445    """The resource type assigns a broad category to the resource."""
446
447    id: Optional[
448        Annotated[ResourceId, Field(examples=["affable-shark", "ambitious-sloth"])]
449    ] = None
450    """bioimage.io-wide unique resource identifier
451    assigned by bioimage.io; version **un**specific."""
452
453    parent: Optional[ResourceId] = None
454    """The description from which this one is derived"""
455
456    source: Optional[HttpUrl] = None
457    """The primary source of the resource"""
458
459    @field_validator("type", mode="after")
460    @classmethod
461    def check_specific_types(cls, value: str) -> str:
462        if value in KNOWN_SPECIFIC_RESOURCE_TYPES:
463            raise ValueError(
464                f"Use the {value} description instead of this generic description for"
465                + f" your '{value}' resource."
466            )
467
468        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.

type: Annotated[str, Annotated[~_StrType, Predicate(str.islower)]]

The resource type assigns a broad category to the resource.

id: Optional[Annotated[ResourceId, FieldInfo(annotation=NoneType, required=True, examples=['affable-shark', 'ambitious-sloth'])]]

bioimage.io-wide unique resource identifier assigned by bioimage.io; version unspecific.

parent: Optional[ResourceId]

The description from which this one is derived

source: Optional[HttpUrl]

The primary source of the resource

@field_validator('type', mode='after')
@classmethod
def check_specific_types(cls, value: str) -> str:
459    @field_validator("type", mode="after")
460    @classmethod
461    def check_specific_types(cls, value: str) -> str:
462        if value in KNOWN_SPECIFIC_RESOURCE_TYPES:
463            raise ValueError(
464                f"Use the {value} description instead of this generic description for"
465                + f" your '{value}' resource."
466            )
467
468        return value
implemented_type: ClassVar[str] = 'generic'
implemented_format_version: ClassVar[str] = '0.3.0'
implemented_format_version_tuple: ClassVar[Tuple[int, int, int]] = (0, 3, 0)
def model_post_init(self: pydantic.main.BaseModel, context: Any, /) -> None:
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.

118class HttpUrl(RootHttpUrl):
119    """A URL with the HTTP or HTTPS scheme."""
120
121    root_model: ClassVar[Type[RootModel[Any]]] = RootModel[pydantic.HttpUrl]
122    _exists: Optional[bool] = None
123
124    def _after_validator(self):
125        self = super()._after_validator()
126        context = validation_context_var.get()
127        if (
128            context.perform_io_checks
129            and str(self._validated) not in context.known_files
130        ):
131            self._validated = _validate_url(self._validated)
132            self._exists = True
133
134        return self
135
136    def exists(self):
137        """True if URL is available"""
138        if self._exists is None:
139            try:
140                self._validated = _validate_url(self._validated)
141            except Exception as e:
142                logger.info(e)
143                self._exists = False
144            else:
145                self._exists = True
146
147        return self._exists

A URL with the HTTP or HTTPS scheme.

root_model: ClassVar[Type[pydantic.root_model.RootModel[Any]]] = <class 'pydantic.root_model.RootModel[Annotated[Url, UrlConstraints(max_length=2083, allowed_schemes=['http', 'https'], host_required=None, default_host=None, default_port=None, default_path=None)]]'>

the pydantic root model to validate the string

def exists(self):
136    def exists(self):
137        """True if URL is available"""
138        if self._exists is None:
139            try:
140                self._validated = _validate_url(self._validated)
141            except Exception as e:
142                logger.info(e)
143                self._exists = False
144            else:
145                self._exists = True
146
147        return self._exists

True if URL is available

KNOWN_SPECIFIC_RESOURCE_TYPES = ('application', 'collection', 'dataset', 'model', 'notebook')
20class LicenseId(ValidatedString):
21    root_model: ClassVar[Type[RootModel[Any]]] = RootModel[LicenseIdLiteral]

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'.

root_model: ClassVar[Type[pydantic.root_model.RootModel[Any]]] = <class 'pydantic.root_model.RootModel[Literal['0BSD', 'AAL', 'Abstyles', 'AdaCore-doc', 'Adobe-2006', 'Adobe-Display-PostScript', 'Adobe-Glyph', 'Adobe-Utopia', 'ADSL', 'AFL-1.1', 'AFL-1.2', 'AFL-2.0', 'AFL-2.1', 'AFL-3.0', 'Afmparse', 'AGPL-1.0-only', 'AGPL-1.0-or-later', 'AGPL-3.0-only', 'AGPL-3.0-or-later', 'Aladdin', 'AMDPLPA', 'AML', 'AML-glslang', 'AMPAS', 'ANTLR-PD', 'ANTLR-PD-fallback', 'Apache-1.0', 'Apache-1.1', 'Apache-2.0', 'APAFML', 'APL-1.0', 'App-s2p', 'APSL-1.0', 'APSL-1.1', 'APSL-1.2', 'APSL-2.0', 'Arphic-1999', 'Artistic-1.0', 'Artistic-1.0-cl8', 'Artistic-1.0-Perl', 'Artistic-2.0', 'ASWF-Digital-Assets-1.0', 'ASWF-Digital-Assets-1.1', 'Baekmuk', 'Bahyph', 'Barr', 'bcrypt-Solar-Designer', 'Beerware', 'Bitstream-Charter', 'Bitstream-Vera', 'BitTorrent-1.0', 'BitTorrent-1.1', 'blessing', 'BlueOak-1.0.0', 'Boehm-GC', 'Borceux', 'Brian-Gladman-2-Clause', 'Brian-Gladman-3-Clause', 'BSD-1-Clause', 'BSD-2-Clause', 'BSD-2-Clause-Darwin', 'BSD-2-Clause-Patent', 'BSD-2-Clause-Views', 'BSD-3-Clause', 'BSD-3-Clause-acpica', 'BSD-3-Clause-Attribution', 'BSD-3-Clause-Clear', 'BSD-3-Clause-flex', 'BSD-3-Clause-HP', 'BSD-3-Clause-LBNL', 'BSD-3-Clause-Modification', 'BSD-3-Clause-No-Military-License', 'BSD-3-Clause-No-Nuclear-License', 'BSD-3-Clause-No-Nuclear-License-2014', 'BSD-3-Clause-No-Nuclear-Warranty', 'BSD-3-Clause-Open-MPI', 'BSD-3-Clause-Sun', 'BSD-4-Clause', 'BSD-4-Clause-Shortened', 'BSD-4-Clause-UC', 'BSD-4.3RENO', 'BSD-4.3TAHOE', 'BSD-Advertising-Acknowledgement', 'BSD-Attribution-HPND-disclaimer', 'BSD-Inferno-Nettverk', 'BSD-Protection', 'BSD-Source-beginning-file', 'BSD-Source-Code', 'BSD-Systemics', 'BSD-Systemics-W3Works', 'BSL-1.0', 'BUSL-1.1', 'bzip2-1.0.6', 'C-UDA-1.0', 'CAL-1.0', 'CAL-1.0-Combined-Work-Exception', 'Caldera', 'Caldera-no-preamble', 'CATOSL-1.1', 'CC-BY-1.0', 'CC-BY-2.0', 'CC-BY-2.5', 'CC-BY-2.5-AU', 'CC-BY-3.0', 'CC-BY-3.0-AT', 'CC-BY-3.0-AU', 'CC-BY-3.0-DE', 'CC-BY-3.0-IGO', 'CC-BY-3.0-NL', 'CC-BY-3.0-US', 'CC-BY-4.0', 'CC-BY-NC-1.0', 'CC-BY-NC-2.0', 'CC-BY-NC-2.5', 'CC-BY-NC-3.0', 'CC-BY-NC-3.0-DE', 'CC-BY-NC-4.0', 'CC-BY-NC-ND-1.0', 'CC-BY-NC-ND-2.0', 'CC-BY-NC-ND-2.5', 'CC-BY-NC-ND-3.0', 'CC-BY-NC-ND-3.0-DE', 'CC-BY-NC-ND-3.0-IGO', 'CC-BY-NC-ND-4.0', 'CC-BY-NC-SA-1.0', 'CC-BY-NC-SA-2.0', 'CC-BY-NC-SA-2.0-DE', 'CC-BY-NC-SA-2.0-FR', 'CC-BY-NC-SA-2.0-UK', 'CC-BY-NC-SA-2.5', 'CC-BY-NC-SA-3.0', 'CC-BY-NC-SA-3.0-DE', 'CC-BY-NC-SA-3.0-IGO', 'CC-BY-NC-SA-4.0', 'CC-BY-ND-1.0', 'CC-BY-ND-2.0', 'CC-BY-ND-2.5', 'CC-BY-ND-3.0', 'CC-BY-ND-3.0-DE', 'CC-BY-ND-4.0', 'CC-BY-SA-1.0', 'CC-BY-SA-2.0', 'CC-BY-SA-2.0-UK', 'CC-BY-SA-2.1-JP', 'CC-BY-SA-2.5', 'CC-BY-SA-3.0', 'CC-BY-SA-3.0-AT', 'CC-BY-SA-3.0-DE', 'CC-BY-SA-3.0-IGO', 'CC-BY-SA-4.0', 'CC-PDDC', 'CC0-1.0', 'CDDL-1.0', 'CDDL-1.1', 'CDL-1.0', 'CDLA-Permissive-1.0', 'CDLA-Permissive-2.0', 'CDLA-Sharing-1.0', 'CECILL-1.0', 'CECILL-1.1', 'CECILL-2.0', 'CECILL-2.1', 'CECILL-B', 'CECILL-C', 'CERN-OHL-1.1', 'CERN-OHL-1.2', 'CERN-OHL-P-2.0', 'CERN-OHL-S-2.0', 'CERN-OHL-W-2.0', 'CFITSIO', 'check-cvs', 'checkmk', 'ClArtistic', 'Clips', 'CMU-Mach', 'CMU-Mach-nodoc', 'CNRI-Jython', 'CNRI-Python', 'CNRI-Python-GPL-Compatible', 'COIL-1.0', 'Community-Spec-1.0', 'Condor-1.1', 'copyleft-next-0.3.0', 'copyleft-next-0.3.1', 'Cornell-Lossless-JPEG', 'CPAL-1.0', 'CPL-1.0', 'CPOL-1.02', 'Cronyx', 'Crossword', 'CrystalStacker', 'CUA-OPL-1.0', 'Cube', 'curl', 'D-FSL-1.0', 'DEC-3-Clause', 'diffmark', 'DL-DE-BY-2.0', 'DL-DE-ZERO-2.0', 'DOC', 'Dotseqn', 'DRL-1.0', 'DRL-1.1', 'DSDP', 'dtoa', 'dvipdfm', 'ECL-1.0', 'ECL-2.0', 'EFL-1.0', 'EFL-2.0', 'eGenix', 'Elastic-2.0', 'Entessa', 'EPICS', 'EPL-1.0', 'EPL-2.0', 'ErlPL-1.1', 'etalab-2.0', 'EUDatagrid', 'EUPL-1.0', 'EUPL-1.1', 'EUPL-1.2', 'Eurosym', 'Fair', 'FBM', 'FDK-AAC', 'Ferguson-Twofish', 'Frameworx-1.0', 'FreeBSD-DOC', 'FreeImage', 'FSFAP', 'FSFAP-no-warranty-disclaimer', 'FSFUL', 'FSFULLR', 'FSFULLRWD', 'FTL', 'Furuseth', 'fwlw', 'GCR-docs', 'GD', 'GFDL-1.1-invariants-only', 'GFDL-1.1-invariants-or-later', 'GFDL-1.1-no-invariants-only', 'GFDL-1.1-no-invariants-or-later', 'GFDL-1.1-only', 'GFDL-1.1-or-later', 'GFDL-1.2-invariants-only', 'GFDL-1.2-invariants-or-later', 'GFDL-1.2-no-invariants-only', 'GFDL-1.2-no-invariants-or-later', 'GFDL-1.2-only', 'GFDL-1.2-or-later', 'GFDL-1.3-invariants-only', 'GFDL-1.3-invariants-or-later', 'GFDL-1.3-no-invariants-only', 'GFDL-1.3-no-invariants-or-later', 'GFDL-1.3-only', 'GFDL-1.3-or-later', 'Giftware', 'GL2PS', 'Glide', 'Glulxe', 'GLWTPL', 'gnuplot', 'GPL-1.0-only', 'GPL-1.0-or-later', 'GPL-2.0-only', 'GPL-2.0-or-later', 'GPL-3.0-only', 'GPL-3.0-or-later', 'Graphics-Gems', 'gSOAP-1.3b', 'gtkbook', 'HaskellReport', 'hdparm', 'Hippocratic-2.1', 'HP-1986', 'HP-1989', 'HPND', 'HPND-DEC', 'HPND-doc', 'HPND-doc-sell', 'HPND-export-US', 'HPND-export-US-modify', 'HPND-Fenneberg-Livingston', 'HPND-INRIA-IMAG', 'HPND-Kevlin-Henney', 'HPND-Markus-Kuhn', 'HPND-MIT-disclaimer', 'HPND-Pbmplus', 'HPND-sell-MIT-disclaimer-xserver', 'HPND-sell-regexpr', 'HPND-sell-variant', 'HPND-sell-variant-MIT-disclaimer', 'HPND-UC', 'HTMLTIDY', 'IBM-pibs', 'ICU', 'IEC-Code-Components-EULA', 'IJG', 'IJG-short', 'ImageMagick', 'iMatix', 'Imlib2', 'Info-ZIP', 'Inner-Net-2.0', 'Intel', 'Intel-ACPI', 'Interbase-1.0', 'IPA', 'IPL-1.0', 'ISC', 'ISC-Veillard', 'Jam', 'JasPer-2.0', 'JPL-image', 'JPNIC', 'JSON', 'Kastrup', 'Kazlib', 'Knuth-CTAN', 'LAL-1.2', 'LAL-1.3', 'Latex2e', 'Latex2e-translated-notice', 'Leptonica', 'LGPL-2.0-only', 'LGPL-2.0-or-later', 'LGPL-2.1-only', 'LGPL-2.1-or-later', 'LGPL-3.0-only', 'LGPL-3.0-or-later', 'LGPLLR', 'Libpng', 'libpng-2.0', 'libselinux-1.0', 'libtiff', 'libutil-David-Nugent', 'LiLiQ-P-1.1', 'LiLiQ-R-1.1', 'LiLiQ-Rplus-1.1', 'Linux-man-pages-1-para', 'Linux-man-pages-copyleft', 'Linux-man-pages-copyleft-2-para', 'Linux-man-pages-copyleft-var', 'Linux-OpenIB', 'LOOP', 'LPD-document', 'LPL-1.0', 'LPL-1.02', 'LPPL-1.0', 'LPPL-1.1', 'LPPL-1.2', 'LPPL-1.3a', 'LPPL-1.3c', 'lsof', 'Lucida-Bitmap-Fonts', 'LZMA-SDK-9.11-to-9.20', 'LZMA-SDK-9.22', 'Mackerras-3-Clause', 'Mackerras-3-Clause-acknowledgment', 'magaz', 'mailprio', 'MakeIndex', 'Martin-Birgmeier', 'McPhee-slideshow', 'metamail', 'Minpack', 'MirOS', 'MIT', 'MIT-0', 'MIT-advertising', 'MIT-CMU', 'MIT-enna', 'MIT-feh', 'MIT-Festival', 'MIT-Modern-Variant', 'MIT-open-group', 'MIT-testregex', 'MIT-Wu', 'MITNFA', 'MMIXware', 'Motosoto', 'MPEG-SSG', 'mpi-permissive', 'mpich2', 'MPL-1.0', 'MPL-1.1', 'MPL-2.0', 'MPL-2.0-no-copyleft-exception', 'mplus', 'MS-LPL', 'MS-PL', 'MS-RL', 'MTLL', 'MulanPSL-1.0', 'MulanPSL-2.0', 'Multics', 'Mup', 'NAIST-2003', 'NASA-1.3', 'Naumen', 'NBPL-1.0', 'NCGL-UK-2.0', 'NCSA', 'Net-SNMP', 'NetCDF', 'Newsletr', 'NGPL', 'NICTA-1.0', 'NIST-PD', 'NIST-PD-fallback', 'NIST-Software', 'NLOD-1.0', 'NLOD-2.0', 'NLPL', 'Nokia', 'NOSL', 'Noweb', 'NPL-1.0', 'NPL-1.1', 'NPOSL-3.0', 'NRL', 'NTP', 'NTP-0', 'O-UDA-1.0', 'OCCT-PL', 'OCLC-2.0', 'ODbL-1.0', 'ODC-By-1.0', 'OFFIS', 'OFL-1.0', 'OFL-1.0-no-RFN', 'OFL-1.0-RFN', 'OFL-1.1', 'OFL-1.1-no-RFN', 'OFL-1.1-RFN', 'OGC-1.0', 'OGDL-Taiwan-1.0', 'OGL-Canada-2.0', 'OGL-UK-1.0', 'OGL-UK-2.0', 'OGL-UK-3.0', 'OGTSL', 'OLDAP-1.1', 'OLDAP-1.2', 'OLDAP-1.3', 'OLDAP-1.4', 'OLDAP-2.0', 'OLDAP-2.0.1', 'OLDAP-2.1', 'OLDAP-2.2', 'OLDAP-2.2.1', 'OLDAP-2.2.2', 'OLDAP-2.3', 'OLDAP-2.4', 'OLDAP-2.5', 'OLDAP-2.6', 'OLDAP-2.7', 'OLDAP-2.8', 'OLFL-1.3', 'OML', 'OpenPBS-2.3', 'OpenSSL', 'OpenSSL-standalone', 'OpenVision', 'OPL-1.0', 'OPL-UK-3.0', 'OPUBL-1.0', 'OSET-PL-2.1', 'OSL-1.0', 'OSL-1.1', 'OSL-2.0', 'OSL-2.1', 'OSL-3.0', 'PADL', 'Parity-6.0.0', 'Parity-7.0.0', 'PDDL-1.0', 'PHP-3.0', 'PHP-3.01', 'Pixar', 'Plexus', 'pnmstitch', 'PolyForm-Noncommercial-1.0.0', 'PolyForm-Small-Business-1.0.0', 'PostgreSQL', 'PSF-2.0', 'psfrag', 'psutils', 'Python-2.0', 'Python-2.0.1', 'python-ldap', 'Qhull', 'QPL-1.0', 'QPL-1.0-INRIA-2004', 'radvd', 'Rdisc', 'RHeCos-1.1', 'RPL-1.1', 'RPL-1.5', 'RPSL-1.0', 'RSA-MD', 'RSCPL', 'Ruby', 'SAX-PD', 'SAX-PD-2.0', 'Saxpath', 'SCEA', 'SchemeReport', 'Sendmail', 'Sendmail-8.23', 'SGI-B-1.0', 'SGI-B-1.1', 'SGI-B-2.0', 'SGI-OpenGL', 'SGP4', 'SHL-0.5', 'SHL-0.51', 'SimPL-2.0', 'SISSL', 'SISSL-1.2', 'SL', 'Sleepycat', 'SMLNJ', 'SMPPL', 'SNIA', 'snprintf', 'softSurfer', 'Soundex', 'Spencer-86', 'Spencer-94', 'Spencer-99', 'SPL-1.0', 'ssh-keyscan', 'SSH-OpenSSH', 'SSH-short', 'SSLeay-standalone', 'SSPL-1.0', 'SugarCRM-1.1.3', 'Sun-PPP', 'SunPro', 'SWL', 'swrule', 'Symlinks', 'TAPR-OHL-1.0', 'TCL', 'TCP-wrappers', 'TermReadKey', 'TGPPL-1.0', 'TMate', 'TORQUE-1.1', 'TOSL', 'TPDL', 'TPL-1.0', 'TTWL', 'TTYP0', 'TU-Berlin-1.0', 'TU-Berlin-2.0', 'UCAR', 'UCL-1.0', 'ulem', 'UMich-Merit', 'Unicode-3.0', 'Unicode-DFS-2015', 'Unicode-DFS-2016', 'Unicode-TOU', 'UnixCrypt', 'Unlicense', 'UPL-1.0', 'URT-RLE', 'Vim', 'VOSTROM', 'VSL-1.0', 'W3C', 'W3C-19980720', 'W3C-20150513', 'w3m', 'Watcom-1.0', 'Widget-Workshop', 'Wsuipa', 'WTFPL', 'X11', 'X11-distribute-modifications-variant', 'Xdebug-1.03', 'Xerox', 'Xfig', 'XFree86-1.1', 'xinetd', 'xkeyboard-config-Zinoviev', 'xlock', 'Xnet', 'xpp', 'XSkat', 'YPL-1.0', 'YPL-1.1', 'Zed', 'Zeeff', 'Zend-2.0', 'Zimbra-1.3', 'Zimbra-1.4', 'Zlib', 'zlib-acknowledgement', 'ZPL-1.1', 'ZPL-2.0', 'ZPL-2.1']]'>

the pydantic root model to validate the string

class LinkedResource(LinkedResourceBase):
209class LinkedResource(LinkedResourceBase):
210    """Reference to a bioimage.io resource"""
211
212    id: ResourceId
213    """A valid resource `id` from the official bioimage.io collection."""

Reference to a bioimage.io resource

A valid resource id from the official bioimage.io collection.

class Maintainer(bioimageio.spec.generic.v0_2.Maintainer):
148class Maintainer(_Maintainer_v0_2):
149    name: Optional[Annotated[str, Predicate(_has_no_slash)]] = None
150    github_user: str
151
152    @field_validator("github_user", mode="after")
153    def validate_gh_user(cls, value: str):
154        return validate_gh_user(value)
name: Optional[Annotated[str, Predicate(func=<function _has_no_slash at 0x7fec14a8e3e0>)]]
github_user: str
@field_validator('github_user', mode='after')
def validate_gh_user(cls, value: str):
152    @field_validator("github_user", mode="after")
153    def validate_gh_user(cls, value: str):
154        return validate_gh_user(value)
136class OrcidId(ValidatedString):
137    """An ORCID identifier, see https://orcid.org/"""
138
139    root_model: ClassVar[Type[RootModel[Any]]] = RootModel[
140        Annotated[str, AfterValidator(_validate_orcid_id)]
141    ]

An ORCID identifier, see https://orcid.org/

root_model: ClassVar[Type[pydantic.root_model.RootModel[Any]]] = <class 'pydantic.root_model.RootModel[Annotated[str, AfterValidator]]'>

the pydantic root model to validate the string

class RelativeFilePath(pydantic.root_model.RootModel[PurePath], typing.Generic[~AbsolutePathT]):
186class RelativeFilePath(
187    RelativePathBase[Union[AbsoluteFilePath, HttpUrl, ZipPath]], frozen=True
188):
189    """A path relative to the `rdf.yaml` file (also if the RDF source is a URL)."""
190
191    def model_post_init(self, __context: Any) -> None:
192        """add validation @private"""
193        if not self.root.parts:  # an empty path can only be a directory
194            raise ValueError(f"{self.root} is not a valid file path.")
195
196        super().model_post_init(__context)
197
198    def get_absolute(
199        self, root: "RootHttpUrl | Path | AnyUrl | ZipFile"
200    ) -> "AbsoluteFilePath | HttpUrl | ZipPath":
201        absolute = self._get_absolute_impl(root)
202        if (
203            isinstance(absolute, Path)
204            and (context := validation_context_var.get()).perform_io_checks
205            and str(self.root) not in context.known_files
206            and not absolute.is_file()
207        ):
208            raise ValueError(f"{absolute} does not point to an existing file")
209
210        return absolute

A path relative to the rdf.yaml file (also if the RDF source is a URL).

def model_post_init(self: pydantic.main.BaseModel, context: Any, /) -> None:
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.

def get_absolute( self, root: bioimageio.spec._internal.root_url.RootHttpUrl | pathlib.Path | pydantic_core._pydantic_core.Url | zipfile.ZipFile) -> Union[Annotated[pathlib.Path, PathType(path_type='file'), Predicate(is_absolute), FieldInfo(annotation=NoneType, required=True, title='AbsoluteFilePath')], HttpUrl, zipp.Path]:
198    def get_absolute(
199        self, root: "RootHttpUrl | Path | AnyUrl | ZipFile"
200    ) -> "AbsoluteFilePath | HttpUrl | ZipPath":
201        absolute = self._get_absolute_impl(root)
202        if (
203            isinstance(absolute, Path)
204            and (context := validation_context_var.get()).perform_io_checks
205            and str(self.root) not in context.known_files
206            and not absolute.is_file()
207        ):
208            raise ValueError(f"{absolute} does not point to an existing file")
209
210        return absolute
 92class ResourceId(ValidatedString):
 93    root_model: ClassVar[Type[RootModel[Any]]] = RootModel[
 94        Annotated[
 95            NotEmpty[str],
 96            RestrictCharacters(string.ascii_lowercase + string.digits + "_-/."),
 97            annotated_types.Predicate(
 98                lambda s: not (s.startswith("/") or s.endswith("/"))
 99            ),
100        ]
101    ]

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'.

root_model: ClassVar[Type[pydantic.root_model.RootModel[Any]]] = <class 'pydantic.root_model.RootModel[Annotated[str, MinLen, RestrictCharacters, Predicate]]'>

the pydantic root model to validate the string

33class Sha256(ValidatedString):
34    """A SHA-256 hash value"""
35
36    root_model: ClassVar[Type[RootModel[Any]]] = RootModel[
37        Annotated[
38            str,
39            StringConstraints(
40                strip_whitespace=True, to_lower=True, min_length=64, max_length=64
41            ),
42        ]
43    ]

A SHA-256 hash value

root_model: ClassVar[Type[pydantic.root_model.RootModel[Any]]] = <class 'pydantic.root_model.RootModel[Annotated[str, StringConstraints]]'>

the pydantic root model to validate the string

class Uploader(bioimageio.spec._internal.node.Node):
109class Uploader(Node):
110    email: EmailStr
111    """Email"""
112    name: Optional[Annotated[str, AfterValidator(_remove_slashes)]] = None
113    """name"""
email: pydantic.networks.EmailStr

Email

name: Optional[Annotated[str, AfterValidator(func=<function _remove_slashes at 0x7fec151bb240>)]]

name

VALID_COVER_IMAGE_EXTENSIONS = ('.gif', '.jpeg', '.jpg', '.png', '.svg')
class Version(pydantic.main.BaseModel, typing.Generic[~RootModelRootType]):
 10class Version(RootModel[Union[str, int, float]]):
 11    """wraps a packaging.version.Version instance for validation in pydantic models"""
 12
 13    _version: packaging.version.Version = PrivateAttr()
 14
 15    def __str__(self):
 16        return str(self._version)
 17
 18    def model_post_init(self, __context: Any) -> None:
 19        """set `_version` attribute @private"""
 20        self._version = packaging.version.Version(str(self.root))
 21        return super().model_post_init(__context)
 22
 23    def __lt__(self, other: Version):
 24        return self._version < other._version
 25
 26    def __eq__(self, other: Version):
 27        return self._version == other._version
 28
 29    # the properties below are adopted from and mirror properties of packaging.version.Version
 30    @property
 31    def epoch(self) -> int:
 32        """The epoch of the version.
 33
 34        >>> Version("2.0.0").epoch
 35        0
 36        >>> Version("1!2.0.0").epoch
 37        1
 38        """
 39        return self._version.epoch
 40
 41    @property
 42    def release(self) -> Tuple[int, ...]:
 43        """The components of the "release" segment of the version.
 44
 45        >>> Version("1.2.3").release
 46        (1, 2, 3)
 47        >>> Version("2.0.0").release
 48        (2, 0, 0)
 49        >>> Version("1!2.0.0.post0").release
 50        (2, 0, 0)
 51
 52        Includes trailing zeroes but not the epoch or any pre-release / development /
 53        post-release suffixes.
 54        """
 55        return self._version.release
 56
 57    @property
 58    def pre(self) -> Optional[Tuple[str, int]]:
 59        """The pre-release segment of the version.
 60
 61        >>> print(Version("1.2.3").pre)
 62        None
 63        >>> Version("1.2.3a1").pre
 64        ('a', 1)
 65        >>> Version("1.2.3b1").pre
 66        ('b', 1)
 67        >>> Version("1.2.3rc1").pre
 68        ('rc', 1)
 69        """
 70        return self._version.pre
 71
 72    @property
 73    def post(self) -> Optional[int]:
 74        """The post-release number of the version.
 75
 76        >>> print(Version("1.2.3").post)
 77        None
 78        >>> Version("1.2.3.post1").post
 79        1
 80        """
 81        return self._version.post
 82
 83    @property
 84    def dev(self) -> Optional[int]:
 85        """The development number of the version.
 86
 87        >>> print(Version("1.2.3").dev)
 88        None
 89        >>> Version("1.2.3.dev1").dev
 90        1
 91        """
 92        return self._version.dev
 93
 94    @property
 95    def local(self) -> Optional[str]:
 96        """The local version segment of the version.
 97
 98        >>> print(Version("1.2.3").local)
 99        None
100        >>> Version("1.2.3+abc").local
101        'abc'
102        """
103        return self._version.local
104
105    @property
106    def public(self) -> str:
107        """The public portion of the version.
108
109        >>> Version("1.2.3").public
110        '1.2.3'
111        >>> Version("1.2.3+abc").public
112        '1.2.3'
113        >>> Version("1.2.3+abc.dev1").public
114        '1.2.3'
115        """
116        return self._version.public
117
118    @property
119    def base_version(self) -> str:
120        """The "base version" of the version.
121
122        >>> Version("1.2.3").base_version
123        '1.2.3'
124        >>> Version("1.2.3+abc").base_version
125        '1.2.3'
126        >>> Version("1!1.2.3+abc.dev1").base_version
127        '1!1.2.3'
128
129        The "base version" is the public version of the project without any pre or post
130        release markers.
131        """
132        return self._version.base_version
133
134    @property
135    def is_prerelease(self) -> bool:
136        """Whether this version is a pre-release.
137
138        >>> Version("1.2.3").is_prerelease
139        False
140        >>> Version("1.2.3a1").is_prerelease
141        True
142        >>> Version("1.2.3b1").is_prerelease
143        True
144        >>> Version("1.2.3rc1").is_prerelease
145        True
146        >>> Version("1.2.3dev1").is_prerelease
147        True
148        """
149        return self._version.is_prerelease
150
151    @property
152    def is_postrelease(self) -> bool:
153        """Whether this version is a post-release.
154
155        >>> Version("1.2.3").is_postrelease
156        False
157        >>> Version("1.2.3.post1").is_postrelease
158        True
159        """
160        return self._version.is_postrelease
161
162    @property
163    def is_devrelease(self) -> bool:
164        """Whether this version is a development release.
165
166        >>> Version("1.2.3").is_devrelease
167        False
168        >>> Version("1.2.3.dev1").is_devrelease
169        True
170        """
171        return self._version.is_devrelease
172
173    @property
174    def major(self) -> int:
175        """The first item of :attr:`release` or ``0`` if unavailable.
176
177        >>> Version("1.2.3").major
178        1
179        """
180        return self._version.major
181
182    @property
183    def minor(self) -> int:
184        """The second item of :attr:`release` or ``0`` if unavailable.
185
186        >>> Version("1.2.3").minor
187        2
188        >>> Version("1").minor
189        0
190        """
191        return self._version.minor
192
193    @property
194    def micro(self) -> int:
195        """The third item of :attr:`release` or ``0`` if unavailable.
196
197        >>> Version("1.2.3").micro
198        3
199        >>> Version("1").micro
200        0
201        """
202        return self._version.micro

wraps a packaging.version.Version instance for validation in pydantic models

epoch: int
30    @property
31    def epoch(self) -> int:
32        """The epoch of the version.
33
34        >>> Version("2.0.0").epoch
35        0
36        >>> Version("1!2.0.0").epoch
37        1
38        """
39        return self._version.epoch

The epoch of the version.

>>> Version("2.0.0").epoch
0
>>> Version("1!2.0.0").epoch
1
release: Tuple[int, ...]
41    @property
42    def release(self) -> Tuple[int, ...]:
43        """The components of the "release" segment of the version.
44
45        >>> Version("1.2.3").release
46        (1, 2, 3)
47        >>> Version("2.0.0").release
48        (2, 0, 0)
49        >>> Version("1!2.0.0.post0").release
50        (2, 0, 0)
51
52        Includes trailing zeroes but not the epoch or any pre-release / development /
53        post-release suffixes.
54        """
55        return self._version.release

The components of the "release" segment of the version.

>>> Version("1.2.3").release
(1, 2, 3)
>>> Version("2.0.0").release
(2, 0, 0)
>>> Version("1!2.0.0.post0").release
(2, 0, 0)

Includes trailing zeroes but not the epoch or any pre-release / development / post-release suffixes.

pre: Optional[Tuple[str, int]]
57    @property
58    def pre(self) -> Optional[Tuple[str, int]]:
59        """The pre-release segment of the version.
60
61        >>> print(Version("1.2.3").pre)
62        None
63        >>> Version("1.2.3a1").pre
64        ('a', 1)
65        >>> Version("1.2.3b1").pre
66        ('b', 1)
67        >>> Version("1.2.3rc1").pre
68        ('rc', 1)
69        """
70        return self._version.pre

The pre-release segment of the version.

>>> print(Version("1.2.3").pre)
None
>>> Version("1.2.3a1").pre
('a', 1)
>>> Version("1.2.3b1").pre
('b', 1)
>>> Version("1.2.3rc1").pre
('rc', 1)
post: Optional[int]
72    @property
73    def post(self) -> Optional[int]:
74        """The post-release number of the version.
75
76        >>> print(Version("1.2.3").post)
77        None
78        >>> Version("1.2.3.post1").post
79        1
80        """
81        return self._version.post

The post-release number of the version.

>>> print(Version("1.2.3").post)
None
>>> Version("1.2.3.post1").post
1
dev: Optional[int]
83    @property
84    def dev(self) -> Optional[int]:
85        """The development number of the version.
86
87        >>> print(Version("1.2.3").dev)
88        None
89        >>> Version("1.2.3.dev1").dev
90        1
91        """
92        return self._version.dev

The development number of the version.

>>> print(Version("1.2.3").dev)
None
>>> Version("1.2.3.dev1").dev
1
local: Optional[str]
 94    @property
 95    def local(self) -> Optional[str]:
 96        """The local version segment of the version.
 97
 98        >>> print(Version("1.2.3").local)
 99        None
100        >>> Version("1.2.3+abc").local
101        'abc'
102        """
103        return self._version.local

The local version segment of the version.

>>> print(Version("1.2.3").local)
None
>>> Version("1.2.3+abc").local
'abc'
public: str
105    @property
106    def public(self) -> str:
107        """The public portion of the version.
108
109        >>> Version("1.2.3").public
110        '1.2.3'
111        >>> Version("1.2.3+abc").public
112        '1.2.3'
113        >>> Version("1.2.3+abc.dev1").public
114        '1.2.3'
115        """
116        return self._version.public

The public portion of the version.

>>> Version("1.2.3").public
'1.2.3'
>>> Version("1.2.3+abc").public
'1.2.3'
>>> Version("1.2.3+abc.dev1").public
'1.2.3'
base_version: str
118    @property
119    def base_version(self) -> str:
120        """The "base version" of the version.
121
122        >>> Version("1.2.3").base_version
123        '1.2.3'
124        >>> Version("1.2.3+abc").base_version
125        '1.2.3'
126        >>> Version("1!1.2.3+abc.dev1").base_version
127        '1!1.2.3'
128
129        The "base version" is the public version of the project without any pre or post
130        release markers.
131        """
132        return self._version.base_version

The "base version" of the version.

>>> Version("1.2.3").base_version
'1.2.3'
>>> Version("1.2.3+abc").base_version
'1.2.3'
>>> Version("1!1.2.3+abc.dev1").base_version
'1!1.2.3'

The "base version" is the public version of the project without any pre or post release markers.

is_prerelease: bool
134    @property
135    def is_prerelease(self) -> bool:
136        """Whether this version is a pre-release.
137
138        >>> Version("1.2.3").is_prerelease
139        False
140        >>> Version("1.2.3a1").is_prerelease
141        True
142        >>> Version("1.2.3b1").is_prerelease
143        True
144        >>> Version("1.2.3rc1").is_prerelease
145        True
146        >>> Version("1.2.3dev1").is_prerelease
147        True
148        """
149        return self._version.is_prerelease

Whether this version is a pre-release.

>>> Version("1.2.3").is_prerelease
False
>>> Version("1.2.3a1").is_prerelease
True
>>> Version("1.2.3b1").is_prerelease
True
>>> Version("1.2.3rc1").is_prerelease
True
>>> Version("1.2.3dev1").is_prerelease
True
is_postrelease: bool
151    @property
152    def is_postrelease(self) -> bool:
153        """Whether this version is a post-release.
154
155        >>> Version("1.2.3").is_postrelease
156        False
157        >>> Version("1.2.3.post1").is_postrelease
158        True
159        """
160        return self._version.is_postrelease

Whether this version is a post-release.

>>> Version("1.2.3").is_postrelease
False
>>> Version("1.2.3.post1").is_postrelease
True
is_devrelease: bool
162    @property
163    def is_devrelease(self) -> bool:
164        """Whether this version is a development release.
165
166        >>> Version("1.2.3").is_devrelease
167        False
168        >>> Version("1.2.3.dev1").is_devrelease
169        True
170        """
171        return self._version.is_devrelease

Whether this version is a development release.

>>> Version("1.2.3").is_devrelease
False
>>> Version("1.2.3.dev1").is_devrelease
True
major: int
173    @property
174    def major(self) -> int:
175        """The first item of :attr:`release` or ``0`` if unavailable.
176
177        >>> Version("1.2.3").major
178        1
179        """
180        return self._version.major

The first item of release or 0 if unavailable.

>>> Version("1.2.3").major
1
minor: int
182    @property
183    def minor(self) -> int:
184        """The second item of :attr:`release` or ``0`` if unavailable.
185
186        >>> Version("1.2.3").minor
187        2
188        >>> Version("1").minor
189        0
190        """
191        return self._version.minor

The second item of release or 0 if unavailable.

>>> Version("1.2.3").minor
2
>>> Version("1").minor
0
micro: int
193    @property
194    def micro(self) -> int:
195        """The third item of :attr:`release` or ``0`` if unavailable.
196
197        >>> Version("1.2.3").micro
198        3
199        >>> Version("1").micro
200        0
201        """
202        return self._version.micro

The third item of release or 0 if unavailable.

>>> Version("1.2.3").micro
3
>>> Version("1").micro
0