Skip to content

Commit

Permalink
ALIES INVASION (#1301)
Browse files Browse the repository at this point in the history
* add alias_required

* remove abc

* fix tests

* alias test WIP

* alias test WIP

* alias test WIP

* alias test WIP

* alias test WIP

* alias test WIP

* alias test WIP

* alias test WIP

* add aliases (#1302)

* alias registries and tests

* test classpaths exist

* fix mypy

* transitive aliases

* fix lint

* better error
  • Loading branch information
mike0sv authored Sep 18, 2024
1 parent 40817e1 commit 3a9e199
Show file tree
Hide file tree
Showing 168 changed files with 2,967 additions and 348 deletions.
14 changes: 14 additions & 0 deletions src/evidently/base_metric.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
from evidently.pydantic_utils import FrozenBaseMeta
from evidently.pydantic_utils import PolymorphicModel
from evidently.pydantic_utils import WithTestAndMetricDependencies
from evidently.pydantic_utils import autoregister
from evidently.pydantic_utils import get_value_fingerprint
from evidently.utils.data_preprocessing import DataDefinition

Expand All @@ -49,7 +50,10 @@ def fields(cls) -> FieldPath:

class MetricResult(PolymorphicModel, BaseResult, metaclass=WithFieldsPathMetaclass): # type: ignore[misc] # pydantic Config
class Config:
type_alias = "evidently:metric_result:MetricResult"
field_tags = {"type": {IncludeTags.TypeField}}
is_base_type = True
alias_required = True


class ErrorResult(BaseResult):
Expand All @@ -72,7 +76,11 @@ class DatasetType(Enum):
ADDITIONAL = "additional"


@autoregister
class ColumnName(EnumValueMixin, EvidentlyBaseModel):
class Config:
type_alias = "evidently:base:ColumnName"

name: str
display_name: str
dataset: DatasetType
Expand Down Expand Up @@ -217,10 +225,15 @@ def result_type(cls) -> Type[MetricResult]:

class BasePreset(EvidentlyBaseModel):
class Config:
type_alias = "evidently:base:BasePreset"
transitive_aliases = True
is_base_type = True


class Metric(WithTestAndMetricDependencies, Generic[TResult], metaclass=WithResultFieldPathMetaclass):
class Config:
is_base_type = True

_context: Optional["Context"] = None

options: Options
Expand Down Expand Up @@ -310,6 +323,7 @@ def get_options_fingerprint(self) -> FingerprintPart:

class ColumnMetricResult(MetricResult):
class Config:
type_alias = "evidently:metric_result:ColumnMetricResult"
field_tags = {
"column_name": {IncludeTags.Parameter},
"column_type": {IncludeTags.Parameter},
Expand Down
5 changes: 5 additions & 0 deletions src/evidently/calculations/data_drift.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@

class DriftStatsField(MetricResult):
class Config:
type_alias = "evidently:metric_result:DriftStatsField"
dict_exclude_fields = {"characteristic_examples", "characteristic_words", "correlations"}
# todo: after tests PR
field_tags = {
Expand All @@ -55,6 +56,7 @@ class Config:
class ColumnDataDriftMetrics(ColumnMetricResult):
class Config:
# todo: change to field_tags: render
type_alias = "evidently:metric_result:ColumnDataDriftMetrics"
dict_exclude_fields = {"scatter"}
pd_exclude_fields = {"scatter"}
field_tags = {
Expand Down Expand Up @@ -85,6 +87,9 @@ class DatasetDrift:


class DatasetDriftMetrics(MetricResult):
class Config:
type_alias = "evidently:metric_result:DatasetDriftMetrics"

number_of_columns: int
number_of_drifted_columns: int
share_of_drifted_columns: float
Expand Down
16 changes: 16 additions & 0 deletions src/evidently/collector/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from evidently.collector.storage import InMemoryStorage
from evidently.options.base import Options
from evidently.pydantic_utils import PolymorphicModel
from evidently.pydantic_utils import autoregister
from evidently.report import Report
from evidently.suite.base_suite import MetadataValueType
from evidently.test_suite import TestSuite
Expand All @@ -42,12 +43,19 @@ def save(self, path: str):


class CollectorTrigger(PolymorphicModel):
class Config:
is_base_type = True

@abc.abstractmethod
def is_ready(self, config: "CollectorConfig", storage: "CollectorStorage") -> bool:
raise NotImplementedError


@autoregister
class IntervalTrigger(CollectorTrigger):
class Config:
type_alias = "evidently:collector_trigger:IntervalTrigger"

interval: float = Field(gt=0)
last_triggered: float = 0

Expand All @@ -59,15 +67,23 @@ def is_ready(self, config: "CollectorConfig", storage: "CollectorStorage") -> bo
return is_ready


@autoregister
class RowsCountTrigger(CollectorTrigger):
class Config:
type_alias = "evidently:collector_trigger:RowsCountTrigger"

rows_count: int = Field(default=1, gt=0)

def is_ready(self, config: "CollectorConfig", storage: "CollectorStorage") -> bool:
buffer_size = storage.get_buffer_size(config.id)
return buffer_size > 0 and buffer_size >= self.rows_count


@autoregister
class RowsCountOrIntervalTrigger(CollectorTrigger):
class Config:
type_alias = "evidently:collector_trigger:RowsCountOrIntervalTrigger"

rows_count_trigger: RowsCountTrigger
interval_trigger: IntervalTrigger

Expand Down
6 changes: 6 additions & 0 deletions src/evidently/collector/storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

from evidently._pydantic_compat import BaseModel
from evidently.pydantic_utils import PolymorphicModel
from evidently.pydantic_utils import autoregister
from evidently.suite.base_suite import ReportBase


Expand Down Expand Up @@ -43,6 +44,7 @@ def __exit__(self, exc_type, exc_val, exc_tb):
class CollectorStorage(PolymorphicModel):
class Config:
underscore_attrs_are_private = True
is_base_type = True

_locks: Dict[str, Lock] = {}

Expand Down Expand Up @@ -85,7 +87,11 @@ def take_reports(self, id: str) -> Sequence[ReportPopper]:
raise NotImplementedError


@autoregister
class InMemoryStorage(CollectorStorage):
class Config:
type_alias = "evidently:collector_storage:InMemoryStorage"

max_log_events: int = 10

_buffers: Dict[str, List[Any]] = {}
Expand Down
2 changes: 2 additions & 0 deletions src/evidently/descriptors/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from . import _registry
from .custom_descriptor import CustomColumnEval
from .custom_descriptor import CustomPairColumnEval
from .hf_descriptor import HuggingFaceModel
Expand Down Expand Up @@ -54,4 +55,5 @@
"SentenceCount",
"Sentiment",
"RegExp",
"_registry",
]
102 changes: 102 additions & 0 deletions src/evidently/descriptors/_registry.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
from evidently.features.generated_features import FeatureDescriptor
from evidently.features.generated_features import GeneralDescriptor
from evidently.pydantic_utils import register_type_alias

register_type_alias(
FeatureDescriptor,
"evidently.descriptors.custom_descriptor.CustomColumnEval",
"evidently:descriptor:CustomColumnEval",
)
register_type_alias(
FeatureDescriptor, "evidently.descriptors.hf_descriptor.HuggingFaceModel", "evidently:descriptor:HuggingFaceModel"
)
register_type_alias(
FeatureDescriptor,
"evidently.descriptors.hf_descriptor.HuggingFaceToxicityModel",
"evidently:descriptor:HuggingFaceToxicityModel",
)
register_type_alias(
FeatureDescriptor, "evidently.descriptors.llm_judges.BiasLLMEval", "evidently:descriptor:BiasLLMEval"
)
register_type_alias(
FeatureDescriptor,
"evidently.descriptors.llm_judges.BinaryClassificationLLMEval",
"evidently:descriptor:BinaryClassificationLLMEval",
)
register_type_alias(
FeatureDescriptor,
"evidently.descriptors.llm_judges.ContextQualityLLMEval",
"evidently:descriptor:ContextQualityLLMEval",
)
register_type_alias(
FeatureDescriptor, "evidently.descriptors.llm_judges.DeclineLLMEval", "evidently:descriptor:DeclineLLMEval"
)
register_type_alias(FeatureDescriptor, "evidently.descriptors.llm_judges.LLMEval", "evidently:descriptor:LLMEval")
register_type_alias(
FeatureDescriptor, "evidently.descriptors.llm_judges.NegativityLLMEval", "evidently:descriptor:NegativityLLMEval"
)
register_type_alias(FeatureDescriptor, "evidently.descriptors.llm_judges.PIILLMEval", "evidently:descriptor:PIILLMEval")
register_type_alias(
FeatureDescriptor, "evidently.descriptors.llm_judges.ToxicityLLMEval", "evidently:descriptor:ToxicityLLMEval"
)
register_type_alias(
FeatureDescriptor,
"evidently.descriptors.non_letter_character_percentage_descriptor.NonLetterCharacterPercentage",
"evidently:descriptor:NonLetterCharacterPercentage",
)
register_type_alias(
FeatureDescriptor, "evidently.descriptors.oov_words_percentage_descriptor.OOV", "evidently:descriptor:OOV"
)
register_type_alias(
FeatureDescriptor, "evidently.descriptors.openai_descriptor.OpenAIPrompting", "evidently:descriptor:OpenAIPrompting"
)
register_type_alias(FeatureDescriptor, "evidently.descriptors.regexp_descriptor.RegExp", "evidently:descriptor:RegExp")
register_type_alias(
FeatureDescriptor,
"evidently.descriptors.semantic_similarity.SemanticSimilarity",
"evidently:descriptor:SemanticSimilarity",
)
register_type_alias(
FeatureDescriptor,
"evidently.descriptors.sentence_count_descriptor.SentenceCount",
"evidently:descriptor:SentenceCount",
)
register_type_alias(
FeatureDescriptor, "evidently.descriptors.sentiment_descriptor.Sentiment", "evidently:descriptor:Sentiment"
)
register_type_alias(
FeatureDescriptor, "evidently.descriptors.text_contains_descriptor.Contains", "evidently:descriptor:Contains"
)
register_type_alias(
FeatureDescriptor,
"evidently.descriptors.text_contains_descriptor.DoesNotContain",
"evidently:descriptor:DoesNotContain",
)
register_type_alias(
FeatureDescriptor, "evidently.descriptors.text_length_descriptor.TextLength", "evidently:descriptor:TextLength"
)
register_type_alias(
FeatureDescriptor, "evidently.descriptors.text_part_descriptor.BeginsWith", "evidently:descriptor:BeginsWith"
)
register_type_alias(
FeatureDescriptor, "evidently.descriptors.text_part_descriptor.EndsWith", "evidently:descriptor:EndsWith"
)
register_type_alias(
FeatureDescriptor,
"evidently.descriptors.trigger_words_presence_descriptor.TriggerWordsPresence",
"evidently:descriptor:TriggerWordsPresence",
)
register_type_alias(
FeatureDescriptor, "evidently.descriptors.word_count_descriptor.WordCount", "evidently:descriptor:WordCount"
)
register_type_alias(
FeatureDescriptor, "evidently.descriptors.words_descriptor.ExcludesWords", "evidently:descriptor:ExcludesWords"
)
register_type_alias(
FeatureDescriptor, "evidently.descriptors.words_descriptor.IncludesWords", "evidently:descriptor:IncludesWords"
)
register_type_alias(
GeneralDescriptor,
"evidently.descriptors.custom_descriptor.CustomPairColumnEval",
"evidently:descriptor:CustomPairColumnEval",
)
6 changes: 6 additions & 0 deletions src/evidently/descriptors/custom_descriptor.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@


class CustomColumnEval(FeatureDescriptor):
class Config:
type_alias = "evidently:descriptor:CustomColumnEval"

func: Callable[[pd.Series], pd.Series]
display_name: str
feature_type: Union[str, ColumnType]
Expand All @@ -29,6 +32,9 @@ def feature(self, column_name: str) -> GeneratedFeature:


class CustomPairColumnEval(GeneralDescriptor):
class Config:
type_alias = "evidently:descriptor:CustomPairColumnEval"

func: Callable[[pd.Series, pd.Series], pd.Series]
display_name: str
first_column: str
Expand Down
6 changes: 6 additions & 0 deletions src/evidently/descriptors/hf_descriptor.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@


class HuggingFaceModel(FeatureDescriptor):
class Config:
type_alias = "evidently:descriptor:HuggingFaceModel"

model: str
params: Optional[dict] = None

Expand All @@ -20,6 +23,9 @@ def feature(self, column_name: str) -> GeneratedFeature:


class HuggingFaceToxicityModel(FeatureDescriptor):
class Config:
type_alias = "evidently:descriptor:HuggingFaceToxicityModel"

model: Optional[str] = None
toxic_label: Optional[str] = None

Expand Down
24 changes: 24 additions & 0 deletions src/evidently/descriptors/llm_judges.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ def get_input_columns(self, column_name: str) -> Dict[str, str]:


class LLMEval(BaseLLMEval):
class Config:
type_alias = "evidently:descriptor:LLMEval"

name: ClassVar = "LLMEval"

template: BaseLLMPromptTemplate
Expand All @@ -61,6 +64,9 @@ def get_subcolumn(self) -> Optional[str]:


class BinaryClassificationLLMEval(BaseLLMEval):
class Config:
type_alias = "evidently:descriptor:BinaryClassificationLLMEval"

template: ClassVar[BinaryClassificationPromptTemplate]
include_category: Optional[bool] = None
include_score: Optional[bool] = None
Expand All @@ -81,6 +87,9 @@ def get_subcolumn(self) -> Optional[str]:


class NegativityLLMEval(BinaryClassificationLLMEval):
class Config:
type_alias = "evidently:descriptor:NegativityLLMEval"

name: ClassVar = "Negativity"
template: ClassVar = BinaryClassificationPromptTemplate(
criteria="""A "NEGATIVE" typically refers to a tendency to be overly critical, pessimistic, or cynical in attitude or tone.
Expand All @@ -98,6 +107,9 @@ class NegativityLLMEval(BinaryClassificationLLMEval):


class PIILLMEval(BinaryClassificationLLMEval):
class Config:
type_alias = "evidently:descriptor:PIILLMEval"

name: ClassVar = "PII"
template: ClassVar = BinaryClassificationPromptTemplate(
criteria="""Personally identifiable information (PII) is information that, when used alone or with other relevant data, can identify an individual.
Expand All @@ -116,6 +128,9 @@ class PIILLMEval(BinaryClassificationLLMEval):


class DeclineLLMEval(BinaryClassificationLLMEval):
class Config:
type_alias = "evidently:descriptor:DeclineLLMEval"

name: ClassVar = "Decline"
template: ClassVar = BinaryClassificationPromptTemplate(
criteria="""A "DECLINE" typically refers to a refusal or a polite rejection to do something.
Expand All @@ -131,6 +146,9 @@ class DeclineLLMEval(BinaryClassificationLLMEval):


class ContextQualityLLMEval(BinaryClassificationLLMEval):
class Config:
type_alias = "evidently:descriptor:ContextQualityLLMEval"

name: ClassVar = "ContextQuality"

template: ClassVar = BinaryClassificationPromptTemplate(
Expand Down Expand Up @@ -164,6 +182,9 @@ def get_input_columns(self, column_name: str) -> Dict[str, str]:


class BiasLLMEval(BinaryClassificationLLMEval):
class Config:
type_alias = "evidently:descriptor:BiasLLMEval"

name: ClassVar = "Bias"
template: ClassVar = BinaryClassificationPromptTemplate(
criteria="""A "BIAS" typically refers to an inclination or prejudice for or against one person or group, especially in a way considered to be unfair.
Expand All @@ -185,6 +206,9 @@ class BiasLLMEval(BinaryClassificationLLMEval):


class ToxicityLLMEval(BinaryClassificationLLMEval):
class Config:
type_alias = "evidently:descriptor:ToxicityLLMEval"

name: ClassVar = "Toxicity"
template: ClassVar = BinaryClassificationPromptTemplate(
criteria="""A TOXICITY typically refers to content that includes harmful, offensive, or derogatory language.
Expand Down
Loading

0 comments on commit 3a9e199

Please sign in to comment.