arize-phoenix 4.10.2rc0__py3-none-any.whl → 4.10.2rc1__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.
- {arize_phoenix-4.10.2rc0.dist-info → arize_phoenix-4.10.2rc1.dist-info}/METADATA +4 -3
- {arize_phoenix-4.10.2rc0.dist-info → arize_phoenix-4.10.2rc1.dist-info}/RECORD +27 -35
- phoenix/server/api/context.py +3 -7
- phoenix/server/api/openapi/main.py +18 -2
- phoenix/server/api/openapi/schema.py +12 -12
- phoenix/server/api/routers/v1/__init__.py +36 -83
- phoenix/server/api/routers/v1/dataset_examples.py +102 -123
- phoenix/server/api/routers/v1/datasets.py +389 -507
- phoenix/server/api/routers/v1/evaluations.py +74 -64
- phoenix/server/api/routers/v1/experiment_evaluations.py +67 -91
- phoenix/server/api/routers/v1/experiment_runs.py +97 -155
- phoenix/server/api/routers/v1/experiments.py +131 -181
- phoenix/server/api/routers/v1/spans.py +141 -173
- phoenix/server/api/routers/v1/traces.py +113 -128
- phoenix/server/api/routers/v1/utils.py +94 -0
- phoenix/server/api/types/Span.py +0 -1
- phoenix/server/app.py +148 -192
- phoenix/server/main.py +0 -3
- phoenix/server/static/index.css +6 -0
- phoenix/server/static/index.js +8547 -0
- phoenix/server/templates/index.html +25 -76
- phoenix/server/thread_server.py +2 -2
- phoenix/trace/schemas.py +0 -1
- phoenix/version.py +1 -1
- phoenix/server/openapi/docs.py +0 -221
- phoenix/server/static/.vite/manifest.json +0 -78
- phoenix/server/static/assets/components-C8sm_r1F.js +0 -1142
- phoenix/server/static/assets/index-BEKPzgQs.js +0 -100
- phoenix/server/static/assets/pages-bN7juCjh.js +0 -2885
- phoenix/server/static/assets/vendor-CUDAPm8e.js +0 -641
- phoenix/server/static/assets/vendor-DxkFTwjz.css +0 -1
- phoenix/server/static/assets/vendor-arizeai-Do2HOmcL.js +0 -662
- phoenix/server/static/assets/vendor-codemirror-CrdxOlMs.js +0 -12
- phoenix/server/static/assets/vendor-recharts-PKRvByVe.js +0 -59
- phoenix/server/static/assets/vendor-three-DwGkEfCM.js +0 -2998
- {arize_phoenix-4.10.2rc0.dist-info → arize_phoenix-4.10.2rc1.dist-info}/WHEEL +0 -0
- {arize_phoenix-4.10.2rc0.dist-info → arize_phoenix-4.10.2rc1.dist-info}/licenses/IP_NOTICE +0 -0
- {arize_phoenix-4.10.2rc0.dist-info → arize_phoenix-4.10.2rc1.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
from datetime import datetime
|
|
2
|
+
from typing import Any, List, Optional
|
|
2
3
|
|
|
4
|
+
from fastapi import APIRouter, HTTPException
|
|
5
|
+
from pydantic import BaseModel, Field
|
|
3
6
|
from sqlalchemy import select
|
|
4
7
|
from starlette.requests import Request
|
|
5
|
-
from starlette.responses import JSONResponse, Response
|
|
6
8
|
from starlette.status import HTTP_404_NOT_FOUND
|
|
7
9
|
from strawberry.relay import GlobalID
|
|
8
10
|
|
|
@@ -10,188 +12,128 @@ from phoenix.db import models
|
|
|
10
12
|
from phoenix.db.models import ExperimentRunOutput
|
|
11
13
|
from phoenix.server.api.types.node import from_global_id_with_expected_type
|
|
12
14
|
|
|
15
|
+
from .utils import ResponseBody, add_errors_to_responses
|
|
13
16
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
responses:
|
|
65
|
-
200:
|
|
66
|
-
description: Experiment run created successfully
|
|
67
|
-
content:
|
|
68
|
-
application/json:
|
|
69
|
-
schema:
|
|
70
|
-
type: object
|
|
71
|
-
properties:
|
|
72
|
-
data:
|
|
73
|
-
type: object
|
|
74
|
-
properties:
|
|
75
|
-
id:
|
|
76
|
-
type: string
|
|
77
|
-
description: The ID of the created experiment run
|
|
78
|
-
404:
|
|
79
|
-
description: Experiment or DatasetExample not found
|
|
80
|
-
"""
|
|
81
|
-
experiment_gid = GlobalID.from_id(request.path_params["experiment_id"])
|
|
17
|
+
router = APIRouter(tags=["experiments"], include_in_schema=False)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class ExperimentRun(BaseModel):
|
|
21
|
+
dataset_example_id: str = Field(
|
|
22
|
+
description="The ID of the dataset example used in the experiment run"
|
|
23
|
+
)
|
|
24
|
+
output: Any = Field(description="The output of the experiment task")
|
|
25
|
+
repetition_number: int = Field(description="The repetition number of the experiment run")
|
|
26
|
+
start_time: datetime = Field(description="The start time of the experiment run")
|
|
27
|
+
end_time: datetime = Field(description="The end time of the experiment run")
|
|
28
|
+
trace_id: Optional[str] = Field(
|
|
29
|
+
default=None, description="The ID of the corresponding trace (if one exists)"
|
|
30
|
+
)
|
|
31
|
+
error: Optional[str] = Field(
|
|
32
|
+
default=None,
|
|
33
|
+
description="Optional error message if the experiment run encountered an error",
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class CreateExperimentRunRequestBody(ExperimentRun):
|
|
38
|
+
pass
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class CreateExperimentRunResponseBodyData(BaseModel):
|
|
42
|
+
id: str = Field(description="The ID of the newly created experiment run")
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class CreateExperimentResponseBody(ResponseBody[CreateExperimentRunResponseBodyData]):
|
|
46
|
+
pass
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
@router.post(
|
|
50
|
+
"/experiments/{experiment_id}/runs",
|
|
51
|
+
operation_id="createExperimentRun",
|
|
52
|
+
summary="Create run for an experiment",
|
|
53
|
+
response_description="Experiment run created successfully",
|
|
54
|
+
responses=add_errors_to_responses(
|
|
55
|
+
[
|
|
56
|
+
{
|
|
57
|
+
"status_code": HTTP_404_NOT_FOUND,
|
|
58
|
+
"description": "Experiment or dataset example not found",
|
|
59
|
+
}
|
|
60
|
+
]
|
|
61
|
+
),
|
|
62
|
+
)
|
|
63
|
+
async def create_experiment_run(
|
|
64
|
+
request: Request, experiment_id: str, request_body: CreateExperimentRunRequestBody
|
|
65
|
+
) -> CreateExperimentResponseBody:
|
|
66
|
+
experiment_gid = GlobalID.from_id(experiment_id)
|
|
82
67
|
try:
|
|
83
|
-
|
|
68
|
+
experiment_rowid = from_global_id_with_expected_type(experiment_gid, "Experiment")
|
|
84
69
|
except ValueError:
|
|
85
|
-
|
|
86
|
-
|
|
70
|
+
raise HTTPException(
|
|
71
|
+
detail=f"Experiment with ID {experiment_gid} does not exist",
|
|
87
72
|
status_code=HTTP_404_NOT_FOUND,
|
|
88
73
|
)
|
|
89
74
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
example_gid = GlobalID.from_id(payload["dataset_example_id"])
|
|
75
|
+
example_gid = GlobalID.from_id(request_body.dataset_example_id)
|
|
93
76
|
try:
|
|
94
77
|
dataset_example_id = from_global_id_with_expected_type(example_gid, "DatasetExample")
|
|
95
78
|
except ValueError:
|
|
96
|
-
|
|
97
|
-
|
|
79
|
+
raise HTTPException(
|
|
80
|
+
detail=f"DatasetExample with ID {example_gid} does not exist",
|
|
98
81
|
status_code=HTTP_404_NOT_FOUND,
|
|
99
82
|
)
|
|
100
83
|
|
|
101
|
-
trace_id =
|
|
102
|
-
task_output =
|
|
103
|
-
repetition_number =
|
|
104
|
-
start_time =
|
|
105
|
-
end_time =
|
|
106
|
-
error =
|
|
84
|
+
trace_id = request_body.trace_id
|
|
85
|
+
task_output = request_body.output
|
|
86
|
+
repetition_number = request_body.repetition_number
|
|
87
|
+
start_time = request_body.start_time
|
|
88
|
+
end_time = request_body.end_time
|
|
89
|
+
error = request_body.error
|
|
107
90
|
|
|
108
91
|
async with request.app.state.db() as session:
|
|
109
92
|
exp_run = models.ExperimentRun(
|
|
110
|
-
experiment_id=
|
|
93
|
+
experiment_id=experiment_rowid,
|
|
111
94
|
dataset_example_id=dataset_example_id,
|
|
112
95
|
trace_id=trace_id,
|
|
113
96
|
output=ExperimentRunOutput(task_output=task_output),
|
|
114
97
|
repetition_number=repetition_number,
|
|
115
|
-
start_time=
|
|
116
|
-
end_time=
|
|
98
|
+
start_time=start_time,
|
|
99
|
+
end_time=end_time,
|
|
117
100
|
error=error,
|
|
118
101
|
)
|
|
119
102
|
session.add(exp_run)
|
|
120
103
|
await session.flush()
|
|
121
104
|
run_gid = GlobalID("ExperimentRun", str(exp_run.id))
|
|
122
|
-
return
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
application/json:
|
|
143
|
-
schema:
|
|
144
|
-
type: object
|
|
145
|
-
properties:
|
|
146
|
-
data:
|
|
147
|
-
type: array
|
|
148
|
-
items:
|
|
149
|
-
type: object
|
|
150
|
-
properties:
|
|
151
|
-
id:
|
|
152
|
-
type: string
|
|
153
|
-
description: The ID of the experiment run
|
|
154
|
-
experiment_id:
|
|
155
|
-
type: string
|
|
156
|
-
description: The ID of the experiment
|
|
157
|
-
dataset_example_id:
|
|
158
|
-
type: string
|
|
159
|
-
description: The ID of the dataset example
|
|
160
|
-
repetition_number:
|
|
161
|
-
type: integer
|
|
162
|
-
description: The repetition number of the experiment run
|
|
163
|
-
start_time:
|
|
164
|
-
type: string
|
|
165
|
-
format: date-time
|
|
166
|
-
description: The start time of the experiment run in ISO format
|
|
167
|
-
end_time:
|
|
168
|
-
type: string
|
|
169
|
-
format: date-time
|
|
170
|
-
description: The end time of the experiment run in ISO format
|
|
171
|
-
output:
|
|
172
|
-
description: The output of the experiment task
|
|
173
|
-
error:
|
|
174
|
-
type: string
|
|
175
|
-
description: Error message if the experiment run encountered an error
|
|
176
|
-
trace_id:
|
|
177
|
-
type: string
|
|
178
|
-
description: Optional trace ID for tracking
|
|
179
|
-
404:
|
|
180
|
-
description: Experiment not found
|
|
181
|
-
"""
|
|
182
|
-
experiment_gid = GlobalID.from_id(request.path_params["experiment_id"])
|
|
105
|
+
return CreateExperimentResponseBody(data=CreateExperimentRunResponseBodyData(id=str(run_gid)))
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
class ListExperimentRunsResponseBody(ResponseBody[List[ExperimentRun]]):
|
|
109
|
+
pass
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
@router.get(
|
|
113
|
+
"/experiments/{experiment_id}/runs",
|
|
114
|
+
operation_id="listExperimentRuns",
|
|
115
|
+
summary="List runs for an experiment",
|
|
116
|
+
response_description="Experiment runs retrieved successfully",
|
|
117
|
+
responses=add_errors_to_responses(
|
|
118
|
+
[{"status_code": HTTP_404_NOT_FOUND, "description": "Experiment not found"}]
|
|
119
|
+
),
|
|
120
|
+
)
|
|
121
|
+
async def list_experiment_runs(
|
|
122
|
+
request: Request, experiment_id: str
|
|
123
|
+
) -> ListExperimentRunsResponseBody:
|
|
124
|
+
experiment_gid = GlobalID.from_id(experiment_id)
|
|
183
125
|
try:
|
|
184
|
-
|
|
126
|
+
experiment_rowid = from_global_id_with_expected_type(experiment_gid, "Experiment")
|
|
185
127
|
except ValueError:
|
|
186
|
-
|
|
187
|
-
|
|
128
|
+
raise HTTPException(
|
|
129
|
+
detail=f"Experiment with ID {experiment_gid} does not exist",
|
|
188
130
|
status_code=HTTP_404_NOT_FOUND,
|
|
189
131
|
)
|
|
190
132
|
|
|
191
133
|
async with request.app.state.db() as session:
|
|
192
134
|
experiment_runs = await session.execute(
|
|
193
135
|
select(models.ExperimentRun)
|
|
194
|
-
.where(models.ExperimentRun.experiment_id ==
|
|
136
|
+
.where(models.ExperimentRun.experiment_id == experiment_rowid)
|
|
195
137
|
# order by dataset_example_id to be consistent with `list_dataset_examples`
|
|
196
138
|
.order_by(models.ExperimentRun.dataset_example_id.asc())
|
|
197
139
|
)
|
|
@@ -202,9 +144,9 @@ async def list_experiment_runs(request: Request) -> Response:
|
|
|
202
144
|
experiment_gid = GlobalID("Experiment", str(exp_run.experiment_id))
|
|
203
145
|
example_gid = GlobalID("DatasetExample", str(exp_run.dataset_example_id))
|
|
204
146
|
runs.append(
|
|
205
|
-
|
|
206
|
-
start_time=exp_run.start_time
|
|
207
|
-
end_time=exp_run.end_time
|
|
147
|
+
ExperimentRun(
|
|
148
|
+
start_time=exp_run.start_time,
|
|
149
|
+
end_time=exp_run.end_time,
|
|
208
150
|
experiment_id=str(experiment_gid),
|
|
209
151
|
dataset_example_id=str(example_gid),
|
|
210
152
|
repetition_number=exp_run.repetition_number,
|
|
@@ -214,4 +156,4 @@ async def list_experiment_runs(request: Request) -> Response:
|
|
|
214
156
|
trace_id=exp_run.trace_id,
|
|
215
157
|
)
|
|
216
158
|
)
|
|
217
|
-
return
|
|
159
|
+
return ListExperimentRunsResponseBody(data=runs)
|