arize-phoenix 4.4.4rc6__py3-none-any.whl → 4.5.0__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.

Files changed (123) hide show
  1. {arize_phoenix-4.4.4rc6.dist-info → arize_phoenix-4.5.0.dist-info}/METADATA +8 -14
  2. {arize_phoenix-4.4.4rc6.dist-info → arize_phoenix-4.5.0.dist-info}/RECORD +58 -122
  3. {arize_phoenix-4.4.4rc6.dist-info → arize_phoenix-4.5.0.dist-info}/WHEEL +1 -1
  4. phoenix/__init__.py +27 -0
  5. phoenix/config.py +7 -42
  6. phoenix/core/model.py +25 -25
  7. phoenix/core/model_schema.py +62 -64
  8. phoenix/core/model_schema_adapter.py +25 -27
  9. phoenix/datetime_utils.py +0 -4
  10. phoenix/db/bulk_inserter.py +14 -54
  11. phoenix/db/insertion/evaluation.py +10 -10
  12. phoenix/db/insertion/helpers.py +14 -17
  13. phoenix/db/insertion/span.py +3 -3
  14. phoenix/db/migrations/versions/cf03bd6bae1d_init.py +28 -2
  15. phoenix/db/models.py +4 -236
  16. phoenix/inferences/fixtures.py +23 -23
  17. phoenix/inferences/inferences.py +7 -7
  18. phoenix/inferences/validation.py +1 -1
  19. phoenix/server/api/context.py +0 -20
  20. phoenix/server/api/dataloaders/__init__.py +0 -20
  21. phoenix/server/api/dataloaders/span_descendants.py +3 -2
  22. phoenix/server/api/routers/v1/__init__.py +2 -77
  23. phoenix/server/api/routers/v1/evaluations.py +13 -8
  24. phoenix/server/api/routers/v1/spans.py +5 -9
  25. phoenix/server/api/routers/v1/traces.py +4 -1
  26. phoenix/server/api/schema.py +303 -2
  27. phoenix/server/api/types/Cluster.py +19 -19
  28. phoenix/server/api/types/Dataset.py +63 -282
  29. phoenix/server/api/types/DatasetRole.py +23 -0
  30. phoenix/server/api/types/Dimension.py +29 -30
  31. phoenix/server/api/types/EmbeddingDimension.py +34 -40
  32. phoenix/server/api/types/Event.py +16 -16
  33. phoenix/server/api/{mutations/export_events_mutations.py → types/ExportEventsMutation.py} +14 -17
  34. phoenix/server/api/types/Model.py +42 -43
  35. phoenix/server/api/types/Project.py +12 -26
  36. phoenix/server/api/types/Span.py +2 -79
  37. phoenix/server/api/types/TimeSeries.py +6 -6
  38. phoenix/server/api/types/Trace.py +4 -15
  39. phoenix/server/api/types/UMAPPoints.py +1 -1
  40. phoenix/server/api/types/node.py +111 -5
  41. phoenix/server/api/types/pagination.py +52 -10
  42. phoenix/server/app.py +49 -103
  43. phoenix/server/main.py +27 -49
  44. phoenix/server/openapi/docs.py +0 -3
  45. phoenix/server/static/index.js +1384 -2390
  46. phoenix/server/templates/index.html +0 -1
  47. phoenix/services.py +15 -15
  48. phoenix/session/client.py +23 -611
  49. phoenix/session/session.py +37 -47
  50. phoenix/trace/exporter.py +9 -14
  51. phoenix/trace/fixtures.py +7 -133
  52. phoenix/trace/schemas.py +2 -1
  53. phoenix/trace/span_evaluations.py +3 -3
  54. phoenix/trace/trace_dataset.py +6 -6
  55. phoenix/version.py +1 -1
  56. phoenix/db/insertion/dataset.py +0 -237
  57. phoenix/db/migrations/types.py +0 -29
  58. phoenix/db/migrations/versions/10460e46d750_datasets.py +0 -291
  59. phoenix/experiments/__init__.py +0 -6
  60. phoenix/experiments/evaluators/__init__.py +0 -29
  61. phoenix/experiments/evaluators/base.py +0 -153
  62. phoenix/experiments/evaluators/code_evaluators.py +0 -99
  63. phoenix/experiments/evaluators/llm_evaluators.py +0 -244
  64. phoenix/experiments/evaluators/utils.py +0 -189
  65. phoenix/experiments/functions.py +0 -616
  66. phoenix/experiments/tracing.py +0 -85
  67. phoenix/experiments/types.py +0 -722
  68. phoenix/experiments/utils.py +0 -9
  69. phoenix/server/api/dataloaders/average_experiment_run_latency.py +0 -54
  70. phoenix/server/api/dataloaders/dataset_example_revisions.py +0 -100
  71. phoenix/server/api/dataloaders/dataset_example_spans.py +0 -43
  72. phoenix/server/api/dataloaders/experiment_annotation_summaries.py +0 -85
  73. phoenix/server/api/dataloaders/experiment_error_rates.py +0 -43
  74. phoenix/server/api/dataloaders/experiment_run_counts.py +0 -42
  75. phoenix/server/api/dataloaders/experiment_sequence_number.py +0 -49
  76. phoenix/server/api/dataloaders/project_by_name.py +0 -31
  77. phoenix/server/api/dataloaders/span_projects.py +0 -33
  78. phoenix/server/api/dataloaders/trace_row_ids.py +0 -39
  79. phoenix/server/api/helpers/dataset_helpers.py +0 -179
  80. phoenix/server/api/input_types/AddExamplesToDatasetInput.py +0 -16
  81. phoenix/server/api/input_types/AddSpansToDatasetInput.py +0 -14
  82. phoenix/server/api/input_types/ClearProjectInput.py +0 -15
  83. phoenix/server/api/input_types/CreateDatasetInput.py +0 -12
  84. phoenix/server/api/input_types/DatasetExampleInput.py +0 -14
  85. phoenix/server/api/input_types/DatasetSort.py +0 -17
  86. phoenix/server/api/input_types/DatasetVersionSort.py +0 -16
  87. phoenix/server/api/input_types/DeleteDatasetExamplesInput.py +0 -13
  88. phoenix/server/api/input_types/DeleteDatasetInput.py +0 -7
  89. phoenix/server/api/input_types/DeleteExperimentsInput.py +0 -9
  90. phoenix/server/api/input_types/PatchDatasetExamplesInput.py +0 -35
  91. phoenix/server/api/input_types/PatchDatasetInput.py +0 -14
  92. phoenix/server/api/mutations/__init__.py +0 -13
  93. phoenix/server/api/mutations/auth.py +0 -11
  94. phoenix/server/api/mutations/dataset_mutations.py +0 -520
  95. phoenix/server/api/mutations/experiment_mutations.py +0 -65
  96. phoenix/server/api/mutations/project_mutations.py +0 -47
  97. phoenix/server/api/openapi/__init__.py +0 -0
  98. phoenix/server/api/openapi/main.py +0 -6
  99. phoenix/server/api/openapi/schema.py +0 -16
  100. phoenix/server/api/queries.py +0 -503
  101. phoenix/server/api/routers/v1/dataset_examples.py +0 -178
  102. phoenix/server/api/routers/v1/datasets.py +0 -965
  103. phoenix/server/api/routers/v1/experiment_evaluations.py +0 -65
  104. phoenix/server/api/routers/v1/experiment_runs.py +0 -96
  105. phoenix/server/api/routers/v1/experiments.py +0 -174
  106. phoenix/server/api/types/AnnotatorKind.py +0 -10
  107. phoenix/server/api/types/CreateDatasetPayload.py +0 -8
  108. phoenix/server/api/types/DatasetExample.py +0 -85
  109. phoenix/server/api/types/DatasetExampleRevision.py +0 -34
  110. phoenix/server/api/types/DatasetVersion.py +0 -14
  111. phoenix/server/api/types/ExampleRevisionInterface.py +0 -14
  112. phoenix/server/api/types/Experiment.py +0 -147
  113. phoenix/server/api/types/ExperimentAnnotationSummary.py +0 -13
  114. phoenix/server/api/types/ExperimentComparison.py +0 -19
  115. phoenix/server/api/types/ExperimentRun.py +0 -91
  116. phoenix/server/api/types/ExperimentRunAnnotation.py +0 -57
  117. phoenix/server/api/types/Inferences.py +0 -80
  118. phoenix/server/api/types/InferencesRole.py +0 -23
  119. phoenix/utilities/json.py +0 -61
  120. phoenix/utilities/re.py +0 -50
  121. {arize_phoenix-4.4.4rc6.dist-info → arize_phoenix-4.5.0.dist-info}/licenses/IP_NOTICE +0 -0
  122. {arize_phoenix-4.4.4rc6.dist-info → arize_phoenix-4.5.0.dist-info}/licenses/LICENSE +0 -0
  123. /phoenix/server/api/{helpers/__init__.py → helpers.py} +0 -0
@@ -1,179 +0,0 @@
1
- import json
2
- from typing import Any, Dict, Literal, Mapping, Optional, Protocol
3
-
4
- from openinference.semconv.trace import (
5
- MessageAttributes,
6
- OpenInferenceMimeTypeValues,
7
- OpenInferenceSpanKindValues,
8
- ToolCallAttributes,
9
- )
10
-
11
- from phoenix.trace.attributes import get_attribute_value
12
-
13
-
14
- class HasSpanIO(Protocol):
15
- """
16
- An interface that contains the information needed to extract dataset example
17
- input and output values from a span.
18
- """
19
-
20
- span_kind: Optional[str]
21
- input_value: Any
22
- input_mime_type: Optional[str]
23
- output_value: Any
24
- output_mime_type: Optional[str]
25
- llm_prompt_template_variables: Any
26
- llm_input_messages: Any
27
- llm_output_messages: Any
28
- retrieval_documents: Any
29
-
30
-
31
- def get_dataset_example_input(span: HasSpanIO) -> Dict[str, Any]:
32
- """
33
- Extracts the input value from a span and returns it as a dictionary. Input
34
- values from LLM spans are extracted from the input messages and prompt
35
- template variables (if present). For other span kinds, the input is
36
- extracted from the input value and input mime type attributes.
37
- """
38
- input_value = span.input_value
39
- input_mime_type = span.input_mime_type
40
- if span.span_kind == OpenInferenceSpanKindValues.LLM.value:
41
- return _get_llm_span_input(
42
- input_messages=span.llm_input_messages,
43
- input_value=input_value,
44
- input_mime_type=input_mime_type,
45
- prompt_template_variables=span.llm_prompt_template_variables,
46
- )
47
- return _get_generic_io_value(io_value=input_value, mime_type=input_mime_type, kind="input")
48
-
49
-
50
- def get_dataset_example_output(span: HasSpanIO) -> Dict[str, Any]:
51
- """
52
- Extracts the output value from a span and returns it as a dictionary. Output
53
- values from LLM spans are extracted from the output messages (if present).
54
- Output from retriever spans are extracted from the retrieval documents (if
55
- present). For other span kinds, the output is extracted from the output
56
- value and output mime type attributes.
57
- """
58
-
59
- output_value = span.output_value
60
- output_mime_type = span.output_mime_type
61
- if (span_kind := span.span_kind) == OpenInferenceSpanKindValues.LLM.value:
62
- return _get_llm_span_output(
63
- output_messages=span.llm_output_messages,
64
- output_value=output_value,
65
- output_mime_type=output_mime_type,
66
- )
67
- if span_kind == OpenInferenceSpanKindValues.RETRIEVER.value:
68
- return _get_retriever_span_output(
69
- retrieval_documents=span.retrieval_documents,
70
- output_value=output_value,
71
- output_mime_type=output_mime_type,
72
- )
73
- return _get_generic_io_value(io_value=output_value, mime_type=output_mime_type, kind="output")
74
-
75
-
76
- def _get_llm_span_input(
77
- input_messages: Any,
78
- input_value: Any,
79
- input_mime_type: Optional[str],
80
- prompt_template_variables: Any,
81
- ) -> Dict[str, Any]:
82
- """
83
- Extracts the input value from an LLM span and returns it as a dictionary.
84
- The input is extracted from the input messages (if present) and prompt
85
- template variables (if present).
86
- """
87
- input: Dict[str, Any] = {}
88
- if messages := [_get_message(m) for m in input_messages or ()]:
89
- input["messages"] = messages
90
- if not input:
91
- input = _get_generic_io_value(io_value=input_value, mime_type=input_mime_type, kind="input")
92
- if prompt_template_variables:
93
- input = {**input, "prompt_template_variables": prompt_template_variables}
94
- return input
95
-
96
-
97
- def _get_llm_span_output(
98
- output_messages: Any,
99
- output_value: Any,
100
- output_mime_type: Optional[str],
101
- ) -> Dict[str, Any]:
102
- """
103
- Extracts the output value from an LLM span and returns it as a dictionary.
104
- The output is extracted from the output messages (if present).
105
- """
106
- if messages := [_get_message(m) for m in output_messages or ()]:
107
- return {"messages": messages}
108
- return _get_generic_io_value(io_value=output_value, mime_type=output_mime_type, kind="output")
109
-
110
-
111
- def _get_retriever_span_output(
112
- retrieval_documents: Any,
113
- output_value: Any,
114
- output_mime_type: Optional[str],
115
- ) -> Dict[str, Any]:
116
- """
117
- Extracts the output value from a retriever span and returns it as a dictionary.
118
- The output is extracted from the retrieval documents (if present).
119
- """
120
- if retrieval_documents is not None:
121
- return {"documents": retrieval_documents}
122
- return _get_generic_io_value(io_value=output_value, mime_type=output_mime_type, kind="output")
123
-
124
-
125
- def _get_generic_io_value(
126
- io_value: Any, mime_type: Optional[str], kind: Literal["input", "output"]
127
- ) -> Dict[str, Any]:
128
- """
129
- Makes a best-effort attempt to extract the input or output value from a span
130
- and returns it as a dictionary.
131
- """
132
- if mime_type == OpenInferenceMimeTypeValues.JSON.value:
133
- parsed_value = json.loads(io_value)
134
- if isinstance(parsed_value, dict):
135
- return parsed_value
136
- else:
137
- return {kind: parsed_value}
138
- if isinstance(io_value, str):
139
- return {kind: io_value}
140
- return {}
141
-
142
-
143
- def _get_message(message: Mapping[str, Any]) -> Dict[str, Any]:
144
- content = get_attribute_value(message, MESSAGE_CONTENT)
145
- name = get_attribute_value(message, MESSAGE_NAME)
146
- function_call_name = get_attribute_value(message, MESSAGE_FUNCTION_CALL_NAME)
147
- function_call_arguments = get_attribute_value(message, MESSAGE_FUNCTION_CALL_ARGUMENTS_JSON)
148
- function_call = (
149
- {"name": function_call_name, "arguments": function_call_arguments}
150
- if function_call_name is not None or function_call_arguments is not None
151
- else None
152
- )
153
- tool_calls = [
154
- {
155
- "function": {
156
- "name": get_attribute_value(tool_call, TOOL_CALL_FUNCTION_NAME),
157
- "arguments": get_attribute_value(tool_call, TOOL_CALL_FUNCTION_ARGUMENTS_JSON),
158
- }
159
- }
160
- for tool_call in get_attribute_value(message, MESSAGE_TOOL_CALLS) or ()
161
- ]
162
- return {
163
- "role": get_attribute_value(message, MESSAGE_ROLE),
164
- **({"content": content} if content is not None else {}),
165
- **({"name": name} if name is not None else {}),
166
- **({"function_call": function_call} if function_call is not None else {}),
167
- **({"tool_calls": tool_calls} if tool_calls else {}),
168
- }
169
-
170
-
171
- MESSAGE_CONTENT = MessageAttributes.MESSAGE_CONTENT
172
- MESSAGE_FUNCTION_CALL_ARGUMENTS_JSON = MessageAttributes.MESSAGE_FUNCTION_CALL_ARGUMENTS_JSON
173
- MESSAGE_FUNCTION_CALL_NAME = MessageAttributes.MESSAGE_FUNCTION_CALL_NAME
174
- MESSAGE_NAME = MessageAttributes.MESSAGE_NAME
175
- MESSAGE_ROLE = MessageAttributes.MESSAGE_ROLE
176
- MESSAGE_TOOL_CALLS = MessageAttributes.MESSAGE_TOOL_CALLS
177
-
178
- TOOL_CALL_FUNCTION_NAME = ToolCallAttributes.TOOL_CALL_FUNCTION_NAME
179
- TOOL_CALL_FUNCTION_ARGUMENTS_JSON = ToolCallAttributes.TOOL_CALL_FUNCTION_ARGUMENTS_JSON
@@ -1,16 +0,0 @@
1
- from typing import List, Optional
2
-
3
- import strawberry
4
- from strawberry import UNSET
5
- from strawberry.relay import GlobalID
6
- from strawberry.scalars import JSON
7
-
8
- from .DatasetExampleInput import DatasetExampleInput
9
-
10
-
11
- @strawberry.input
12
- class AddExamplesToDatasetInput:
13
- dataset_id: GlobalID
14
- examples: List[DatasetExampleInput]
15
- dataset_version_description: Optional[str] = UNSET
16
- dataset_version_metadata: Optional[JSON] = UNSET
@@ -1,14 +0,0 @@
1
- from typing import List, Optional
2
-
3
- import strawberry
4
- from strawberry import UNSET
5
- from strawberry.relay import GlobalID
6
- from strawberry.scalars import JSON
7
-
8
-
9
- @strawberry.input
10
- class AddSpansToDatasetInput:
11
- dataset_id: GlobalID
12
- span_ids: List[GlobalID]
13
- dataset_version_description: Optional[str] = UNSET
14
- dataset_version_metadata: Optional[JSON] = UNSET
@@ -1,15 +0,0 @@
1
- from datetime import datetime
2
- from typing import Optional
3
-
4
- import strawberry
5
- from strawberry import UNSET
6
- from strawberry.relay import GlobalID
7
-
8
-
9
- @strawberry.input
10
- class ClearProjectInput:
11
- id: GlobalID
12
- end_time: Optional[datetime] = strawberry.field(
13
- default=UNSET,
14
- description="The time up to which to purge data. Time is right-open /non-inclusive.",
15
- )
@@ -1,12 +0,0 @@
1
- from typing import Optional
2
-
3
- import strawberry
4
- from strawberry import UNSET
5
- from strawberry.scalars import JSON
6
-
7
-
8
- @strawberry.input
9
- class CreateDatasetInput:
10
- name: str
11
- description: Optional[str] = UNSET
12
- metadata: Optional[JSON] = UNSET
@@ -1,14 +0,0 @@
1
- from typing import Optional
2
-
3
- import strawberry
4
- from strawberry import UNSET
5
- from strawberry.relay import GlobalID
6
- from strawberry.scalars import JSON
7
-
8
-
9
- @strawberry.input
10
- class DatasetExampleInput:
11
- input: JSON
12
- output: JSON
13
- metadata: JSON
14
- span_id: Optional[GlobalID] = UNSET
@@ -1,17 +0,0 @@
1
- from enum import Enum
2
-
3
- import strawberry
4
-
5
- from phoenix.server.api.types.SortDir import SortDir
6
-
7
-
8
- @strawberry.enum
9
- class DatasetColumn(Enum):
10
- createdAt = "created_at"
11
- name = "name"
12
-
13
-
14
- @strawberry.input(description="The sort key and direction for dataset connections")
15
- class DatasetSort:
16
- col: DatasetColumn
17
- dir: SortDir
@@ -1,16 +0,0 @@
1
- from enum import Enum
2
-
3
- import strawberry
4
-
5
- from phoenix.server.api.types.SortDir import SortDir
6
-
7
-
8
- @strawberry.enum
9
- class DatasetVersionColumn(Enum):
10
- createdAt = "created_at"
11
-
12
-
13
- @strawberry.input(description="The sort key and direction for dataset version connections")
14
- class DatasetVersionSort:
15
- col: DatasetVersionColumn
16
- dir: SortDir
@@ -1,13 +0,0 @@
1
- from typing import List, Optional
2
-
3
- import strawberry
4
- from strawberry import UNSET
5
- from strawberry.relay import GlobalID
6
- from strawberry.scalars import JSON
7
-
8
-
9
- @strawberry.input
10
- class DeleteDatasetExamplesInput:
11
- example_ids: List[GlobalID]
12
- dataset_version_description: Optional[str] = UNSET
13
- dataset_version_metadata: Optional[JSON] = UNSET
@@ -1,7 +0,0 @@
1
- import strawberry
2
- from strawberry.relay import GlobalID
3
-
4
-
5
- @strawberry.input
6
- class DeleteDatasetInput:
7
- dataset_id: GlobalID
@@ -1,9 +0,0 @@
1
- from typing import List
2
-
3
- import strawberry
4
- from strawberry.relay import GlobalID
5
-
6
-
7
- @strawberry.input
8
- class DeleteExperimentsInput:
9
- experiment_ids: List[GlobalID]
@@ -1,35 +0,0 @@
1
- from typing import List, Optional
2
-
3
- import strawberry
4
- from strawberry import UNSET
5
- from strawberry.relay import GlobalID
6
- from strawberry.scalars import JSON
7
-
8
-
9
- @strawberry.input
10
- class DatasetExamplePatch:
11
- """
12
- Contains the information needed to apply a patch revision to a dataset example.
13
- """
14
-
15
- example_id: GlobalID
16
- input: Optional[JSON] = UNSET
17
- output: Optional[JSON] = UNSET
18
- metadata: Optional[JSON] = UNSET
19
-
20
- def is_empty(self) -> bool:
21
- """
22
- Non-empty patches have at least one field set.
23
- """
24
- return all(field is UNSET for field in (self.input, self.output, self.metadata))
25
-
26
-
27
- @strawberry.input
28
- class PatchDatasetExamplesInput:
29
- """
30
- Input type to the patchDatasetExamples mutation.
31
- """
32
-
33
- patches: List[DatasetExamplePatch]
34
- version_description: Optional[str] = UNSET
35
- version_metadata: Optional[JSON] = UNSET
@@ -1,14 +0,0 @@
1
- from typing import Optional
2
-
3
- import strawberry
4
- from strawberry import UNSET
5
- from strawberry.relay import GlobalID
6
- from strawberry.scalars import JSON
7
-
8
-
9
- @strawberry.input
10
- class PatchDatasetInput:
11
- dataset_id: GlobalID
12
- name: Optional[str] = UNSET
13
- description: Optional[str] = UNSET
14
- metadata: Optional[JSON] = UNSET
@@ -1,13 +0,0 @@
1
- import strawberry
2
-
3
- from phoenix.server.api.mutations.dataset_mutations import DatasetMutationMixin
4
- from phoenix.server.api.mutations.experiment_mutations import ExperimentMutationMixin
5
- from phoenix.server.api.mutations.export_events_mutations import ExportEventsMutationMixin
6
- from phoenix.server.api.mutations.project_mutations import ProjectMutationMixin
7
-
8
-
9
- @strawberry.type
10
- class Mutation(
11
- ProjectMutationMixin, DatasetMutationMixin, ExperimentMutationMixin, ExportEventsMutationMixin
12
- ):
13
- pass
@@ -1,11 +0,0 @@
1
- from typing import Any
2
-
3
- from strawberry import Info
4
- from strawberry.permission import BasePermission
5
-
6
-
7
- class IsAuthenticated(BasePermission):
8
- message = "User is not authenticated"
9
-
10
- async def has_permission(self, source: Any, info: Info, **kwargs: Any) -> bool:
11
- return not info.context.read_only