arize-phoenix 0.0.24rc0__tar.gz → 0.0.24rc2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of arize-phoenix might be problematic. Click here for more details.
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/PKG-INFO +1 -1
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/__init__.py +1 -1
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/core/model_schema.py +2 -4
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/core/model_schema_adapter.py +50 -3
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/datasets/dataset.py +5 -1
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/pointcloud/projectors.py +9 -1
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/types/PerformanceMetric.py +1 -1
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/types/Segments.py +14 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/static/index.js +426 -386
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/.gitignore +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/IP_NOTICE +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/LICENSE +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/README.md +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/pyproject.toml +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/config.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/core/__init__.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/core/dimension.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/core/dimension_data_type.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/core/dimension_type.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/core/embedding_dimension.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/core/model.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/datasets/__init__.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/datasets/errors.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/datasets/fixtures.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/datasets/schema.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/datasets/validation.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/metrics/README.md +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/metrics/__init__.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/metrics/binning.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/metrics/metrics.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/metrics/mixins.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/metrics/timeseries.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/metrics/wrappers.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/pointcloud/__init__.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/pointcloud/clustering.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/pointcloud/pointcloud.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/py.typed +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/__init__.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/__init__.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/context.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/helpers.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/input_types/ClusterInput.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/input_types/Coordinates.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/input_types/DataQualityMetricInput.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/input_types/DimensionFilter.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/input_types/DimensionInput.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/input_types/Granularity.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/input_types/PerformanceMetricInput.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/input_types/TimeRange.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/input_types/__init__.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/interceptor.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/schema.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/types/Cluster.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/types/DataQualityMetric.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/types/Dataset.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/types/DatasetRole.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/types/DatasetValues.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/types/Dimension.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/types/DimensionDataType.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/types/DimensionShape.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/types/DimensionType.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/types/DimensionWithValue.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/types/EmbeddingDimension.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/types/EmbeddingMetadata.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/types/Event.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/types/EventMetadata.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/types/ExportEventsMutation.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/types/ExportedFile.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/types/Model.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/types/NumericRange.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/types/PromptResponse.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/types/ScalarDriftMetricEnum.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/types/TimeSeries.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/types/UMAPPoints.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/types/VectorDriftMetricEnum.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/types/__init__.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/types/node.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/types/pagination.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/app.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/main.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/static/apple-touch-icon-114x114.png +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/static/apple-touch-icon-120x120.png +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/static/apple-touch-icon-144x144.png +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/static/apple-touch-icon-152x152.png +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/static/apple-touch-icon-180x180.png +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/static/apple-touch-icon-72x72.png +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/static/apple-touch-icon-76x76.png +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/static/apple-touch-icon.png +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/static/favicon.ico +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/static/index.css +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/static/index.html +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/static/modernizr.js +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/thread_server.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/services.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/session/__init__.py +0 -0
- {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/session/session.py +0 -0
|
@@ -3,7 +3,7 @@ from .datasets.fixtures import ExampleDatasets, load_example
|
|
|
3
3
|
from .datasets.schema import EmbeddingColumnNames, Schema
|
|
4
4
|
from .session.session import Session, active_session, close_app, launch_app
|
|
5
5
|
|
|
6
|
-
__version__ = "0.0.
|
|
6
|
+
__version__ = "0.0.24rc2"
|
|
7
7
|
|
|
8
8
|
# module level doc-string
|
|
9
9
|
__doc__ = """
|
|
@@ -599,10 +599,8 @@ class Events(ModelData):
|
|
|
599
599
|
@cached_property
|
|
600
600
|
def time_range(self) -> TimeRange:
|
|
601
601
|
if self._self_model is None or self.empty:
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
# True
|
|
605
|
-
return TimeRange(pd.NaT, pd.NaT) # type: ignore
|
|
602
|
+
now = datetime.now(timezone.utc)
|
|
603
|
+
return TimeRange(now, now)
|
|
606
604
|
model = cast(Model, self._self_model)
|
|
607
605
|
min_max = _agg_min_max(model[TIMESTAMP](self))
|
|
608
606
|
start_time = cast(datetime, min_max.min())
|
{arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/core/model_schema_adapter.py
RENAMED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
from itertools import chain
|
|
2
|
-
from
|
|
2
|
+
from operator import itemgetter
|
|
3
|
+
from typing import Dict, Iterable, List, Optional, Sized, Tuple
|
|
3
4
|
|
|
4
5
|
import pandas as pd
|
|
6
|
+
from pandas.api.types import is_object_dtype
|
|
5
7
|
from typing_extensions import TypeAlias, TypeGuard
|
|
6
8
|
|
|
7
9
|
from phoenix import Dataset, EmbeddingColumnNames
|
|
@@ -107,8 +109,19 @@ def create_model_from_datasets(*datasets: Optional[Dataset]) -> Model:
|
|
|
107
109
|
prediction_score=_take_first_str(prediction_scores),
|
|
108
110
|
actual_label=_take_first_str(actual_labels),
|
|
109
111
|
actual_score=_take_first_str(actual_scores),
|
|
110
|
-
features=chain(
|
|
111
|
-
|
|
112
|
+
features=chain(
|
|
113
|
+
*_split_vectors_vs_scalars(
|
|
114
|
+
features,
|
|
115
|
+
*map(itemgetter(1), named_dataframes),
|
|
116
|
+
),
|
|
117
|
+
translated_embeddings,
|
|
118
|
+
),
|
|
119
|
+
tags=chain(
|
|
120
|
+
*_split_vectors_vs_scalars(
|
|
121
|
+
tags,
|
|
122
|
+
*map(itemgetter(1), named_dataframes),
|
|
123
|
+
)
|
|
124
|
+
),
|
|
112
125
|
prompt=next(map(_translate_embedding, prompts), None),
|
|
113
126
|
response=next(map(_translate_embedding, responses), None),
|
|
114
127
|
)(
|
|
@@ -137,3 +150,37 @@ def _translate_embedding(
|
|
|
137
150
|
link_to_data=embedding.link_to_data_column_name,
|
|
138
151
|
display_name=display_name,
|
|
139
152
|
)
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
def _split_vectors_vs_scalars(
|
|
156
|
+
names: Iterable[str],
|
|
157
|
+
*dataframes: pd.DataFrame,
|
|
158
|
+
) -> Tuple[List[str], List[Embedding]]:
|
|
159
|
+
"""A best-effort attempt at separating vector columns from scalar columns
|
|
160
|
+
by examining the first non-null item of the column from each dataframe. If
|
|
161
|
+
any item is `Iterable` and `Sized`, but not `str`, then the column is
|
|
162
|
+
returned as `Embedding`, else it's returned as scalar.
|
|
163
|
+
"""
|
|
164
|
+
scalars: List[str] = []
|
|
165
|
+
vectors: List[Embedding] = []
|
|
166
|
+
# convert to sets for a speedier lookup
|
|
167
|
+
column_names = [set(df.columns) for df in dataframes]
|
|
168
|
+
for name in names:
|
|
169
|
+
for i, df in enumerate(dataframes):
|
|
170
|
+
if df.empty or name not in column_names[i]:
|
|
171
|
+
continue
|
|
172
|
+
series = df.loc[:, name]
|
|
173
|
+
if not is_object_dtype(series):
|
|
174
|
+
continue
|
|
175
|
+
item = series.iat[series.isna().argmin()]
|
|
176
|
+
if (
|
|
177
|
+
isinstance(item, str) # str is scalar, but Iterable
|
|
178
|
+
or not isinstance(item, Iterable)
|
|
179
|
+
or not isinstance(item, Sized)
|
|
180
|
+
):
|
|
181
|
+
continue
|
|
182
|
+
vectors.append(Embedding(vector=name))
|
|
183
|
+
break
|
|
184
|
+
else:
|
|
185
|
+
scalars.append(name)
|
|
186
|
+
return scalars, vectors
|
|
@@ -443,7 +443,11 @@ def _normalize_timestamps(
|
|
|
443
443
|
if (timestamp_column_name := schema.timestamp_column_name) is None:
|
|
444
444
|
timestamp_column_name = "timestamp"
|
|
445
445
|
schema = replace(schema, timestamp_column_name=timestamp_column_name)
|
|
446
|
-
timestamp_column =
|
|
446
|
+
timestamp_column = (
|
|
447
|
+
Series([default_timestamp] * len(dataframe), index=dataframe.index)
|
|
448
|
+
if len(dataframe)
|
|
449
|
+
else Series([default_timestamp]).iloc[:0].set_axis(dataframe.index, axis=0)
|
|
450
|
+
)
|
|
447
451
|
elif is_numeric_dtype(timestamp_column_dtype := dataframe[timestamp_column_name].dtype):
|
|
448
452
|
timestamp_column = to_datetime(dataframe[timestamp_column_name], unit="s", utc=True)
|
|
449
453
|
elif is_datetime64tz_dtype(timestamp_column_dtype):
|
|
@@ -11,6 +11,7 @@ with warnings.catch_warnings():
|
|
|
11
11
|
|
|
12
12
|
warnings.simplefilter("ignore", category=NumbaWarning)
|
|
13
13
|
from umap import UMAP
|
|
14
|
+
|
|
14
15
|
Matrix: TypeAlias = npt.NDArray[np.float64]
|
|
15
16
|
|
|
16
17
|
|
|
@@ -24,4 +25,11 @@ class Umap:
|
|
|
24
25
|
min_dist: float = 0.1
|
|
25
26
|
|
|
26
27
|
def project(self, mat: Matrix, n_components: int) -> Matrix:
|
|
27
|
-
|
|
28
|
+
config = asdict(self)
|
|
29
|
+
config["n_components"] = n_components
|
|
30
|
+
if len(mat) <= n_components:
|
|
31
|
+
# init='spectral', the default, cannot be used when n_components
|
|
32
|
+
# is greater or equal to the number of samples.
|
|
33
|
+
# see https://github.com/lmcinnes/umap/issues/201#issuecomment-462097103
|
|
34
|
+
config["init"] = "random"
|
|
35
|
+
return _center(UMAP(**config).fit_transform(mat))
|
|
@@ -10,4 +10,4 @@ from phoenix.metrics.wrappers import SkEval
|
|
|
10
10
|
class PerformanceMetric(Enum):
|
|
11
11
|
# To become enum values, functions need to be wrapped in partial.
|
|
12
12
|
# See https://stackoverflow.com/a/40339397
|
|
13
|
-
|
|
13
|
+
accuracyScore = partial(SkEval.accuracy_score) # type: ignore
|
{arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/types/Segments.py
RENAMED
|
@@ -84,5 +84,19 @@ class Segments:
|
|
|
84
84
|
)
|
|
85
85
|
|
|
86
86
|
def append(self, other: Segment) -> None:
|
|
87
|
+
if (
|
|
88
|
+
isinstance(other.bin, IntervalBin)
|
|
89
|
+
and not math.isfinite(other.bin.range.start)
|
|
90
|
+
and not math.isfinite(other.bin.range.end)
|
|
91
|
+
and other.counts.primary_value == 0
|
|
92
|
+
and other.counts.reference_value == 0
|
|
93
|
+
):
|
|
94
|
+
# Skip the interval bin with zero counts if it has -inf and +inf
|
|
95
|
+
# as the endpoints, as it could occur due to all values being
|
|
96
|
+
# missing. Because such bin can exist a priori, the caller may
|
|
97
|
+
# still try to append it, but the bin has no real value at this
|
|
98
|
+
# point (and can cause problems for graphql because of the end
|
|
99
|
+
# points are not serializable to JSON).
|
|
100
|
+
return
|
|
87
101
|
self.segments.append(other)
|
|
88
102
|
self.total_counts += other.counts
|