Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,9 @@ def _chi_stat_test(
ref_feature_dict = {**dict.fromkeys(keys, 0), **dict(reference_data.value_counts())}
current_feature_dict = {**dict.fromkeys(keys, 0), **dict(current_data.value_counts())}
k_norm = current_data.shape[0] / reference_data.shape[0]
f_exp = [ref_feature_dict[key] * k_norm for key in keys]
f_obs = [current_feature_dict[key] for key in keys]
f_exp = [max(ref_feature_dict[key] * k_norm, 1e-6) for key in keys]
f_exp = [f / sum(f_exp) * sum(f_obs) for f in f_exp]
p_value = chisquare(f_obs, f_exp)[1]
return p_value, p_value < threshold

Expand Down
5 changes: 4 additions & 1 deletion src/evidently/legacy/tests/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,10 @@ def dict(self, *args, **kwargs):


# some monkeing for np asserts to work with ApproxValue
np.core.numeric.ScalarType = np.core.numeric.ScalarType + (ApproxValue, ApproxValueNoDict) # type: ignore[attr-defined]
if hasattr(np, "_core"):
np._core.numeric.ScalarType = np._core.numeric.ScalarType + (ApproxValue, ApproxValueNoDict) # type: ignore[attr-defined]
else:
np.core.numeric.ScalarType = np.core.numeric.ScalarType + (ApproxValue, ApproxValueNoDict) # type: ignore[attr-defined]


def approx_result(value, relative=None, absolute=None):
Expand Down
15 changes: 12 additions & 3 deletions src/evidently/ui/workspace.py
Original file line number Diff line number Diff line change
Expand Up @@ -1198,7 +1198,10 @@ def delete_run(self, project_id: STR_UUID, snapshot_id: STR_UUID):
Raises:
* NotImplementedError (snapshot API not yet implemented)
"""
raise NotImplementedError # todo: snapshot api
raise NotImplementedError(
"The Snapshot API is not yet implemented for RemoteWorkspace. "
"Please use a local Workspace instead."
) # todo: snapshot api

def get_run(self, project_id: STR_UUID, snapshot_id: STR_UUID) -> Optional[SnapshotModel]:
"""Get a snapshot (run) by ID.
Expand All @@ -1213,7 +1216,10 @@ def get_run(self, project_id: STR_UUID, snapshot_id: STR_UUID) -> Optional[Snaps
Raises:
* NotImplementedError (snapshot API not yet implemented)
"""
raise NotImplementedError # todo: snapshot api
raise NotImplementedError(
"The Snapshot API is not yet implemented for RemoteWorkspace. "
"Please use a local Workspace instead."
) # todo: snapshot api

def list_runs(self, project_id: STR_UUID) -> Sequence[SnapshotID]:
"""List all snapshots (runs) for a project.
Expand All @@ -1227,7 +1233,10 @@ def list_runs(self, project_id: STR_UUID) -> Sequence[SnapshotID]:
Raises:
* NotImplementedError (snapshot API not yet implemented)
"""
raise NotImplementedError # todo: snapshot api
raise NotImplementedError(
"The Snapshot API is not yet implemented for RemoteWorkspace. "
"Please use a local Workspace instead."
) # todo: snapshot api

def search_project(self, project_name: str, org_id: Optional[OrgID] = None) -> Sequence[Project]:
"""Search for projects by name.
Expand Down
5 changes: 4 additions & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@
from evidently.pydantic_utils import PolymorphicModel

# for np.testing.assert_equal to work with ApproxValue
np.core.numeric.ScalarType = np.core.numeric.ScalarType + (ApproxValue,) # type: ignore[attr-defined]
if hasattr(np, "_core"):
np._core.numeric.ScalarType = np._core.numeric.ScalarType + (ApproxValue,) # type: ignore[attr-defined]
else:
np.core.numeric.ScalarType = np.core.numeric.ScalarType + (ApproxValue,) # type: ignore[attr-defined]


def smart_assert_equal(actual, expected, path=""):
Expand Down
32 changes: 32 additions & 0 deletions tests/ui/test_workspace.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import re
import uuid

import pytest

from evidently.ui.workspace import RemoteWorkspace

# Shared expected message — kept as a constant so the test fails loudly
# if anyone silently removes or waters-down the user-facing guidance.
_EXPECTED_MSG = "The Snapshot API is not yet implemented for RemoteWorkspace. Please use a local Workspace instead."


@pytest.fixture()
def remote_workspace():
"""Return a RemoteWorkspace that skips the server-health check."""
return RemoteWorkspace(base_url="http://localhost:0", verify=False)


class RemoteWorkspaceSnapshotAPITest:
"""Verify that unimplemented snapshot methods raise an actionable error."""

def test_list_runs_raises_not_implemented(self, remote_workspace):
with pytest.raises(NotImplementedError, match=re.escape(_EXPECTED_MSG)):
remote_workspace.list_runs(str(uuid.uuid4()))

def test_get_run_raises_not_implemented(self, remote_workspace):
with pytest.raises(NotImplementedError, match=re.escape(_EXPECTED_MSG)):
remote_workspace.get_run(str(uuid.uuid4()), str(uuid.uuid4()))

def test_delete_run_raises_not_implemented(self, remote_workspace):
with pytest.raises(NotImplementedError, match=re.escape(_EXPECTED_MSG)):
remote_workspace.delete_run(str(uuid.uuid4()), str(uuid.uuid4()))