diff --git a/docs/book/component-guide/data-validators/evidently.md b/docs/book/component-guide/data-validators/evidently.md index c3b3f28d3b1..450e45e4437 100644 --- a/docs/book/component-guide/data-validators/evidently.md +++ b/docs/book/component-guide/data-validators/evidently.md @@ -100,11 +100,11 @@ text_data_report = evidently_report_step.with_options( The configuration shown in the example is the equivalent of running the following Evidently code inside the step: ```python -from evidently.metrics import ColumnRegExpMetric -from evidently.metric_preset import DataQualityPreset, TextOverviewPreset -from evidently import ColumnMapping -from evidently.report import Report -from evidently.metrics.base_metric import generate_column_metrics +from evidently.legacy.metrics import ColumnRegExpMetric +from evidently.legacy.metric_preset import DataQualityPreset, TextOverviewPreset +from evidently.legacy.pipeline.column_mapping import ColumnMapping +from evidently.legacy.report import Report +from evidently.legacy.metrics.base_metric import generate_column_metrics import nltk nltk.download("words") @@ -154,11 +154,11 @@ We configure the `evidently_report_step` using parameters that you would normall There are several ways you can reference the Evidently metrics when configuring `EvidentlyMetricConfig` items: * by class name: this is the easiest way to reference an Evidently metric. You can use the name of a metric or metric preset class as it appears in the Evidently documentation (e.g.`"DataQualityPreset"`, `"DatasetDriftMetric"`). -* by full class path: you can also use the full Python class path of the metric or metric preset class ( e.g. `"evidently.metric_preset.DataQualityPreset"`, `"evidently.metrics.DatasetDriftMetric"`). This is useful if you want to use metrics or metric presets that are not included in Evidently library. +* by full class path: you can also use the full Python class path of the metric or metric preset class ( e.g. `"evidently.legacy.metric_preset.DataQualityPreset"`, `"evidently.legacy.metrics.DatasetDriftMetric"`). This is useful if you want to use metrics or metric presets that are not included in Evidently library. * by passing in the class itself: you can also import and pass in an Evidently metric or metric preset class itself, e.g.: ```python - from evidently.metrics import DatasetDriftMetric + from evidently.legacy.metrics import DatasetDriftMetric ... @@ -221,7 +221,7 @@ text_data_report = evidently_report_step.with_options( parameters=dict( report_options = [ ( - "evidently.options.ColorOptions", { + "evidently.legacy.options.ColorOptions", { "primary_color": "#5a86ad", "fill_color": "#fff4f2", "zero_line_color": "#016795", @@ -289,11 +289,11 @@ text_data_test = evidently_test_step.with_options( The configuration shown in the example is the equivalent of running the following Evidently code inside the step: ```python -from evidently.tests import TestColumnRegExp -from evidently.test_preset import DataQualityTestPreset -from evidently import ColumnMapping -from evidently.test_suite import TestSuite -from evidently.tests.base_test import generate_column_tests +from evidently.legacy.tests import TestColumnRegExp +from evidently.legacy.test_preset import DataQualityTestPreset +from evidently.legacy.pipeline.column_mapping import ColumnMapping +from evidently.legacy.test_suite import TestSuite +from evidently.legacy.tests.base_test import generate_column_tests import nltk nltk.download("words") @@ -342,11 +342,11 @@ We configure the `evidently_test_step` using parameters that you would normally There are several ways you can reference the Evidently tests when configuring `EvidentlyTestConfig` items, similar to how you reference them in an `EvidentlyMetricConfig` object: * by class name: this is the easiest way to reference an Evidently test. You can use the name of a test or test preset class as it appears in the Evidently documentation (e.g.`"DataQualityTestPreset"`, `"TestColumnRegExp"`). -* by full class path: you can also use the full Python class path of the test or test preset class ( e.g. `"evidently.test_preset.DataQualityTestPreset"`, `"evidently.tests.TestColumnRegExp"`). This is useful if you want to use tests or test presets that are not included in Evidently library. +* by full class path: you can also use the full Python class path of the test or test preset class ( e.g. `"evidently.legacy.test_preset.DataQualityTestPreset"`, `"evidently.legacy.tests.TestColumnRegExp"`). This is useful if you want to use tests or test presets that are not included in Evidently library. * by passing in the class itself: you can also import and pass in an Evidently test or test preset class itself, e.g.: ```python - from evidently.tests import TestColumnRegExp + from evidently.legacy.tests import TestColumnRegExp ... @@ -398,7 +398,7 @@ text_data_test = evidently_test_step.with_options( parameters=dict( test_options = [ ( - "evidently.options.ColorOptions", { + "evidently.legacy.options.ColorOptions", { "primary_color": "#5a86ad", "fill_color": "#fff4f2", "zero_line_color": "#016795", @@ -423,7 +423,7 @@ All you have to do is call the Evidently Data Validator methods when you need to from typing import Annotated from typing import Tuple import pandas as pd -from evidently.pipeline.column_mapping import ColumnMapping +from evidently.legacy.pipeline.column_mapping import ColumnMapping from zenml.integrations.evidently.data_validators import EvidentlyDataValidator from zenml.integrations.evidently.metrics import EvidentlyMetricConfig from zenml.integrations.evidently.tests import EvidentlyTestConfig @@ -544,11 +544,11 @@ You can use the Evidently library directly in your custom pipeline steps, e.g.: from typing import Annotated from typing import Tuple import pandas as pd -from evidently.report import Report -import evidently.metric_preset as metric_preset -from evidently.test_suite import TestSuite -import evidently.test_preset as test_preset -from evidently.pipeline.column_mapping import ColumnMapping +from evidently.legacy.report import Report +from evidently.legacy.metric_preset import DataQualityPreset +from evidently.legacy.test_suite import TestSuite +from evidently.legacy.test_preset import DataQualityTestPreset +from evidently.legacy.pipeline.column_mapping import ColumnMapping from zenml.types import HTMLString from zenml import step @@ -571,7 +571,7 @@ def data_profiler( # pre-processing (e.g. dataset preparation) can take place here - report = Report(metrics=[metric_preset.DataQualityPreset()]) + report = Report(metrics=[DataQualityPreset()]) report.run( current_data=dataset, reference_data=dataset, @@ -600,8 +600,8 @@ def data_tester( # pre-processing (e.g. dataset preparation) can take place here - test_suite = TestSuite(metrics=[test_preset.DataQualityTestPreset()]) - report.run( + test_suite = TestSuite(tests=[DataQualityTestPreset()]) + test_suite.run( current_data=dataset, reference_data=dataset, ) diff --git a/src/zenml/integrations/evidently/__init__.py b/src/zenml/integrations/evidently/__init__.py index 13a6bf01d86..50749ee9e39 100644 --- a/src/zenml/integrations/evidently/__init__.py +++ b/src/zenml/integrations/evidently/__init__.py @@ -54,9 +54,8 @@ class EvidentlyIntegration(Integration): NAME = EVIDENTLY REQUIREMENTS = [ - "evidently>=0.4.16,<=0.4.22", + "evidently>=0.5.0,<1.0", "tenacity!=8.4.0", # https://github.com/jd/tenacity/issues/471 - "numpy<2.0.0", # evidently is not compatible with NumPy 2.0 ] REQUIREMENTS_IGNORED_ON_UNINSTALL = ["tenacity", "pandas"] @@ -75,8 +74,9 @@ def get_requirements( """ from zenml.integrations.pandas import PandasIntegration - return cls.REQUIREMENTS + \ - PandasIntegration.get_requirements(target_os=target_os, python_version=python_version) + return cls.REQUIREMENTS + PandasIntegration.get_requirements( + target_os=target_os, python_version=python_version + ) @classmethod def flavors(cls) -> List[Type[Flavor]]: diff --git a/src/zenml/integrations/evidently/column_mapping.py b/src/zenml/integrations/evidently/column_mapping.py index 37f9dd505d0..9a4e9997ba4 100644 --- a/src/zenml/integrations/evidently/column_mapping.py +++ b/src/zenml/integrations/evidently/column_mapping.py @@ -15,7 +15,9 @@ from typing import List, Optional, Sequence, Union -from evidently import ColumnMapping # type: ignore[import-untyped] +from evidently.legacy.pipeline.column_mapping import ( # type: ignore[import-untyped] + ColumnMapping, +) from pydantic import BaseModel, ConfigDict, Field diff --git a/src/zenml/integrations/evidently/data_validators/evidently_data_validator.py b/src/zenml/integrations/evidently/data_validators/evidently_data_validator.py index da3b1c6869d..92a240af671 100644 --- a/src/zenml/integrations/evidently/data_validators/evidently_data_validator.py +++ b/src/zenml/integrations/evidently/data_validators/evidently_data_validator.py @@ -15,6 +15,7 @@ import os from typing import ( + TYPE_CHECKING, Any, ClassVar, Dict, @@ -25,19 +26,27 @@ ) import pandas as pd -from evidently.pipeline.column_mapping import ColumnMapping # type: ignore -from evidently.report import Report # type: ignore -from evidently.test_suite import TestSuite # type: ignore + +if TYPE_CHECKING: + from evidently.legacy.pipeline.column_mapping import ( # type: ignore[import-untyped] + ColumnMapping, + ) + from evidently.legacy.report import Report # type: ignore[import-untyped] + from evidently.legacy.test_suite import ( # type: ignore[import-untyped] + TestSuite, + ) from zenml.data_validators import BaseDataValidator, BaseDataValidatorFlavor from zenml.integrations.evidently.flavors.evidently_data_validator_flavor import ( EvidentlyDataValidatorFlavor, ) -from zenml.integrations.evidently.metrics import EvidentlyMetricConfig -from zenml.integrations.evidently.tests import EvidentlyTestConfig from zenml.logger import get_logger from zenml.utils import source_utils +if TYPE_CHECKING: + from zenml.integrations.evidently.metrics import EvidentlyMetricConfig + from zenml.integrations.evidently.tests import EvidentlyTestConfig + logger = get_logger(__name__) @@ -69,7 +78,7 @@ class with Evidently options ```python options = [ ( - "evidently.options.ColorOptions",{ + "evidently.legacy.options.ColorOptions",{ "primary_color": "#5a86ad", "fill_color": "#fff4f2", "zero_line_color": "#016795", @@ -83,7 +92,7 @@ class with Evidently options This is the same as saying: ```python - from evidently.options import ColorOptions + from evidently.legacy.options import ColorOptions color_scheme = ColorOptions() color_scheme.primary_color = "#5a86ad" @@ -166,12 +175,12 @@ def data_profiling( self, dataset: pd.DataFrame, comparison_dataset: Optional[pd.DataFrame] = None, - profile_list: Optional[Sequence[EvidentlyMetricConfig]] = None, - column_mapping: Optional[ColumnMapping] = None, + profile_list: Optional[Sequence["EvidentlyMetricConfig"]] = None, + column_mapping: Optional["ColumnMapping"] = None, report_options: Sequence[Tuple[str, Dict[str, Any]]] = [], download_nltk_data: bool = False, **kwargs: Any, - ) -> Report: + ) -> "Report": """Analyze a dataset and generate a data report with Evidently. The method takes in an optional list of Evidently options to be passed @@ -183,7 +192,7 @@ def data_profiling( ```python options = [ ( - "evidently.options.ColorOptions",{ + "evidently.legacy.options.ColorOptions",{ "primary_color": "#5a86ad", "fill_color": "#fff4f2", "zero_line_color": "#016795", @@ -213,6 +222,10 @@ def data_profiling( Returns: The Evidently Report as JSON object and as HTML. """ + from evidently.legacy.report import Report + + from zenml.integrations.evidently.metrics import EvidentlyMetricConfig + self._set_nltk_data_path() if download_nltk_data: self._download_nltk_data() @@ -236,12 +249,12 @@ def data_validation( self, dataset: Any, comparison_dataset: Optional[Any] = None, - check_list: Optional[Sequence[EvidentlyTestConfig]] = None, + check_list: Optional[Sequence["EvidentlyTestConfig"]] = None, test_options: Sequence[Tuple[str, Dict[str, Any]]] = [], - column_mapping: Optional[ColumnMapping] = None, + column_mapping: Optional["ColumnMapping"] = None, download_nltk_data: bool = False, **kwargs: Any, - ) -> TestSuite: + ) -> "TestSuite": """Validate a dataset with Evidently. Args: @@ -262,6 +275,10 @@ def data_validation( Returns: The Evidently Test Suite as JSON object and as HTML. """ + from evidently.legacy.test_suite import TestSuite + + from zenml.integrations.evidently.tests import EvidentlyTestConfig + if download_nltk_data: self._download_nltk_data() diff --git a/src/zenml/integrations/evidently/metrics.py b/src/zenml/integrations/evidently/metrics.py index 0ecc74bc99a..c2ee406ec10 100644 --- a/src/zenml/integrations/evidently/metrics.py +++ b/src/zenml/integrations/evidently/metrics.py @@ -22,15 +22,18 @@ Union, ) -from evidently import metric_preset, metrics # type: ignore[import-untyped] -from evidently.metric_preset.metric_preset import ( # type: ignore[import-untyped] +from evidently.legacy import ( # type: ignore[import-untyped] + metric_preset, + metrics, +) +from evidently.legacy.metric_preset.metric_preset import ( # type: ignore[import-untyped] MetricPreset, ) -from evidently.metrics.base_metric import ( # type: ignore[import-untyped] +from evidently.legacy.metrics.base_metric import ( # type: ignore[import-untyped] Metric, generate_column_metrics, ) -from evidently.utils.generators import ( # type: ignore[import-untyped] +from evidently.legacy.utils.generators import ( # type: ignore[import-untyped] BaseGenerator, ) from pydantic import BaseModel, ConfigDict, Field @@ -170,7 +173,7 @@ def metric_generator( # Configure an Evidently Metric generator using a full Metric class # path config = EvidentlyMetric.metric_generator( - "evidently.metrics.ColumnSummaryMetric", columns=["age", "name"] + "evidently.legacy.metrics.ColumnSummaryMetric", columns=["age", "name"] ) ``` @@ -178,7 +181,7 @@ def metric_generator( from zenml.integrations.evidently.data_validators import EvidentlyMetric # Configure an Evidently Metric generator using a Metric class - from evidently.metrics import ColumnDriftMetric + from evidently.legacy.metrics import ColumnDriftMetric config = EvidentlyMetric.metric_generator( ColumnDriftMetric, columns="all", skip_id_column=True ) @@ -253,7 +256,7 @@ def metric( # Configure an Evidently MetricPreset using its full class path config = EvidentlyMetric.metric( - "evidently.metric_preset.DataDriftPreset" + "evidently.legacy.metric_preset.DataDriftPreset" ) ``` @@ -262,7 +265,7 @@ def metric( # Configure an Evidently Metric using its class and pass additional # parameters - from evidently.metrics import ColumnSummaryMetric + from evidently.legacy.metrics import ColumnSummaryMetric config = EvidentlyMetric.metric( ColumnSummaryMetric, column_name="age" ) diff --git a/src/zenml/integrations/evidently/steps/evidently_report.py b/src/zenml/integrations/evidently/steps/evidently_report.py index 6d8fc38170e..c96af0532af 100644 --- a/src/zenml/integrations/evidently/steps/evidently_report.py +++ b/src/zenml/integrations/evidently/steps/evidently_report.py @@ -108,4 +108,4 @@ def evidently_report_step( report_options=report_options or [], download_nltk_data=download_nltk_data, ) - return report.json(), HTMLString(report.show(mode="inline").data) + return report.json(), HTMLString(report.get_html()) diff --git a/src/zenml/integrations/evidently/steps/evidently_test.py b/src/zenml/integrations/evidently/steps/evidently_test.py index 1449fd0c51d..567b8f5006d 100644 --- a/src/zenml/integrations/evidently/steps/evidently_test.py +++ b/src/zenml/integrations/evidently/steps/evidently_test.py @@ -104,5 +104,5 @@ def evidently_test_step( ) return ( test_suite.json(), - HTMLString(test_suite.show(mode="inline").data), + HTMLString(test_suite.get_html()), ) diff --git a/src/zenml/integrations/evidently/tests.py b/src/zenml/integrations/evidently/tests.py index 4478ee4ad69..9a787ad93d9 100644 --- a/src/zenml/integrations/evidently/tests.py +++ b/src/zenml/integrations/evidently/tests.py @@ -22,15 +22,15 @@ Union, ) -from evidently import test_preset, tests # type: ignore[import-untyped] -from evidently.test_preset.test_preset import ( # type: ignore[import-untyped] +from evidently.legacy import test_preset, tests # type: ignore[import-untyped] +from evidently.legacy.test_preset.test_preset import ( # type: ignore[import-untyped] TestPreset, ) -from evidently.tests.base_test import ( # type: ignore[import-untyped] +from evidently.legacy.tests.base_test import ( # type: ignore[import-untyped] Test, generate_column_tests, ) -from evidently.utils.generators import ( # type: ignore[import-untyped] +from evidently.legacy.utils.generators import ( # type: ignore[import-untyped] BaseGenerator, ) from pydantic import BaseModel, ConfigDict, Field @@ -166,7 +166,7 @@ def test_generator( # Configure an Evidently Test generator using a full Test class # path config = EvidentlyTest.test_generator( - "evidently.tests.TestColumnShareOfMissingValues", columns=["age", "name"] + "evidently.legacy.tests.TestColumnShareOfMissingValues", columns=["age", "name"] ) ``` @@ -174,7 +174,7 @@ def test_generator( from zenml.integrations.evidently.data_validators import EvidentlyTest # Configure an Evidently Test generator using a Test class - from evidently.tests import TestColumnQuantile + from evidently.legacy.tests import TestColumnQuantile config = EvidentlyTest.test_generator( TestColumnQuantile, columns="all", quantile=0.5 ) @@ -246,7 +246,7 @@ def test( # Configure an Evidently TestPreset using its full class path config = EvidentlyTest.test( - "evidently.test_preset.DataDriftPreset" + "evidently.legacy.test_preset.DataDriftPreset" ) ``` @@ -255,7 +255,7 @@ def test( # Configure an Evidently Test using its class and pass additional # parameters - from evidently.tests import ColumnSummaryTest + from evidently.legacy.tests import ColumnSummaryTest config = EvidentlyTest.test( ColumnSummaryTest, column_name="age" )