arize-phoenix 3.0.0__py3-none-any.whl → 3.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.1
2
2
  Name: arize-phoenix
3
- Version: 3.0.0
3
+ Version: 3.0.2
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
@@ -50,14 +50,14 @@ Requires-Dist: hatch; extra == 'dev'
50
50
  Requires-Dist: jupyter; extra == 'dev'
51
51
  Requires-Dist: langchain>=0.0.334; extra == 'dev'
52
52
  Requires-Dist: litellm>=1.0.3; extra == 'dev'
53
- Requires-Dist: llama-index>=0.9.14; extra == 'dev'
53
+ Requires-Dist: llama-index<0.10.0; extra == 'dev'
54
54
  Requires-Dist: nbqa; extra == 'dev'
55
55
  Requires-Dist: pandas-stubs<=2.0.2.230605; extra == 'dev'
56
56
  Requires-Dist: pre-commit; extra == 'dev'
57
- Requires-Dist: pytest; extra == 'dev'
58
57
  Requires-Dist: pytest-asyncio; extra == 'dev'
59
58
  Requires-Dist: pytest-cov; extra == 'dev'
60
59
  Requires-Dist: pytest-lazy-fixture; extra == 'dev'
60
+ Requires-Dist: pytest==7.4.4; extra == 'dev'
61
61
  Requires-Dist: ruff==0.1.5; extra == 'dev'
62
62
  Requires-Dist: strawberry-graphql[debug-server]==0.208.2; extra == 'dev'
63
63
  Provides-Extra: experimental
@@ -223,9 +223,8 @@ session = px.launch_app()
223
223
 
224
224
  from phoenix.trace.langchain import OpenInferenceTracer, LangChainInstrumentor
225
225
 
226
- # If no exporter is specified, the tracer will export to the locally running Phoenix server
227
- tracer = OpenInferenceTracer()
228
- LangChainInstrumentor(tracer).instrument()
226
+ # By default, the traces will be exported to the locally running Phoenix server.
227
+ LangChainInstrumentor().instrument()
229
228
 
230
229
  # Initialize your LangChain application
231
230
  from langchain.chains import RetrievalQA
@@ -1,10 +1,10 @@
1
1
  phoenix/__init__.py,sha256=MSamw7OMCIcCtrJdvJYMvQmC6O0uyehfPAXXELsllZM,1451
2
- phoenix/config.py,sha256=RbQw8AkVyI4SSo5CD520AjUNcwkDNOGZA6_ErE48R7A,3454
2
+ phoenix/config.py,sha256=RT4UR5VH8JUAKQhfmlkpxq2kmBSA8G8MODrC3GXWyaI,3507
3
3
  phoenix/datetime_utils.py,sha256=D955QLrkgrrSdUM6NyqbCeAu2SMsjhR5rHVQEsVUdng,2773
4
4
  phoenix/exceptions.py,sha256=X5k9ipUDfwSCwZB-H5zFJLas86Gf9tAx0W4l5TZxp5k,108
5
5
  phoenix/py.typed,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
6
6
  phoenix/services.py,sha256=f6AeyKTuOpy9RCcTCjVH3gx5nYZhbTMFOuv1WSUOB5o,4992
7
- phoenix/version.py,sha256=EPmgXOdWKks5S__ZMH7Nu6xpAeVrZpfxaFy4pykuyeI,22
7
+ phoenix/version.py,sha256=YKXrr5J7dV2n7ZhaRv0tigylRDtfOuvJC9Y4ouFZpzo,22
8
8
  phoenix/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
9
  phoenix/core/embedding_dimension.py,sha256=zKGbcvwOXgLf-yrJBpQyKtd-LEOPRKHnUToyAU8Owis,87
10
10
  phoenix/core/evals.py,sha256=gJyqQzpud5YjtoY8h4pgXvHDsdubGfqmEewLuZHPPmQ,10224
@@ -23,7 +23,7 @@ phoenix/experimental/evals/__init__.py,sha256=q96YKLMt2GJD9zL8sjugvWx1INfw40Wa7E
23
23
  phoenix/experimental/evals/evaluators.py,sha256=r7fXrS-l4gn58SUhLAZSfY3P8lxysouSVJwHddrZJ_Q,15956
24
24
  phoenix/experimental/evals/retrievals.py,sha256=o3fqrsYbYZjyGj_jWkN_9VQVyXjLkDKDw5Ws7l8bwdI,3828
25
25
  phoenix/experimental/evals/functions/__init__.py,sha256=NNd0-_cmIopdV7vm3rspjfgM726qoQJ4DPq_vqbnaxQ,180
26
- phoenix/experimental/evals/functions/classify.py,sha256=6yCajPT9i98b4_2qYn9ZxGhdI3CLhfUSrEyUUcqQqmQ,19517
26
+ phoenix/experimental/evals/functions/classify.py,sha256=wqsLtDVPckt4OYuyr1YzaIokqnhzfYf_bMhR5ythWww,18961
27
27
  phoenix/experimental/evals/functions/executor.py,sha256=bM7PI2rcPukQQzZ2rWqN_-Kfo_a935YJj0bh1Red8Ps,13406
28
28
  phoenix/experimental/evals/functions/generate.py,sha256=8LnnPAjBM9yxitdkaGZ67OabuDTOWBF3fvinJ_uCFRg,5584
29
29
  phoenix/experimental/evals/functions/processing.py,sha256=F4xtLsulLV4a8CkuLldRddsCim75dSTIShEJUYN6I6w,1823
@@ -141,7 +141,7 @@ phoenix/trace/errors.py,sha256=DbXSJnNErV7305tKv7pUWLD6jcVHJ6EBdSu4mZJ6IM4,112
141
141
  phoenix/trace/evaluation_conventions.py,sha256=t8jydM3U0-T5YpiQKRJ3tWdWGlHtzKyttYdw-ddvPOk,1048
142
142
  phoenix/trace/exporter.py,sha256=O-9Arn-S_B9Me-jy4Qa84y6lvxKNoa8pczrsamPl3_Q,4871
143
143
  phoenix/trace/fixtures.py,sha256=LokNedhbGYxpzXznteO4m5QehvNYjzvoh231-CMJQeY,7113
144
- phoenix/trace/otel.py,sha256=9oum5RPCsEZvKg41mEy8aKDcXHBwtR-P9eeqEXp-ts4,14642
144
+ phoenix/trace/otel.py,sha256=lJoTvkCSFiPT4dFRLMZZgZfsOoTSATctW9lQk9J30ZI,14821
145
145
  phoenix/trace/schemas.py,sha256=QDBlM94faceTnloY_ZVo2BHWWnE5UGymefC0jmfj4ew,6011
146
146
  phoenix/trace/semantic_conventions.py,sha256=u6NG85ZhbreriZr8cqJaddldM_jUcew7JilszY7JUk8,4652
147
147
  phoenix/trace/span_evaluations.py,sha256=FvY9YRnKuYIzCa-H9P5SuDaI2DeqGnVCjNgclC2v3HA,12909
@@ -169,8 +169,8 @@ phoenix/trace/v1/evaluation_pb2.pyi,sha256=cCbbx06gwQmaH14s3J1X25TtaARh-k1abbxQd
169
169
  phoenix/utilities/__init__.py,sha256=3TVirVnjIGyaCFuJCqeZO4tjlzQ_chZgYM0itIwsEpE,656
170
170
  phoenix/utilities/error_handling.py,sha256=7b5rpGFj9EWZ8yrZK1IHvxB89suWk3lggDayUQcvZds,1946
171
171
  phoenix/utilities/logging.py,sha256=lDXd6EGaamBNcQxL4vP1au9-i_SXe0OraUDiJOcszSw,222
172
- arize_phoenix-3.0.0.dist-info/METADATA,sha256=wC0glS_s7OdY7E0MQnvztpSmPYm8p-Hp_gSih5pPsAo,28597
173
- arize_phoenix-3.0.0.dist-info/WHEEL,sha256=TJPnKdtrSue7xZ_AVGkp9YXcvDrobsjBds1du3Nx6dc,87
174
- arize_phoenix-3.0.0.dist-info/licenses/IP_NOTICE,sha256=JBqyyCYYxGDfzQ0TtsQgjts41IJoa-hiwDrBjCb9gHM,469
175
- arize_phoenix-3.0.0.dist-info/licenses/LICENSE,sha256=HFkW9REuMOkvKRACuwLPT0hRydHb3zNg-fdFt94td18,3794
176
- arize_phoenix-3.0.0.dist-info/RECORD,,
172
+ arize_phoenix-3.0.2.dist-info/METADATA,sha256=80fEGOl8VUcS4B1STEVmDITkrkYytJtE6f9d7VmkyhI,28555
173
+ arize_phoenix-3.0.2.dist-info/WHEEL,sha256=TJPnKdtrSue7xZ_AVGkp9YXcvDrobsjBds1du3Nx6dc,87
174
+ arize_phoenix-3.0.2.dist-info/licenses/IP_NOTICE,sha256=JBqyyCYYxGDfzQ0TtsQgjts41IJoa-hiwDrBjCb9gHM,469
175
+ arize_phoenix-3.0.2.dist-info/licenses/LICENSE,sha256=HFkW9REuMOkvKRACuwLPT0hRydHb3zNg-fdFt94td18,3794
176
+ arize_phoenix-3.0.2.dist-info/RECORD,,
phoenix/config.py CHANGED
@@ -12,7 +12,7 @@ ENV_PHOENIX_COLLECTOR_ENDPOINT = "PHOENIX_COLLECTOR_ENDPOINT"
12
12
  The endpoint traces and evals are sent to. This must be set if the Phoenix
13
13
  server is running on a remote instance.
14
14
  """
15
- ENV_WORKING_DIR = "PHOENIX_WORKING_DIR"
15
+ ENV_PHOENIX_WORKING_DIR = "PHOENIX_WORKING_DIR"
16
16
  """
17
17
  The directory in which to save, load, and export datasets. This directory must
18
18
  be accessible by both the Phoenix server and the notebook environment.
@@ -45,7 +45,7 @@ def get_working_dir() -> Path:
45
45
  """
46
46
  Get the working directory for saving, loading, and exporting datasets.
47
47
  """
48
- working_dir_str = os.getenv(ENV_WORKING_DIR)
48
+ working_dir_str = os.getenv(ENV_PHOENIX_WORKING_DIR)
49
49
  if working_dir_str is not None:
50
50
  return Path(working_dir_str)
51
51
  # Fall back to ~/.phoenix if PHOENIX_WORKING_DIR is not set
@@ -77,7 +77,9 @@ except Exception as e:
77
77
  f"⚠️ Failed to initialize the working directory at {WORKING_DIR} due to an error: {str(e)}"
78
78
  )
79
79
  print("⚠️ While phoenix will still run, you will not be able to save, load, or export data")
80
- print("ℹ️ To change, set the `{ENV_WORKING_DIR}` environment variable before importing phoenix.")
80
+ print(
81
+ f"ℹ️ To change, set the `{ENV_PHOENIX_WORKING_DIR}` environment variable before importing phoenix." # noqa: E501
82
+ )
81
83
 
82
84
 
83
85
  def get_exported_files(directory: Path) -> List[Path]:
@@ -3,6 +3,7 @@ from __future__ import annotations
3
3
  import logging
4
4
  import warnings
5
5
  from collections import defaultdict
6
+ from itertools import product
6
7
  from typing import (
7
8
  Any,
8
9
  DefaultDict,
@@ -54,8 +55,7 @@ Label: TypeAlias = str
54
55
  Score: TypeAlias = Optional[float]
55
56
  Explanation: TypeAlias = Optional[str]
56
57
  Record: TypeAlias = Mapping[str, Any]
57
- EvaluatorIndex: TypeAlias = int
58
- RowIndex: TypeAlias = Any
58
+ Index: TypeAlias = int
59
59
 
60
60
  # snapped_response, explanation, response
61
61
  ParsedLLMResponse: TypeAlias = Tuple[Optional[str], Optional[str], str]
@@ -343,8 +343,6 @@ def _get_contents_from_openinference_documents(documents: Iterable[Any]) -> List
343
343
 
344
344
 
345
345
  class RunEvalsPayload(NamedTuple):
346
- evaluator_index: EvaluatorIndex
347
- row_index: RowIndex
348
346
  evaluator: LLMEvaluator
349
347
  record: Record
350
348
 
@@ -404,23 +402,21 @@ def run_evals(
404
402
 
405
403
  async def _arun_eval(
406
404
  payload: RunEvalsPayload,
407
- ) -> Tuple[EvaluatorIndex, RowIndex, Label, Score, Explanation]:
408
- label, score, explanation = await payload.evaluator.aevaluate(
405
+ ) -> Tuple[Label, Score, Explanation]:
406
+ return await payload.evaluator.aevaluate(
409
407
  payload.record,
410
408
  provide_explanation=provide_explanation,
411
409
  use_function_calling_if_available=use_function_calling_if_available,
412
410
  )
413
- return payload.evaluator_index, payload.row_index, label, score, explanation
414
411
 
415
412
  def _run_eval(
416
413
  payload: RunEvalsPayload,
417
- ) -> Tuple[EvaluatorIndex, RowIndex, Label, Score, Explanation]:
418
- label, score, explanation = payload.evaluator.evaluate(
414
+ ) -> Tuple[Label, Score, Explanation]:
415
+ return payload.evaluator.evaluate(
419
416
  payload.record,
420
417
  provide_explanation=provide_explanation,
421
418
  use_function_calling_if_available=use_function_calling_if_available,
422
419
  )
423
- return payload.evaluator_index, payload.row_index, label, score, explanation
424
420
 
425
421
  executor = get_executor_on_sync_context(
426
422
  _run_eval,
@@ -428,24 +424,20 @@ def run_evals(
428
424
  concurrency=concurrency,
429
425
  tqdm_bar_format=get_tqdm_progress_bar_formatter("run_evals"),
430
426
  exit_on_error=True,
431
- fallback_return_value=(None, None),
427
+ fallback_return_value=(None, None, None),
432
428
  )
429
+
430
+ total_records = len(dataframe)
433
431
  payloads = [
434
- RunEvalsPayload(
435
- evaluator_index=evaluator_index,
436
- row_index=row_index,
437
- evaluator=evaluator,
438
- record=row.to_dict(),
439
- )
440
- # use the position of the row rather than the dataframe index, which is used
441
- # to ensure the output dataframe has the same row order as the input dataframe
442
- for row_index, (_, row) in enumerate(dataframe.iterrows())
443
- for evaluator_index, evaluator in enumerate(evaluators)
432
+ RunEvalsPayload(evaluator=evaluator, record=row)
433
+ for evaluator, (_, row) in product(evaluators, dataframe.iterrows())
444
434
  ]
445
- eval_results: List[DefaultDict[RowIndex, Dict[ColumnName, Union[Label, Explanation]]]] = [
435
+ eval_results: List[DefaultDict[Index, Dict[ColumnName, Union[Label, Explanation]]]] = [
446
436
  defaultdict(dict) for _ in range(len(evaluators))
447
437
  ]
448
- for evaluator_index, row_index, label, score, explanation in executor.run(payloads):
438
+ for index, (label, score, explanation) in enumerate(executor.run(payloads)):
439
+ evaluator_index = index // total_records
440
+ row_index = index % total_records
449
441
  eval_results[evaluator_index][row_index]["label"] = label
450
442
  eval_results[evaluator_index][row_index]["score"] = score
451
443
  if provide_explanation:
phoenix/trace/otel.py CHANGED
@@ -19,6 +19,7 @@ from typing import (
19
19
  cast,
20
20
  )
21
21
 
22
+ import numpy as np
22
23
  import opentelemetry.proto.trace.v1.trace_pb2 as otlp
23
24
  from opentelemetry.proto.common.v1.common_pb2 import AnyValue, ArrayValue, KeyValue
24
25
  from opentelemetry.util.types import Attributes, AttributeValue
@@ -320,7 +321,11 @@ def encode(span: Span) -> otlp.Span:
320
321
  attributes[key] = json.dumps(value)
321
322
  else:
322
323
  attributes.update(_flatten_mapping(value, key))
323
- elif not isinstance(value, str) and isinstance(value, Sequence) and _has_mapping(value):
324
+ elif (
325
+ not isinstance(value, str)
326
+ and (isinstance(value, Sequence) or isinstance(value, np.ndarray))
327
+ and _has_mapping(value)
328
+ ):
324
329
  attributes.pop(key, None)
325
330
  attributes.update(_flatten_sequence(value, key))
326
331
 
@@ -413,6 +418,8 @@ def _encode_attributes(attributes: Attributes) -> Iterator[KeyValue]:
413
418
  if not attributes:
414
419
  return
415
420
  for key, value in attributes.items():
421
+ if isinstance(value, np.ndarray):
422
+ value = value.tolist()
416
423
  yield KeyValue(key=key, value=_encode_value(value))
417
424
 
418
425
 
phoenix/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "3.0.0"
1
+ __version__ = "3.0.2"