Skip to content

Package eido Documentation

Package Overview

The eido package provides validation and filtering tools for PEPs (Portable Encapsulated Projects). It enables schema-based validation of project metadata and provides flexible filtering mechanisms.

Key Features

  • Schema Validation: Validate PEPs against JSON schemas
  • Sample Filtering: Filter samples based on custom criteria
  • Config Validation: Validate project configuration separately
  • Extensible Filtering: Support for custom filter plugins
  • Error Reporting: Detailed validation error messages

Installation

pip install eido

Quick Example

from eido import validate_project
from peppy import Project

# Load a project
prj = Project("project_config.yaml")

# Validate against a schema
validate_project(prj, "schema.yaml")

API Reference

Validation Functions

validate_project

validate_project(project, schema)

Validate a project object against a schema

:param peppy.Project project: a project object to validate :param str | dict schema: schema dict to validate against or a path to one from the error. Useful when used ith large projects

:return: None :raises EidoValidationError: if validation is unsuccessful

Source code in eido/validation.py
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
def validate_project(project: peppy.Project, schema: Union[str, dict]) -> None:
    """
    Validate a project object against a schema

    :param peppy.Project project: a project object to validate
    :param str | dict schema: schema dict to validate against or a path to one
    from the error. Useful when used ith large projects

    :return: None
    :raises EidoValidationError: if validation is unsuccessful
    """
    sample_name_colname = project.sample_name_colname
    schema_dicts = read_schema(schema=schema)
    for schema_dict in schema_dicts:
        project_dict = project.to_dict()
        _validate_object(
            project_dict, preprocess_schema(schema_dict), sample_name_colname
        )
        _LOGGER.debug("Project validation successful")

validate_sample

validate_sample(project, sample_name, schema)

Validate the selected sample object against a schema

:param peppy.Project project: a project object to validate :param str | int sample_name: name or index of the sample to validate :param str | dict schema: schema dict to validate against or a path to one

:raises EidoValidationError: if validation is unsuccessful

Source code in eido/validation.py
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
def validate_sample(
    project: peppy.Project, sample_name: Union[str, int], schema: Union[str, dict]
) -> None:
    """
    Validate the selected sample object against a schema

    :param peppy.Project project: a project object to validate
    :param str | int sample_name: name or index of the sample to validate
    :param str | dict schema: schema dict to validate against or a path to one

    :raises EidoValidationError: if validation is unsuccessful
    """
    sample = (
        project.samples[sample_name]
        if isinstance(sample_name, int)
        else project.get_sample(sample_name)
    )
    _validate_sample_object(
        sample=sample,
        schemas=read_schema(schema=schema),
    )

validate_config

validate_config(project, schema)

Validate the config part of the Project object against a schema

:param peppy.Project project: a project object to validate :param str | dict schema: schema dict to validate against or a path to one

Source code in eido/validation.py
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
def validate_config(
    project: Union[peppy.Project, dict], schema: Union[str, dict]
) -> None:
    """
    Validate the config part of the Project object against a schema

    :param peppy.Project project: a project object to validate
    :param str | dict schema: schema dict to validate against or a path to one
    """
    schema_dicts = read_schema(schema=schema)
    for schema_dict in schema_dicts:
        schema_cpy = preprocess_schema(dpcpy(schema_dict))
        try:
            del schema_cpy[PROP_KEY][SAMPLES_KEY]
        except KeyError:
            pass
        if "required" in schema_cpy:
            try:
                schema_cpy["required"].remove(SAMPLES_KEY)
            except ValueError:
                pass
        if isinstance(project, dict):
            _validate_object({"project": project}, schema_cpy)

        else:
            project_dict = project.to_dict()
            _validate_object(project_dict, schema_cpy)
            _LOGGER.debug("Config validation successful")

Schema Functions

read_schema

read_schema(schema)

Safely read schema from YAML-formatted file.

If the schema imports any other schemas, they will be read recursively.

:param str | Mapping schema: path to the schema file or schema in a dict form :return list[dict]: read schemas :raise TypeError: if the schema arg is neither a Mapping nor a file path or if the 'imports' sections in any of the schemas is not a list

Source code in eido/schema.py
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
def read_schema(schema):
    """
    Safely read schema from YAML-formatted file.

    If the schema imports any other schemas, they will be read recursively.

    :param str | Mapping schema: path to the schema file
        or schema in a dict form
    :return list[dict]: read schemas
    :raise TypeError: if the schema arg is neither a Mapping nor a file path or
        if the 'imports' sections in any of the schemas is not a list
    """

    def _recursively_read_schemas(x, lst):
        if "imports" in x:
            if isinstance(x["imports"], list):
                for sch in x["imports"]:
                    lst.extend(read_schema(sch))
            else:
                raise TypeError("In schema the 'imports' section has to be a list")
        lst.append(x)
        return lst

    schema_list = []
    if isinstance(schema, str):
        _LOGGER.debug(f"Reading schema: {schema}")
        schema = load_yaml(schema)
    if not isinstance(schema, dict):
        raise TypeError(
            f"schema has to be a dict, path to an existing file or URL to a remote one. "
            f"Got: {type(schema)}"
        )
    return _recursively_read_schemas(schema, schema_list)

Exceptions

EidoValidationError

EidoValidationError(message, errors_by_type)

Bases: EidoException

Object was not validated successfully according to schema.

Source code in eido/exceptions.py
43
44
45
46
def __init__(self, message, errors_by_type):
    super().__init__(message)
    self.errors_by_type = errors_by_type
    self.message = message