92 lines
3.6 KiB
Python
92 lines
3.6 KiB
Python
|
|
from datetime import datetime
|
||
|
|
from typing import Any, Dict, Optional
|
||
|
|
from typing_extensions import deprecated
|
||
|
|
from pydantic import Field, field_validator, field_serializer
|
||
|
|
from guardrails_ai.types import ValidationResult, Outcome, PassResult, FailResult
|
||
|
|
from guardrails.classes.generic.arbitrary_model import ArbitraryModel
|
||
|
|
|
||
|
|
|
||
|
|
class ValidatorLogs(ArbitraryModel):
|
||
|
|
"""Logs for a single validator execution."""
|
||
|
|
|
||
|
|
validator_name: str = Field(
|
||
|
|
description="The class name of the validator.", alias="validatorName"
|
||
|
|
)
|
||
|
|
registered_name: str = Field(
|
||
|
|
description="The registry id of the validator.", alias="registeredName"
|
||
|
|
)
|
||
|
|
value_before_validation: Any = Field(alias="valueBeforeValidation")
|
||
|
|
validation_result: Optional[ValidationResult] = Field(
|
||
|
|
default=None, alias="validationResult"
|
||
|
|
)
|
||
|
|
value_after_validation: Optional[Any] = Field(
|
||
|
|
default=None, alias="valueAfterValidation"
|
||
|
|
)
|
||
|
|
start_time: Optional[datetime] = Field(default=None, alias="startTime")
|
||
|
|
end_time: Optional[datetime] = Field(default=None, alias="endTime")
|
||
|
|
instance_id: Optional[int] = Field(default=None, alias="instanceId")
|
||
|
|
property_path: str = Field(
|
||
|
|
description="The JSON path to the property which was validated that produced"
|
||
|
|
" this log.",
|
||
|
|
alias="propertyPath",
|
||
|
|
)
|
||
|
|
|
||
|
|
@field_serializer("start_time")
|
||
|
|
def serialize_start_time(self, start_time: datetime | None) -> str | None:
|
||
|
|
if start_time is None:
|
||
|
|
return None
|
||
|
|
|
||
|
|
return start_time.isoformat()
|
||
|
|
|
||
|
|
@field_serializer("end_time")
|
||
|
|
def serialize_end_time(self, end_time: datetime | None) -> str | None:
|
||
|
|
if end_time is None:
|
||
|
|
return None
|
||
|
|
|
||
|
|
return end_time.isoformat()
|
||
|
|
|
||
|
|
# NOTE: It shouldn't be necessary to add this serializer just to call model_dump,
|
||
|
|
# but it is to get the correct serialized output.
|
||
|
|
@field_serializer("validation_result")
|
||
|
|
def serialize_validation_result(
|
||
|
|
self, validation_result: ValidationResult | None
|
||
|
|
) -> dict[str, Any] | None:
|
||
|
|
if validation_result is None:
|
||
|
|
return None
|
||
|
|
return validation_result.model_dump(exclude_none=True, by_alias=True)
|
||
|
|
|
||
|
|
@field_validator("validation_result", mode="before")
|
||
|
|
@classmethod
|
||
|
|
def deserialize_validation_result(
|
||
|
|
cls, validation_result: Any
|
||
|
|
) -> ValidationResult | None:
|
||
|
|
if validation_result is None:
|
||
|
|
return None
|
||
|
|
elif isinstance(validation_result, ValidationResult):
|
||
|
|
return validation_result
|
||
|
|
elif isinstance(validation_result, dict):
|
||
|
|
outcome = validation_result.get("outcome")
|
||
|
|
if outcome == Outcome.PASS:
|
||
|
|
return PassResult.model_validate(validation_result)
|
||
|
|
elif outcome == Outcome.FAIL:
|
||
|
|
return FailResult.model_validate(validation_result)
|
||
|
|
return ValidationResult.model_validate(validation_result)
|
||
|
|
|
||
|
|
@deprecated("Use ValidatorLogs.model_dump() instead.")
|
||
|
|
def to_interface(self) -> dict[str, Any]:
|
||
|
|
return self.model_dump(exclude_none=True, by_alias=True)
|
||
|
|
|
||
|
|
@deprecated("Use ValidatorLogs.model_dump() instead.")
|
||
|
|
def to_dict(self) -> Dict[str, Any]:
|
||
|
|
return self.model_dump(exclude_none=True, by_alias=True)
|
||
|
|
|
||
|
|
@classmethod
|
||
|
|
@deprecated("Use ValidatorLogs.model_validate() instead.")
|
||
|
|
def from_interface(cls, i_validator_log: Any) -> "ValidatorLogs":
|
||
|
|
return cls.model_validate(i_validator_log)
|
||
|
|
|
||
|
|
@classmethod
|
||
|
|
@deprecated("Use ValidatorLogs.model_validate() instead.")
|
||
|
|
def from_dict(cls, obj: Any) -> "ValidatorLogs":
|
||
|
|
return cls.model_validate(obj)
|