Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Implementation:Evidentlyai Evidently Pydantic Utils

From Leeroopedia
Revision as of 12:29, 16 February 2026 by Admin (talk | contribs) (Auto-imported from implementations/Evidentlyai_Evidently_Pydantic_Utils.md)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Knowledge Sources
Domains Serialization, Framework Infrastructure, Type System
Last Updated 2026-02-14 12:00 GMT

Overview

Provides foundational pydantic utility classes for Evidently's type system, including polymorphic model serialization/deserialization, frozen immutable models, fingerprint computation, field path navigation, and configuration management.

Description

The pydantic_utils module is a core infrastructure module that powers Evidently's serialization, type aliasing, and model identity system. All metric types, descriptors, tests, and configuration objects inherit from the classes defined here.

Key Classes:

  • FrozenBaseModel -- An immutable pydantic BaseModel with a custom metaclass (FrozenBaseMeta) that sets frozen = True. Provides:
    • Immutable fields after initialization (raises AttributeError on reassignment).
    • Custom __hash__ for use as dict keys and in sets.
    • Support for private attributes during initialization via __init_values__.
  • PolymorphicModel -- Enables polymorphic serialization/deserialization of model hierarchies. Features:
    • Type aliasing: Each subclass gets a type field (Literal type) that identifies it during deserialization.
    • Auto-registration: Subclasses are automatically registered via __init_subclass__.
    • Alias system: register_type_alias(), register_loaded_alias(), and @autoregister for managing type lookups.
    • Dynamic import: load_alias() can import subclasses by classpath with security prefix checks via ALLOWED_TYPE_PREFIXES.
    • Config options: type_alias, alias_required, transitive_aliases, is_base_type.
  • EvidentlyBaseModel -- Combines FrozenBaseModel and PolymorphicModel. The primary base class for all Evidently configuration objects. Provides:
    • Fingerprinting: get_fingerprint() computes an MD5-based fingerprint from class path and field values. get_fingerprint_parts() returns the tuple of (field_name, field_value_fingerprint) pairs.
    • Serialization: load(path, fmt) and dump(path, fmt) support both JSON and YAML formats.
    • Update: update(**kwargs) creates a new instance with modified fields.
  • AutoAliasMixin -- Mixin that auto-generates type aliases in the format evidently:{alias_type}:{ClassName}. Used by MetricResult, MetricTest, BoundTest, and Metric classes.
  • FieldPath -- A path navigation utility for traversing nested pydantic model structures. Supports:
    • Attribute-style access: path.field.subfield.
    • Mapping (dict) traversal with keys.
    • list_fields(), list_nested_fields(), list_nested_fields_with_tags() for introspecting model hierarchies.
    • Tag-based field filtering using FieldTags enum (Parameter, Current, Reference, Render, TypeField, Extra).
  • FieldInfo -- Frozen model storing field path, tags, and classpath information for serialized field metadata.

Utility Functions:

  • get_value_fingerprint(value) -- Recursively computes a hashable fingerprint part for any value (primitives, models, dicts, lists, sets, enums, callables).
  • all_subclasses(cls) -- Recursively collects all subclasses of a type.
  • get_base_class(cls) -- Finds the nearest base class marked with is_base_type = True in the MRO.
  • get_classpath(cls) -- Returns the full module path of a class.
  • pydantic_type_validator(type_) -- Decorator for registering custom pydantic validators for specific types.

Mixins:

  • EnumValueMixin -- Overrides dict() to serialize enum fields as their raw values.
  • ExcludeNoneMixin -- Overrides dict() to always exclude None values.
  • WithTestAndMetricDependencies -- Iterates over fields to yield metric/test dependencies.

Type Aliases:

  • Fingerprint -- str type alias for MD5 fingerprint strings.
  • FingerprintPart -- Recursive union type for fingerprint components.

Usage

Use this module when:

  • Creating new Evidently model classes that need serialization, polymorphism, or fingerprinting.
  • Building custom metrics, tests, or descriptors that extend the Evidently type system.
  • Navigating model field hierarchies programmatically with FieldPath.
  • Working with the type alias/registration system for plugin or extension development.

Code Reference

Source Location

Signature

class FrozenBaseModel(BaseModel, metaclass=FrozenBaseMeta):
    def __init__(self, **data: Any): ...
    def __hash__(self): ...

class PolymorphicModel(BaseModel):
    type: str = Field("")
    @classmethod
    def __get_type__(cls) -> str: ...
    @classmethod
    def validate(cls, value: Any) -> TPM: ...
    @classmethod
    def load_alias(cls, typename): ...

class EvidentlyBaseModel(FrozenBaseModel, PolymorphicModel):
    def get_fingerprint(self) -> Fingerprint: ...
    def get_fingerprint_parts(self) -> Tuple[FingerprintPart, ...]: ...
    def update(self, **kwargs) -> EBM: ...
    @classmethod
    def load(cls, path: str, fmt=None) -> EBM: ...
    def dump(self, path: str, fmt=None): ...

class AutoAliasMixin:
    __alias_type__: ClassVar[str]
    @classmethod
    def __get_type__(cls) -> str: ...

class FieldPath:
    def __init__(self, path: List[Any], cls_or_instance, is_mapping=False): ...
    def child(self, item: str) -> "FieldPath": ...
    def list_fields(self) -> List[str]: ...
    def list_nested_fields(self, exclude=None) -> List[str]: ...
    def list_nested_fields_with_tags(self) -> List[Tuple[str, Set[IncludeTags]]]: ...

def get_value_fingerprint(value: Any) -> FingerprintPart: ...
def all_subclasses(cls: Type[T]) -> Set[Type[T]]: ...
def get_base_class(cls, ensure_parent=False) -> Type[PolymorphicModel]: ...
def register_type_alias(base_class, classpath: str, alias: str): ...

Import

from evidently.pydantic_utils import (
    EvidentlyBaseModel,
    FrozenBaseModel,
    PolymorphicModel,
    AutoAliasMixin,
    Fingerprint,
    FingerprintPart,
    FieldPath,
    FieldInfo,
    FieldTags,
    EnumValueMixin,
    ExcludeNoneMixin,
    get_value_fingerprint,
    all_subclasses,
    get_base_class,
    get_classpath,
    register_type_alias,
    autoregister,
    pydantic_type_validator,
)

I/O Contract

Inputs

Name Type Required Description
**data Dict[str, Any] Yes Keyword arguments for model field values (FrozenBaseModel/EvidentlyBaseModel constructors)
path str Yes (load/dump) File path for loading or saving model configuration (JSON or YAML)
fmt Literal["json", "yaml", None] No Format override; if None, inferred from file extension
value Any Yes (get_value_fingerprint) Value to compute fingerprint for

Outputs

Name Type Description
Fingerprint str MD5 hex digest string identifying a model instance
FingerprintPart Union[None, int, str, float, bool, bytes, Tuple] Hashable component of a fingerprint
FieldPath FieldPath Path navigator object for model field traversal
FieldInfo FieldInfo Frozen model with path, tags, and classpath for a field

Usage Examples

Creating a Custom EvidentlyBaseModel

from evidently.pydantic_utils import EvidentlyBaseModel

class MyConfig(EvidentlyBaseModel):
    class Config:
        type_alias = "evidently:custom:MyConfig"

    threshold: float = 0.5
    column: str = "target"

config = MyConfig(threshold=0.8, column="prediction")
fingerprint = config.get_fingerprint()
print(f"Fingerprint: {fingerprint}")

Loading and Saving Configurations

# Save to YAML
config.dump("my_config.yaml")

# Load from YAML
loaded = MyConfig.load("my_config.yaml")

# Save to JSON
config.dump("my_config.json")

Navigating Model Fields with FieldPath

from evidently.pydantic_utils import FieldPath

# Navigate from a model class
path = FieldPath([], MyConfig)
fields = path.list_fields()  # ["threshold", "column", "type"]

# Navigate from an instance
path = FieldPath([], config)
nested = path.list_nested_fields()

Using Polymorphic Deserialization

from evidently._pydantic_compat import parse_obj_as
from evidently.pydantic_utils import EvidentlyBaseModel

# Deserialize with polymorphic type resolution
data = {"type": "evidently:custom:MyConfig", "threshold": 0.9, "column": "score"}
obj = parse_obj_as(EvidentlyBaseModel, data)
# obj is an instance of MyConfig

Related Pages

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment