コード例 #1
0
class TorchscriptWeightsEntry(_WeightsEntryBase):
    raw_nodes = raw_nodes

    bioimageio_description = "Torchscript weights format"
    weights_format = fields.String(
        validate=field_validators.Equal("torchscript"),
        required=True,
        load_only=True)
    pytorch_version = fields.Version()
コード例 #2
0
class PytorchStateDictWeightsEntry(_WeightsEntryBase):
    bioimageio_description = "PyTorch state dictionary weights format"
    weights_format = fields.String(
        validate=field_validators.Equal("pytorch_state_dict"),
        required=True,
        load_only=True)
    architecture = fields.ImportableSource(
        required=True,
        bioimageio_description=
        "Source code of the model architecture that either points to a "
        "local implementation: `<relative path to file>:<identifier of implementation within the file>` or the "
        "implementation in an available dependency: `<root-dependency>.<sub-dependency>.<identifier>`.\nFor example: "
        "`my_function.py:MyImplementation` or `bioimageio.core.some_module.some_class_or_function`.",
    )
    architecture_sha256 = fields.String(
        bioimageio_maybe_required=True,
        validate=field_validators.Length(equal=64),
        bioimageio_description=
        "This field is only required if the architecture points to a source file. "
        "SHA256 checksum of the model source code file." +
        _common_sha256_hint.replace(
            "    ", "        "),  # sha256 hint with one more intend level
    )
    kwargs = fields.Kwargs(
        bioimageio_description=
        "Keyword arguments for the implementation specified by `architecture`."
    )
    pytorch_version = fields.Version()

    @validates_schema
    def sha_for_source_code_file(self, data, **kwargs):
        arch = data.get("architecture")
        if isinstance(arch, raw_nodes.ImportableModule):
            return
        elif isinstance(arch, raw_nodes.ImportableSourceFile):
            sha = data.get("architecture_sha256")
            if sha is None:
                raise ValidationError(
                    "When specifying 'architecture' with a callable from a source file, "
                    "the corresponding 'architecture_sha256' field is required."
                )
コード例 #3
0
class TensorflowSavedModelBundleWeightsEntry(_WeightsEntryBase):
    bioimageio_description = "Tensorflow Saved Model Bundle weights format"
    weights_format = fields.String(
        validate=field_validators.Equal("tensorflow_saved_model_bundle"), required=True, load_only=True
    )
    tensorflow_version = fields.Version()
コード例 #4
0
class TensorflowJsWeightsEntry(_WeightsEntryBase):
    bioimageio_description = "Tensorflow Javascript weights format"
    weights_format = fields.String(validate=field_validators.Equal("tensorflow_js"), required=True, load_only=True)
    tensorflow_version = fields.Version()
コード例 #5
0
class KerasHdf5WeightsEntry(_WeightsEntryBase):
    bioimageio_description = "Keras HDF5 weights format"
    weights_format = fields.String(validate=field_validators.Equal("keras_hdf5"), required=True, load_only=True)
    tensorflow_version = fields.Version()
コード例 #6
0
class RDF(_BioImageIOSchema):
    class Meta:
        unknown = EXCLUDE

    bioimageio_description = f"""# BioImage.IO Resource Description File Specification {get_args(FormatVersion)[-1]}
This specification defines the fields used in a general BioImage.IO-compliant resource description file (`RDF`).
An RDF is stored as a YAML file and describes resources such as models, datasets, applications and notebooks. 
Note that models are described with an extended Model RDF specification.

The RDF contains mandatory and optional fields. In the following description, optional fields are indicated by 
_optional_. _optional*_ with an asterisk indicates the field is optional depending on the value in another field.
If no specialized RDF exists for the specified type (like model RDF for type='model') additional fields may be 
specified.
"""

    attachments = fields.Nested(
        Attachments(),
        bioimageio_description="Additional unknown keys are allowed.")

    authors_bioimageio_description = (
        "A list of authors. The authors are the creators of the specifications and the primary points of contact."
    )
    authors = fields.List(
        fields.Nested(Author()),
        bioimageio_description=authors_bioimageio_description)

    badges = fields.List(fields.Nested(Badge()),
                         bioimageio_description="a list of badges")

    cite_bioimageio_description = """A list of citation entries.
Each entry contains a mandatory `text` field and either one or both of `doi` and `url`.
E.g. the citation for the model architecture and/or the training data used."""
    cite = fields.List(fields.Nested(CiteEntry()),
                       bioimageio_description=cite_bioimageio_description)

    config_bioimageio_description = (
        "A custom configuration field that can contain any keys not present in the RDF spec. "
        "This means you should not store, for example, github repo URL in `config` since we already have the "
        "`git_repo` key defined in the spec.\n"
        "Keys in `config` may be very specific to a tool or consumer software. To avoid conflicted definitions, "
        "it is recommended to wrap configuration into a sub-field named with the specific domain or tool name, "
        """for example:

```yaml
   config:
      bioimage_io:  # here is the domain name
        my_custom_key: 3837283
        another_key:
           nested: value
      imagej:
        macro_dir: /path/to/macro/file
```
"""
        "If possible, please use [`snake_case`](https://en.wikipedia.org/wiki/Snake_case) for keys in `config`."
    )
    config = fields.YamlDict(
        bioimageio_descriptio=config_bioimageio_description)

    covers = fields.List(
        fields.Union([fields.URL(), fields.RelativeLocalPath()]),
        bioimageio_description=
        "A list of cover images provided by either a relative path to the model folder, or a "
        "hyperlink starting with 'http[s]'. Please use an image smaller than 500KB and an aspect ratio width to height "
        "of 2:1. The supported image formats are: 'jpg', 'png', 'gif'.",  # todo: field_validators image format
    )

    description = fields.String(
        required=True,
        bioimageio_description="A string containing a brief description.")

    documentation = fields.Union(
        [
            fields.URL(),
            fields.RelativeLocalPath(validate=field_validators.Attribute(
                "suffix",
                field_validators.Equal(
                    ".md",
                    error=
                    "{!r} is invalid; expected markdown file with '.md' extension."
                ),
            )),
        ],
        bioimageio_description=
        "URL or relative path to markdown file with additional documentation. "
        "For markdown files the recommended documentation file name is `README.md`.",
    )

    download_url = fields.URL(
        bioimageio_description="optional url to download the resource from")

    format_version = fields.String(
        required=True,
        bioimageio_description_order=0,
        bioimageio_description=
        ("Version of the BioImage.IO Resource Description File Specification used."
         f"The current general format version described here is {get_args(FormatVersion)[-1]}. "
         "Note: The general RDF format is not to be confused with specialized RDF format like the Model RDF format."
         ),
    )

    @validates_schema
    def format_version_matches_type(self, data, **kwargs):
        format_version = data.get("format_version")
        type_ = data.get("type")
        try:
            patched_format_version = get_patched_format_version(
                type_, format_version)
            if format_version.split(".") > patched_format_version.split("."):
                raise ValueError(
                    f"Unknown format_version {format_version} (latest patch: {patched_format_version}; latest format version: )"
                )
        except Exception as e:
            raise ValidationError(
                f"Invalid format_version {format_version} for RDF type {type_}. (error: {e})"
            )

    git_repo_bioimageio_description = "A url to the git repository, e.g. to Github or Gitlab."
    git_repo = fields.URL(
        bioimageio_description=git_repo_bioimageio_description)

    icon = fields.String(
        bioimageio_description="an icon for the resource"
    )  # todo: limit length? validate=field_validators.Length(max=1)

    id = fields.String(
        bioimageio_description="Unique id within a collection of resources.")
    license_bioimageio_description = (
        "A [SPDX license identifier](https://spdx.org/licenses/)(e.g. `CC-BY-4.0`, `MIT`, "
        "`BSD-2-Clause`). We don't support custom license beyond the SPDX license list, if you need that please send "
        "an Github issue to discuss your intentions with the community.")
    license = fields.String(  # todo: make mandatory?
        # validate=field_validators.OneOf(LICENSES),  # enforce license id
        bioimageio_description=license_bioimageio_description)

    @validates("license")
    def warn_about_deprecated_spdx_license(self, value: str):
        license_info = LICENSES.get(value)
        if license_info is None:
            self.warn(
                "license",
                f"{value} is not a recognized SPDX license identifier. See https://spdx.org/licenses/"
            )
        else:
            if license_info.get("isDeprecatedLicenseId", False):
                self.warn("license",
                          f"{value} ({license_info['name']}) is deprecated.")

            if not license_info.get("isFsfLibre", False):
                self.warn(
                    "license",
                    f"{value} ({license_info['name']}) is not FSF Free/libre.")

    links = fields.List(
        fields.String(),
        bioimageio_description="links to other bioimage.io resources")

    maintainers = fields.List(
        fields.Nested(Maintainer()),
        bioimageio_description="Maintainers of this resource.")

    name = fields.String(
        required=True,
        bioimageio_description="name of the resource, a human-friendly name")

    @validates
    def warn_about_long_name(self, value: str):
        if isinstance(value, str):
            if len(value) > 64:
                self.warn(
                    "name",
                    f"Length of name ({len(value)}) exceeds the recommended maximum length of 64 characters."
                )
        else:
            self.warn("name", f"Could not check length of name {value}.")

    rdf_source = fields.Union(
        [fields.URL(), fields.DOI()],
        bioimageio_description=
        "url or doi to the source of the resource definition")
    source = fields.Union(
        [fields.URI(), fields.RelativeLocalPath()],
        bioimageio_description=
        "url or local relative path to the source of the resource",
    )

    tags = fields.List(fields.String(),
                       bioimageio_description="A list of tags.")

    @validates("tags")
    def warn_about_tag_categories(self, value):
        if BIOIMAGEIO_SITE_CONFIG is None:
            error = BIOIMAGEIO_SITE_CONFIG_ERROR
        else:
            missing_categories = []
            try:
                categories = {
                    c["type"]: c.get("tag_categories", {})
                    for c in BIOIMAGEIO_SITE_CONFIG["resource_categories"]
                }.get(self.__class__.__name__.lower(), {})
                for cat, entries in categories.items():
                    if not any(e in value for e in entries):
                        missing_categories.append({cat: entries})
            except Exception as e:
                error = str(e)
            else:
                error = None
                if missing_categories:
                    self.warn(
                        "tags",
                        f"Missing tags for categories: {missing_categories}")

        if error is not None:
            self.warn("tags", f"could not check tag categories ({error})")

    type = fields.String(required=True)

    # todo: restrict valid RDF types?
    @validates("type")
    def validate_type(self, value):
        schema_type = self.__class__.__name__.lower()
        if value != schema_type:
            self.warn(
                "type",
                f"Unrecognized type '{value}'. Validating as {schema_type}.")

    version = fields.Version(
        bioimageio_description=
        "The version number of the model. The version number format must be a string in "
        "`MAJOR.MINOR.PATCH` format following the guidelines in Semantic Versioning 2.0.0 (see https://semver.org/), "
        "e.g. the initial version number should be `0.1.0`.")