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.

Files changed (96) hide show
  1. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/PKG-INFO +1 -1
  2. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/__init__.py +1 -1
  3. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/core/model_schema.py +2 -4
  4. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/core/model_schema_adapter.py +50 -3
  5. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/datasets/dataset.py +5 -1
  6. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/pointcloud/projectors.py +9 -1
  7. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/types/PerformanceMetric.py +1 -1
  8. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/types/Segments.py +14 -0
  9. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/static/index.js +426 -386
  10. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/.gitignore +0 -0
  11. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/IP_NOTICE +0 -0
  12. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/LICENSE +0 -0
  13. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/README.md +0 -0
  14. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/pyproject.toml +0 -0
  15. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/config.py +0 -0
  16. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/core/__init__.py +0 -0
  17. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/core/dimension.py +0 -0
  18. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/core/dimension_data_type.py +0 -0
  19. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/core/dimension_type.py +0 -0
  20. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/core/embedding_dimension.py +0 -0
  21. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/core/model.py +0 -0
  22. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/datasets/__init__.py +0 -0
  23. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/datasets/errors.py +0 -0
  24. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/datasets/fixtures.py +0 -0
  25. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/datasets/schema.py +0 -0
  26. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/datasets/validation.py +0 -0
  27. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/metrics/README.md +0 -0
  28. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/metrics/__init__.py +0 -0
  29. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/metrics/binning.py +0 -0
  30. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/metrics/metrics.py +0 -0
  31. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/metrics/mixins.py +0 -0
  32. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/metrics/timeseries.py +0 -0
  33. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/metrics/wrappers.py +0 -0
  34. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/pointcloud/__init__.py +0 -0
  35. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/pointcloud/clustering.py +0 -0
  36. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/pointcloud/pointcloud.py +0 -0
  37. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/py.typed +0 -0
  38. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/__init__.py +0 -0
  39. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/__init__.py +0 -0
  40. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/context.py +0 -0
  41. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/helpers.py +0 -0
  42. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/input_types/ClusterInput.py +0 -0
  43. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/input_types/Coordinates.py +0 -0
  44. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/input_types/DataQualityMetricInput.py +0 -0
  45. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/input_types/DimensionFilter.py +0 -0
  46. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/input_types/DimensionInput.py +0 -0
  47. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/input_types/Granularity.py +0 -0
  48. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/input_types/PerformanceMetricInput.py +0 -0
  49. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/input_types/TimeRange.py +0 -0
  50. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/input_types/__init__.py +0 -0
  51. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/interceptor.py +0 -0
  52. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/schema.py +0 -0
  53. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/types/Cluster.py +0 -0
  54. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/types/DataQualityMetric.py +0 -0
  55. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/types/Dataset.py +0 -0
  56. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/types/DatasetRole.py +0 -0
  57. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/types/DatasetValues.py +0 -0
  58. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/types/Dimension.py +0 -0
  59. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/types/DimensionDataType.py +0 -0
  60. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/types/DimensionShape.py +0 -0
  61. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/types/DimensionType.py +0 -0
  62. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/types/DimensionWithValue.py +0 -0
  63. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/types/EmbeddingDimension.py +0 -0
  64. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/types/EmbeddingMetadata.py +0 -0
  65. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/types/Event.py +0 -0
  66. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/types/EventMetadata.py +0 -0
  67. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/types/ExportEventsMutation.py +0 -0
  68. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/types/ExportedFile.py +0 -0
  69. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/types/Model.py +0 -0
  70. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/types/NumericRange.py +0 -0
  71. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/types/PromptResponse.py +0 -0
  72. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/types/ScalarDriftMetricEnum.py +0 -0
  73. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/types/TimeSeries.py +0 -0
  74. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/types/UMAPPoints.py +0 -0
  75. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/types/VectorDriftMetricEnum.py +0 -0
  76. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/types/__init__.py +0 -0
  77. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/types/node.py +0 -0
  78. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/api/types/pagination.py +0 -0
  79. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/app.py +0 -0
  80. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/main.py +0 -0
  81. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/static/apple-touch-icon-114x114.png +0 -0
  82. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/static/apple-touch-icon-120x120.png +0 -0
  83. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/static/apple-touch-icon-144x144.png +0 -0
  84. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/static/apple-touch-icon-152x152.png +0 -0
  85. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/static/apple-touch-icon-180x180.png +0 -0
  86. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/static/apple-touch-icon-72x72.png +0 -0
  87. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/static/apple-touch-icon-76x76.png +0 -0
  88. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/static/apple-touch-icon.png +0 -0
  89. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/static/favicon.ico +0 -0
  90. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/static/index.css +0 -0
  91. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/static/index.html +0 -0
  92. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/static/modernizr.js +0 -0
  93. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/server/thread_server.py +0 -0
  94. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/services.py +0 -0
  95. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/session/__init__.py +0 -0
  96. {arize_phoenix-0.0.24rc0 → arize_phoenix-0.0.24rc2}/src/phoenix/session/session.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: arize-phoenix
3
- Version: 0.0.24rc0
3
+ Version: 0.0.24rc2
4
4
  Summary: ML Observability in your notebook
5
5
  Project-URL: Documentation, https://docs.arize.com/phoenix/
6
6
  Project-URL: Issues, https://github.com/Arize-ai/phoenix/issues
@@ -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.24rc0"
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
- # NOTE: as of Python 3.8.16, pandas 1.5.3:
603
- # >>> isinstance(pd.NaT, datetime.datetime)
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())
@@ -1,7 +1,9 @@
1
1
  from itertools import chain
2
- from typing import Dict, Iterable, List, Optional, Tuple
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(features, translated_embeddings),
111
- tags=tags,
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 = Series([default_timestamp] * len(dataframe), index=dataframe.index)
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
- return _center(UMAP(**asdict(self), n_components=n_components).fit_transform(mat))
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
- accuracy_score = partial(SkEval.accuracy_score) # type: ignore
13
+ accuracyScore = partial(SkEval.accuracy_score) # type: ignore
@@ -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