Skip to content

validated_spec

mlte/spec/validated_spec.py

ValidatedSpec class implementation.

ValidatedSpec

Bases: Artifact

ValidatedSpec represents a spec with validated results.

Source code in mlte/validation/validated_spec.py
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 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
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
class ValidatedSpec(Artifact):
    """
    ValidatedSpec represents a spec with validated results.
    """

    def __init__(
        self,
        identifier: str = DEFAULT_VALIDATED_SPEC_ID,
        spec: Spec = Spec(),
        results: Dict[str, Dict[str, Result]] = {},
    ):
        """
        Initialize a ValidatedSpec instance.

        :param spec: The Spec
        :param results: The validation Results for the Spec
        """
        super().__init__(identifier, ArtifactType.VALIDATED_SPEC)

        self.spec = spec
        """The spec that we validated."""

        self.results = results
        """The validation results for the spec, by QACategory."""

        # Check that all conditions have results.
        for category, conditions in self.spec.qa_categories.items():
            for measurement_id in conditions.keys():
                if (
                    category.name not in self.results
                    or measurement_id not in self.results[category.name]
                ):
                    raise RuntimeError(
                        f"Id '{measurement_id}' does not have a result."
                    )

    def to_model(self) -> ArtifactModel:
        """
        Generates a model representation of the ValidatedSpec.
        :return: The serialized model
        """
        spec_artifact_model = self.spec.to_model()
        spec_body_model: SpecModel = typing.cast(
            SpecModel, spec_artifact_model.body
        )

        return ArtifactModel(
            header=self.build_artifact_header(),
            body=ValidatedSpecModel(
                spec_identifier=self.spec.identifier,
                spec=spec_body_model,
                results={
                    prop_name: {
                        measure_id: result.to_model()
                        for measure_id, result in results.items()
                    }
                    for prop_name, results in self.results.items()
                },
            ),
        )

    @classmethod
    def from_model(cls, model: ArtifactModel) -> ValidatedSpec:
        """
        Deserialize ValidatedSpec content from model.
        :param model: The model
        :return: The deserialized specification
        """
        assert (
            model.header.type == ArtifactType.VALIDATED_SPEC
        ), "Broken precondition."
        body = typing.cast(ValidatedSpecModel, model.body)

        # Build the spec and ValidatedSpec
        return ValidatedSpec(
            identifier=model.header.identifier,
            spec=Spec(
                body.spec_identifier,
                (
                    Spec.to_qa_category_dict(body.spec.qa_categories)
                    if body.spec is not None
                    else {}
                ),
            ),
            results={
                prop_name: {
                    measure_id: Result.from_model(result)
                    for measure_id, result in results.items()
                }
                for prop_name, results in body.results.items()
            },
        )

    def print_results(self, type: str = "all"):
        """Prints the validated results per property, can be filtered by result type."""
        if type not in ["all", "Success", "Failure", "Info"]:
            raise RuntimeError(f"Invalid type: {type}")

        for category, details in self.results.items():
            print(f"Quality attribute category: {category}")
            for id, result in details.items():
                if type == "all" or type == str(result):
                    print(
                        f" > Measurement: {id}, result: {result}, details: {result.message}"
                    )

    @staticmethod
    def get_default_id() -> str:
        """Overriden"""
        return DEFAULT_VALIDATED_SPEC_ID

    def __eq__(self, other: object) -> bool:
        """Test ValidatedSpec instance for equality."""
        if not isinstance(other, ValidatedSpec):
            return False
        return self._equal(other)

results = results instance-attribute

The validation results for the spec, by QACategory.

spec = spec instance-attribute

The spec that we validated.

__eq__(other)

Test ValidatedSpec instance for equality.

Source code in mlte/validation/validated_spec.py
138
139
140
141
142
def __eq__(self, other: object) -> bool:
    """Test ValidatedSpec instance for equality."""
    if not isinstance(other, ValidatedSpec):
        return False
    return self._equal(other)

__init__(identifier=DEFAULT_VALIDATED_SPEC_ID, spec=Spec(), results={})

Initialize a ValidatedSpec instance.

Parameters:

Name Type Description Default
spec Spec

The Spec

Spec()
results Dict[str, Dict[str, Result]]

The validation Results for the Spec

{}
Source code in mlte/validation/validated_spec.py
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
def __init__(
    self,
    identifier: str = DEFAULT_VALIDATED_SPEC_ID,
    spec: Spec = Spec(),
    results: Dict[str, Dict[str, Result]] = {},
):
    """
    Initialize a ValidatedSpec instance.

    :param spec: The Spec
    :param results: The validation Results for the Spec
    """
    super().__init__(identifier, ArtifactType.VALIDATED_SPEC)

    self.spec = spec
    """The spec that we validated."""

    self.results = results
    """The validation results for the spec, by QACategory."""

    # Check that all conditions have results.
    for category, conditions in self.spec.qa_categories.items():
        for measurement_id in conditions.keys():
            if (
                category.name not in self.results
                or measurement_id not in self.results[category.name]
            ):
                raise RuntimeError(
                    f"Id '{measurement_id}' does not have a result."
                )

from_model(model) classmethod

Deserialize ValidatedSpec content from model.

Parameters:

Name Type Description Default
model ArtifactModel

The model

required

Returns:

Type Description
ValidatedSpec

The deserialized specification

Source code in mlte/validation/validated_spec.py
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
@classmethod
def from_model(cls, model: ArtifactModel) -> ValidatedSpec:
    """
    Deserialize ValidatedSpec content from model.
    :param model: The model
    :return: The deserialized specification
    """
    assert (
        model.header.type == ArtifactType.VALIDATED_SPEC
    ), "Broken precondition."
    body = typing.cast(ValidatedSpecModel, model.body)

    # Build the spec and ValidatedSpec
    return ValidatedSpec(
        identifier=model.header.identifier,
        spec=Spec(
            body.spec_identifier,
            (
                Spec.to_qa_category_dict(body.spec.qa_categories)
                if body.spec is not None
                else {}
            ),
        ),
        results={
            prop_name: {
                measure_id: Result.from_model(result)
                for measure_id, result in results.items()
            }
            for prop_name, results in body.results.items()
        },
    )

get_default_id() staticmethod

Overriden

Source code in mlte/validation/validated_spec.py
133
134
135
136
@staticmethod
def get_default_id() -> str:
    """Overriden"""
    return DEFAULT_VALIDATED_SPEC_ID

print_results(type='all')

Prints the validated results per property, can be filtered by result type.

Source code in mlte/validation/validated_spec.py
120
121
122
123
124
125
126
127
128
129
130
131
def print_results(self, type: str = "all"):
    """Prints the validated results per property, can be filtered by result type."""
    if type not in ["all", "Success", "Failure", "Info"]:
        raise RuntimeError(f"Invalid type: {type}")

    for category, details in self.results.items():
        print(f"Quality attribute category: {category}")
        for id, result in details.items():
            if type == "all" or type == str(result):
                print(
                    f" > Measurement: {id}, result: {result}, details: {result.message}"
                )

to_model()

Generates a model representation of the ValidatedSpec.

Returns:

Type Description
ArtifactModel

The serialized model

Source code in mlte/validation/validated_spec.py
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
def to_model(self) -> ArtifactModel:
    """
    Generates a model representation of the ValidatedSpec.
    :return: The serialized model
    """
    spec_artifact_model = self.spec.to_model()
    spec_body_model: SpecModel = typing.cast(
        SpecModel, spec_artifact_model.body
    )

    return ArtifactModel(
        header=self.build_artifact_header(),
        body=ValidatedSpecModel(
            spec_identifier=self.spec.identifier,
            spec=spec_body_model,
            results={
                prop_name: {
                    measure_id: result.to_model()
                    for measure_id, result in results.items()
                }
                for prop_name, results in self.results.items()
            },
        ),
    )