arize-phoenix 4.0.0__py3-none-any.whl → 4.0.2__py3-none-any.whl

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.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: arize-phoenix
3
- Version: 4.0.0
3
+ Version: 4.0.2
4
4
  Summary: AI Observability and Evaluation
5
5
  Project-URL: Documentation, https://docs.arize.com/phoenix/
6
6
  Project-URL: Issues, https://github.com/Arize-ai/phoenix/issues
@@ -5,7 +5,7 @@ phoenix/exceptions.py,sha256=n2L2KKuecrdflB9MsCdAYCiSEvGJptIsfRkXMoJle7A,169
5
5
  phoenix/py.typed,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
6
6
  phoenix/services.py,sha256=haZUWKuxfI5lm0o61HgW_4B6RTBg9CUbXC8y92ZMsw4,5121
7
7
  phoenix/settings.py,sha256=cO-qgis_S27nHirTobYI9hHPfZH18R--WMmxNdsVUwc,273
8
- phoenix/version.py,sha256=SQa6Ci17DORmGXi_wkOW9pPlUojF-qtjH6NV1WOThsU,22
8
+ phoenix/version.py,sha256=1UD6TKg1K_f5rIzHLYHv3Su3o2nPpbEj1lo55M4pjtM,22
9
9
  phoenix/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
10
  phoenix/core/embedding_dimension.py,sha256=zKGbcvwOXgLf-yrJBpQyKtd-LEOPRKHnUToyAU8Owis,87
11
11
  phoenix/core/model.py,sha256=SBO8BZg_CeQuH5LrSgzlQfqMModzirkQePdhnbLw7dE,4756
@@ -14,14 +14,14 @@ phoenix/core/model_schema_adapter.py,sha256=aFvNtpI01sdaLoKvEvcsx51vP5_6anP0_g9i
14
14
  phoenix/db/README.md,sha256=yM2HQcKBkhnAfbRMmMN5CyTIJs8Vj1Iiw4AENz2Ldz8,592
15
15
  phoenix/db/__init__.py,sha256=pDjEFXukHmJBM-1D8RjmXkvLsz85YWNxMQczt81ec3A,118
16
16
  phoenix/db/alembic.ini,sha256=p8DjVqGUs_tTx8oU56JP7qj-rMUebNFizItUSv_hPhs,3763
17
- phoenix/db/bulk_inserter.py,sha256=ad8-a_V0zSQjk2z7ZGnp8YO0B2cm6pLpHXI08IPPYEE,9655
17
+ phoenix/db/bulk_inserter.py,sha256=mbu1n937Ozg2Lyl3DCk4cxSA3O6V1K-37fJhctp_SL4,9908
18
18
  phoenix/db/engines.py,sha256=vLWaZlToMtDI7rJDxSidYkfOoojamxaZxaz8ND3zTus,4770
19
19
  phoenix/db/helpers.py,sha256=L2_jP1iIWpUREhKLYYb4_vf_6v_BiU1E73Z2PczGm6s,1589
20
20
  phoenix/db/migrate.py,sha256=Rd7rnmYLFlSGO3R3rSzXCCvDkYkhxguqDbQNhI6rm5o,2251
21
21
  phoenix/db/models.py,sha256=Atd61_8I2uiP6tUPW3As4X3UKU2edbS-W4LGGzkJ9KM,12125
22
22
  phoenix/db/insertion/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
23
23
  phoenix/db/insertion/evaluation.py,sha256=nvKXGWv0XD23G3ISw2u9_SqbwtGaB0Vd63wL59nPlCA,7189
24
- phoenix/db/insertion/helpers.py,sha256=-bEYgjob6s1Y7SDy64ZaKJwW4XQkcotwogvxtTnjEmw,2044
24
+ phoenix/db/insertion/helpers.py,sha256=2oBbzwx_Q0JJ9WlvbGl_a8hWySHyGhzbMNv-SHtcM-4,2022
25
25
  phoenix/db/insertion/span.py,sha256=DNBjSrx5g2W5KuTB1dkHwtkb0SFnMIxN1jB-BAdGKFY,5634
26
26
  phoenix/db/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
27
  phoenix/db/migrations/env.py,sha256=QbzB5zrRs6XQQmrYeUpuzeilcMlM-MsbaAgHHYcIHTI,3626
@@ -155,13 +155,13 @@ phoenix/trace/errors.py,sha256=wB1z8qdPckngdfU-TORToekvg3344oNFAA83_hC2yFY,180
155
155
  phoenix/trace/evaluation_conventions.py,sha256=t8jydM3U0-T5YpiQKRJ3tWdWGlHtzKyttYdw-ddvPOk,1048
156
156
  phoenix/trace/exporter.py,sha256=vh2RO1CpP143HxIX94KV0qks8p1x66RE3Tgf8kcBCCg,4519
157
157
  phoenix/trace/fixtures.py,sha256=kupizPlPLoQyCxZfrIU7ZC87dYiL8uEhZEmdia__5qQ,9644
158
- phoenix/trace/otel.py,sha256=LKetRjMYw3D23SDRnO1FZhsOmJ-zFFZMNJTGYBycogk,9663
158
+ phoenix/trace/otel.py,sha256=WA720jvRadiZBAKjsYoPyXzypHwbyEK2OZRVUwtbjB8,9976
159
159
  phoenix/trace/projects.py,sha256=2BwlNjFE-uwpqYtCu5YyBiYZk9wRPpM13vh3-Cv7GkA,2157
160
160
  phoenix/trace/schemas.py,sha256=JiFKhGD2JF6Eai7UOhPF5urcuKGkpMLHc3Vltbe1msk,5967
161
161
  phoenix/trace/span_evaluations.py,sha256=7DI1EFfpZoOH8iIUYNzL9P6U9j0Hc2Z3u2SD0h1SF_Q,13101
162
162
  phoenix/trace/span_json_decoder.py,sha256=IAFakPRqSMYxTPKYFMiXYxm7U-FipdN8_xbvapDS0Qc,3131
163
163
  phoenix/trace/span_json_encoder.py,sha256=tzSCIQJbeFBm33K68G8A5M12n_86tCDyuU0WAobxEz4,2010
164
- phoenix/trace/trace_dataset.py,sha256=RpHIfZLbMmULOIb-fKXJkQLhIdC0sJlAOTjlyJppMYA,13776
164
+ phoenix/trace/trace_dataset.py,sha256=197ey31Zp40eN_gH1YVGM7avkZs-YlROSKG3M5eZsWg,13830
165
165
  phoenix/trace/utils.py,sha256=7LurVGXn245cjj4MJsc7v6jq4DSJkpK6YGBfIaSywuw,1307
166
166
  phoenix/trace/dsl/README.md,sha256=ihmP9zGUC5V-TDbzKla76LuyDqPDQIBUH2BORwxNI68,2902
167
167
  phoenix/trace/dsl/__init__.py,sha256=WIQIjJg362XD3s50OsPJJ0xbDsGp41bSv7vDllLrPuA,144
@@ -183,8 +183,8 @@ phoenix/utilities/error_handling.py,sha256=7b5rpGFj9EWZ8yrZK1IHvxB89suWk3lggDayU
183
183
  phoenix/utilities/logging.py,sha256=lDXd6EGaamBNcQxL4vP1au9-i_SXe0OraUDiJOcszSw,222
184
184
  phoenix/utilities/project.py,sha256=qWsvKnG1oKhOFUowXf9qiOL2ia7jaFe_ijFFHEt8GJo,431
185
185
  phoenix/utilities/span_store.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
186
- arize_phoenix-4.0.0.dist-info/METADATA,sha256=Q1RTfl5in8nJ85OIBxAWbIZCIltD-MQMaC4oXBpLmJ8,30464
187
- arize_phoenix-4.0.0.dist-info/WHEEL,sha256=zEMcRr9Kr03x1ozGwg5v9NQBKn3kndp6LSoSlVg-jhU,87
188
- arize_phoenix-4.0.0.dist-info/licenses/IP_NOTICE,sha256=JBqyyCYYxGDfzQ0TtsQgjts41IJoa-hiwDrBjCb9gHM,469
189
- arize_phoenix-4.0.0.dist-info/licenses/LICENSE,sha256=HFkW9REuMOkvKRACuwLPT0hRydHb3zNg-fdFt94td18,3794
190
- arize_phoenix-4.0.0.dist-info/RECORD,,
186
+ arize_phoenix-4.0.2.dist-info/METADATA,sha256=31HzTL6J7wFPFDRcfhFbNZIqCkFLIM4C515BlGpnC08,30464
187
+ arize_phoenix-4.0.2.dist-info/WHEEL,sha256=zEMcRr9Kr03x1ozGwg5v9NQBKn3kndp6LSoSlVg-jhU,87
188
+ arize_phoenix-4.0.2.dist-info/licenses/IP_NOTICE,sha256=JBqyyCYYxGDfzQ0TtsQgjts41IJoa-hiwDrBjCb9gHM,469
189
+ arize_phoenix-4.0.2.dist-info/licenses/LICENSE,sha256=HFkW9REuMOkvKRACuwLPT0hRydHb3zNg-fdFt94td18,3794
190
+ arize_phoenix-4.0.2.dist-info/RECORD,,
@@ -63,6 +63,10 @@ class BulkInserter:
63
63
  self._db = db
64
64
  self._running = False
65
65
  self._run_interval_seconds = run_interval_in_seconds
66
+
67
+ # tracks time between insertions to improve responsiveness for small batches
68
+ self._last_insertion_time = time() - self._run_interval_seconds
69
+
66
70
  self._max_num_per_transaction = max_num_per_transaction
67
71
  self._spans: List[Tuple[Span, str]] = (
68
72
  [] if initial_batch_of_spans is None else list(initial_batch_of_spans)
@@ -98,10 +102,10 @@ class BulkInserter:
98
102
 
99
103
  async def _bulk_insert(self) -> None:
100
104
  spans_buffer, evaluations_buffer = None, None
101
- next_run_at = time() + self._run_interval_seconds
105
+ # start first insert immediately if the inserter has not run recently
102
106
  while self._spans or self._evaluations or self._running:
103
- await asyncio.sleep(next_run_at - time())
104
- next_run_at = time() + self._run_interval_seconds
107
+ next_run_at = self._last_insertion_time + self._run_interval_seconds
108
+ await asyncio.sleep(max(next_run_at - time(), 0))
105
109
  if not (self._spans or self._evaluations):
106
110
  continue
107
111
  # It's important to grab the buffers at the same time so there's
@@ -128,6 +132,7 @@ class BulkInserter:
128
132
  evaluations_buffer = None
129
133
  for project_rowid in transaction_result.updated_project_rowids:
130
134
  self._last_updated_at_by_project[project_rowid] = datetime.now(timezone.utc)
135
+ self._last_insertion_time = time()
131
136
 
132
137
  async def _insert_spans(self, spans: List[Tuple[Span, str]]) -> TransactionResult:
133
138
  transaction_result = TransactionResult()
@@ -30,11 +30,8 @@ def insert_stmt(
30
30
  raise ValueError(
31
31
  "Both `constraint` and `column_names` must be provided or omitted at the same time."
32
32
  )
33
- if (
34
- dialect is SupportedSQLDialect.POSTGRESQL
35
- and constraint is None
36
- or dialect is SupportedSQLDialect.SQLITE
37
- and not column_names
33
+ if (dialect is SupportedSQLDialect.POSTGRESQL and constraint is None) or (
34
+ dialect is SupportedSQLDialect.SQLITE and not column_names
38
35
  ):
39
36
  return insert(table).values(values)
40
37
  if dialect is SupportedSQLDialect.POSTGRESQL:
phoenix/trace/otel.py CHANGED
@@ -17,7 +17,11 @@ from typing import (
17
17
 
18
18
  import numpy as np
19
19
  import opentelemetry.proto.trace.v1.trace_pb2 as otlp
20
- from openinference.semconv.trace import DocumentAttributes, SpanAttributes
20
+ from openinference.semconv.trace import (
21
+ DocumentAttributes,
22
+ OpenInferenceMimeTypeValues,
23
+ SpanAttributes,
24
+ )
21
25
  from opentelemetry.proto.common.v1.common_pb2 import AnyValue, ArrayValue, KeyValue
22
26
  from opentelemetry.util.types import Attributes, AttributeValue
23
27
  from typing_extensions import TypeAlias, assert_never
@@ -70,6 +74,12 @@ def decode_otlp_span(otlp_span: otlp.Span) -> Span:
70
74
  status_code, status_message = _decode_status(otlp_span.status)
71
75
  events = [_decode_event(event) for event in otlp_span.events]
72
76
 
77
+ if (input_value := get_attribute_value(attributes, INPUT_VALUE)) and not isinstance(
78
+ input_value, str
79
+ ):
80
+ attributes["input"]["value"] = json.dumps(input_value)
81
+ attributes["input"]["mime_type"] = OpenInferenceMimeTypeValues.JSON.value
82
+
73
83
  return Span(
74
84
  name=otlp_span.name,
75
85
  context=SpanContext(
@@ -16,6 +16,7 @@ from pyarrow import Schema, Table, parquet
16
16
 
17
17
  from phoenix.config import DATASET_DIR, GENERATED_DATASET_NAME_PREFIX, TRACE_DATASET_DIR
18
18
  from phoenix.datetime_utils import normalize_timestamps
19
+ from phoenix.trace.attributes import unflatten
19
20
  from phoenix.trace.errors import InvalidParquetMetadataError
20
21
  from phoenix.trace.schemas import ATTRIBUTE_PREFIX, CONTEXT_PREFIX, Span
21
22
  from phoenix.trace.span_evaluations import Evaluations, SpanEvaluations
@@ -161,13 +162,13 @@ class TraceDataset:
161
162
  for _, row in self.dataframe.iterrows():
162
163
  is_attribute = row.index.str.startswith(ATTRIBUTE_PREFIX)
163
164
  attribute_keys = row.index[is_attribute]
164
- attributes = (
165
+ attributes = unflatten(
165
166
  row.loc[is_attribute]
166
167
  .rename(
167
168
  {key: key[len(ATTRIBUTE_PREFIX) :] for key in attribute_keys},
168
169
  )
169
170
  .dropna()
170
- .to_dict()
171
+ .items()
171
172
  )
172
173
  is_context = row.index.str.startswith(CONTEXT_PREFIX)
173
174
  context_keys = row.index[is_context]
phoenix/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "4.0.0"
1
+ __version__ = "4.0.2"