arize-phoenix 4.10.2rc1__py3-none-any.whl → 4.11.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.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: arize-phoenix
3
- Version: 4.10.2rc1
3
+ Version: 4.11.0
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
@@ -22,7 +22,6 @@ Requires-Dist: aiosqlite
22
22
  Requires-Dist: alembic<2,>=1.3.0
23
23
  Requires-Dist: arize-phoenix-evals>=0.13.1
24
24
  Requires-Dist: cachetools
25
- Requires-Dist: fastapi
26
25
  Requires-Dist: grpcio
27
26
  Requires-Dist: hdbscan>=0.8.33
28
27
  Requires-Dist: httpx
@@ -41,8 +40,8 @@ Requires-Dist: pandas>=1.0
41
40
  Requires-Dist: protobuf<6.0,>=3.20
42
41
  Requires-Dist: psutil
43
42
  Requires-Dist: pyarrow
44
- Requires-Dist: pydantic<3,>=1.0
45
43
  Requires-Dist: python-multipart
44
+ Requires-Dist: pyyaml
46
45
  Requires-Dist: scikit-learn
47
46
  Requires-Dist: scipy
48
47
  Requires-Dist: sqlalchemy[asyncio]<3,>=2.0.4
@@ -57,9 +56,9 @@ Requires-Dist: uvicorn
57
56
  Requires-Dist: wrapt
58
57
  Provides-Extra: container
59
58
  Requires-Dist: opentelemetry-exporter-otlp; extra == 'container'
60
- Requires-Dist: opentelemetry-instrumentation-fastapi; extra == 'container'
61
59
  Requires-Dist: opentelemetry-instrumentation-grpc; extra == 'container'
62
60
  Requires-Dist: opentelemetry-instrumentation-sqlalchemy; extra == 'container'
61
+ Requires-Dist: opentelemetry-instrumentation-starlette; extra == 'container'
63
62
  Requires-Dist: opentelemetry-proto>=1.12.0; extra == 'container'
64
63
  Requires-Dist: opentelemetry-sdk; extra == 'container'
65
64
  Requires-Dist: opentelemetry-semantic-conventions; extra == 'container'
@@ -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=aTxhcOA1pZHB6U-B3TEcp6fqDF5oT0xCUvEUNMZVTUQ,5175
7
7
  phoenix/settings.py,sha256=cO-qgis_S27nHirTobYI9hHPfZH18R--WMmxNdsVUwc,273
8
- phoenix/version.py,sha256=Zr3eSPGuwbAWbpKhNj_q-3yeFI5ZZ6HVj7RbDS_7Y14,26
8
+ phoenix/version.py,sha256=MQuf3fbMpjUKJ6HrU3RU6E8TZHYxYwKcBl_cp_Aa-OQ,23
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=km_a--PBHOuA337ClRw9xqhOHhrUT6Rl9pz_zV0JYkQ,4843
@@ -60,14 +60,14 @@ phoenix/pointcloud/pointcloud.py,sha256=4zAIkKs2xOUbchpj4XDAV-iPMXrfAJ15TG6rlIYG
60
60
  phoenix/pointcloud/projectors.py,sha256=zO_RrtDYSv2rqVOfIP2_9Cv11Dc8EmcZR94xhFcBYPU,1057
61
61
  phoenix/pointcloud/umap_parameters.py,sha256=3UQSjrysVOvq2V4KNpTMqNqNiK0BsTZnPBHWZ4fyJtQ,1708
62
62
  phoenix/server/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
63
- phoenix/server/app.py,sha256=2-zGgV1zyeWtnkLLmgqgIU0o7QQ7eHqGTb2bv1ydLXY,17555
63
+ phoenix/server/app.py,sha256=KlvL1Rg9bC1khIip7Rv9ADR9mpEhCiu1in-8WLlw-bc,18647
64
64
  phoenix/server/grpc_server.py,sha256=faktLxEtWGlCB1bPR4QwwTsRoQloahKMx0hAWqRGI5s,3379
65
65
  phoenix/server/main.py,sha256=GpjmstVb4o-xjg0u7t4z1WXRmdxWMOw_XhQ7tPc7Fd8,11113
66
66
  phoenix/server/prometheus.py,sha256=j9DHB2fERuq_ZKmwVaqR-9wx5WcPPuU1Cm5Bhg5241Y,2996
67
67
  phoenix/server/telemetry.py,sha256=T_2OKrxNViAeaANlNspEekg_Y5uZIFWvKAnpz8Aoqvk,2762
68
- phoenix/server/thread_server.py,sha256=RwXQGP_QhGD7le6WB7xEygEEuwBl5Ck_Zo8xGIYGi9M,2135
68
+ phoenix/server/thread_server.py,sha256=dP6cm6Cf08jNhDA1TRlVZpziu1YgtPDmaeIJMm725eI,2154
69
69
  phoenix/server/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
70
- phoenix/server/api/context.py,sha256=G9bmB3h-a4Top6wGAu91ymS-YE6D1DYQyWtPIlZnbgc,2811
70
+ phoenix/server/api/context.py,sha256=DiK2IRMBbMvBF0uK20YBftApJXau4GSDHltVZX2yERQ,2957
71
71
  phoenix/server/api/interceptor.py,sha256=ykDnoC_apUd-llVli3m1CW18kNSIgjz2qZ6m5JmPDu8,1294
72
72
  phoenix/server/api/queries.py,sha256=eq2xHaQF-x4k6AGSY6b6mU2pie9bj-AJML6P2Mr0_DM,19886
73
73
  phoenix/server/api/schema.py,sha256=BcxdqO5CSGqpKd-AAJHMjFlzaK9oJA8GJuxmMfcdjn4,434
@@ -134,20 +134,19 @@ phoenix/server/api/mutations/project_mutations.py,sha256=d_xtYkYfZ5flpVgEkGknKB8
134
134
  phoenix/server/api/mutations/span_annotations_mutations.py,sha256=Pfaq4y-FGskPit4z_9GvsyWeBwK1g3CDi2UhGKxyjFE,4973
135
135
  phoenix/server/api/mutations/trace_annotations_mutations.py,sha256=4xm-zg8PEjwjfVRsWzBD_iiOS94JI6UYtK3fV2dtA4M,5013
136
136
  phoenix/server/api/openapi/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
137
- phoenix/server/api/openapi/main.py,sha256=KNutA_7AvV_WlGX8cOkvvDujcJKQ7AD1HT6rTpCpR8A,616
138
- phoenix/server/api/openapi/schema.py,sha256=oVZoflWMfzOrLKMIrjr3iLnJ13rmN-t_DOe9g6KoN5s,471
137
+ phoenix/server/api/openapi/main.py,sha256=WY0pj3B7siQyyYqKyhqnzWC7P8MtEtiukOBUjGwLXfw,153
138
+ phoenix/server/api/openapi/schema.py,sha256=uuSYe1Ecu72aXRgTNjyMu-9ZPE13DAHJPKtedS-MsSs,451
139
139
  phoenix/server/api/routers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
140
140
  phoenix/server/api/routers/utils.py,sha256=M41BoH-fl37izhRuN2aX7lWm7jOC20A_3uClv9TVUUY,583
141
- phoenix/server/api/routers/v1/__init__.py,sha256=nb49zcOdAi3DSGuC9gUubN9Yri-o7-WFdlGak4jGuFw,1462
142
- phoenix/server/api/routers/v1/dataset_examples.py,sha256=HSPc4PTnGRqyHSXP7qAZtZ39OG3SVk7btU0HmJyrL14,5595
143
- phoenix/server/api/routers/v1/datasets.py,sha256=B2k8IiIkmXEPTdBruGlOUZQmgjj2_G2Bet0_h-X-yZY,32189
144
- phoenix/server/api/routers/v1/evaluations.py,sha256=M1PKCNL_5xB9EXY4EOnrOu9uDoeJan6V1tRkSbRJEgA,9673
145
- phoenix/server/api/routers/v1/experiment_evaluations.py,sha256=Wk6YnjvA3zSh8N0lRxS8V5uf17tLsNzB12LrNDry1I0,4622
146
- phoenix/server/api/routers/v1/experiment_runs.py,sha256=CJtTWSJni0xucDUQ-ouifcAfQFTD2xf-y7B_Xy7S6dA,6007
147
- phoenix/server/api/routers/v1/experiments.py,sha256=oEPCoH_OKnIn04iBYYQcyx9N1LXnZGF0BEHwdO7XbOw,9760
148
- phoenix/server/api/routers/v1/spans.py,sha256=ZGZ67Q5pmKTr2cPqc2Lf5fONmbp-Nr_A-pxLswATk_M,8724
149
- phoenix/server/api/routers/v1/traces.py,sha256=Wm6bVm-MpubOxZwLwS9Xsn93RvDlSwlNYSprXnoIVQo,7921
150
- phoenix/server/api/routers/v1/utils.py,sha256=R2WxEpTyi4Z94K8tyt-a4dMYGh4jP0a_lbJ33FG_dKc,3045
141
+ phoenix/server/api/routers/v1/__init__.py,sha256=D1EFRWG4PcsTubeF3A3ENlNatCRq26AA52FxW11BGjM,3048
142
+ phoenix/server/api/routers/v1/dataset_examples.py,sha256=XfqOvDKF1oxb0pkeYfBycwwGt3LnSyyGdMLKC5VKoGQ,6690
143
+ phoenix/server/api/routers/v1/datasets.py,sha256=r0WcNxF8SKVa3-4rrTIg4Andwr4NmRmW1ybpKuxR9qw,33639
144
+ phoenix/server/api/routers/v1/evaluations.py,sha256=8g6P_e2BweV3RDU0esFmpkb0L5fCwonQPXiJ0y6HLwg,9126
145
+ phoenix/server/api/routers/v1/experiment_evaluations.py,sha256=TE1GMSOLN_96uAaJpnRpIH2u9x6_ebtkECgZRHvqt-w,5098
146
+ phoenix/server/api/routers/v1/experiment_runs.py,sha256=jy4SynmzdtQMoUzlowmG6wsVU14SsLAzfcW4JOhXjeQ,8154
147
+ phoenix/server/api/routers/v1/experiments.py,sha256=uVdmhyJgYI-UqOiRSJ-8OcVpL8a6Z02B5H2Rt_7yboY,11829
148
+ phoenix/server/api/routers/v1/spans.py,sha256=tryWFoJVFRLALzt6dfPmBBhKMS0s3hhlYdTathxVEU4,9638
149
+ phoenix/server/api/routers/v1/traces.py,sha256=PBIrpdJHVJ9gyiukCy1Ck1w0xts0VEHtRKaF7Noa248,8434
151
150
  phoenix/server/api/types/Annotation.py,sha256=7Ym7iuVcbwHlw2yIRylz4nATAF_Cm-Z17qcjiooj1cc,751
152
151
  phoenix/server/api/types/AnnotatorKind.py,sha256=rPgGdbN1Gvc109sGQ_ZH-gfJbp93V9wlarzTEJNtUwI,236
153
152
  phoenix/server/api/types/Cluster.py,sha256=ac4YfT1OH3xLVmex7EUmB6b9IpULnhLTt554LR0jglE,5689
@@ -191,7 +190,7 @@ phoenix/server/api/types/Retrieval.py,sha256=OhMK2ncjoyp5h1yjKhjlKpoTbQrMHuxmgSF
191
190
  phoenix/server/api/types/ScalarDriftMetricEnum.py,sha256=IUAcRPpgL41WdoIgK6cNk2Te38SspXGyEs-S1fY23_A,232
192
191
  phoenix/server/api/types/Segments.py,sha256=m2yoegrxA1Tn7ZAy1rMjjD1isc752MaAXMoffkBlvrM,2921
193
192
  phoenix/server/api/types/SortDir.py,sha256=OUpXhlCzCxPoXSDkJJygEs9Rw9pMymfaZUG5zPTrw4Y,152
194
- phoenix/server/api/types/Span.py,sha256=VjFC5VXe3Incf9AhEvctYhRpUixhF82oN2iepxjU50Q,14180
193
+ phoenix/server/api/types/Span.py,sha256=Qlz5G_gjyy_jpadfc7CD9xB6TekCCySeEqM_hihcrhM,14208
195
194
  phoenix/server/api/types/SpanAnnotation.py,sha256=6b5G-b_OoRvDL2ayWk7MkbqarLK-F-pQMx21CpUuNGY,1168
196
195
  phoenix/server/api/types/TimeSeries.py,sha256=wjzuxHFqCey0O7Ys25qiXyuqXK8an-osyNWUE8A_8G4,5227
197
196
  phoenix/server/api/types/Trace.py,sha256=ep-mPexub1ijxAnBvc2KrGsNVXO2SfDR1WxqER2wcD8,2376
@@ -203,6 +202,7 @@ phoenix/server/api/types/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZ
203
202
  phoenix/server/api/types/node.py,sha256=V0Xh9U4cGkz3iMg-vzEXtcs6cumU29JFPiU-JuGzjWI,848
204
203
  phoenix/server/api/types/pagination.py,sha256=PcaJ0s4exsTKgCZC4aFm1cgZNrGpHSdo6PbkWzPcweg,9077
205
204
  phoenix/server/openapi/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
205
+ phoenix/server/openapi/docs.py,sha256=fTb9q2oOSKC5bLVQy2Dsg3Bs0mGkCOKX1ypX7731sE0,7044
206
206
  phoenix/server/static/apple-touch-icon-114x114.png,sha256=xtFVXAYQnJkpUApg2D1hltSTuyO4Is4sD4A0ZkikiVU,9486
207
207
  phoenix/server/static/apple-touch-icon-120x120.png,sha256=iqZVAk634BbjJMozA8aHYyw15JjhIlIrG41FA2DFFaE,9957
208
208
  phoenix/server/static/apple-touch-icon-144x144.png,sha256=VgARtkHKoU8zikb3_G83h_cb02kpPcoJqO78yRh1AfU,10047
@@ -213,7 +213,7 @@ phoenix/server/static/apple-touch-icon-76x76.png,sha256=CT_xT12I0u2i0WU8JzBZBuOQ
213
213
  phoenix/server/static/apple-touch-icon.png,sha256=fOfpjqGpWYbJ0eAurKsyoZP1EAs6ZVooBJ_SGk2ZkDs,3801
214
214
  phoenix/server/static/favicon.ico,sha256=bY0vvCKRftemZfPShwZtE93DiiQdaYaozkPGwNFr6H8,34494
215
215
  phoenix/server/static/index.css,sha256=KKGpx4iwF91VGRm0YN-4cn8oC-oIqC6HecoPf0x3ZM8,1885
216
- phoenix/server/static/index.js,sha256=NKIEmhs3m-3omunxg9F8lHoYDMry5-DeRwONmRMQHzY,3529972
216
+ phoenix/server/static/index.js,sha256=zEiit1tVmnkPIG4f33wDlbC-G8mz0ubglGBiE2DE4D8,3536640
217
217
  phoenix/server/static/modernizr.js,sha256=mvK-XtkNqjOral-QvzoqsyOMECXIMu5BQwSVN_wcU9c,2564
218
218
  phoenix/server/templates/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
219
219
  phoenix/server/templates/index.html,sha256=S4z7qSoNSwnKFAH9r96AR-YJEyoKMd-VMWVlJ_IdzME,2039
@@ -223,16 +223,16 @@ phoenix/session/data_extractor.py,sha256=dwhiDu-ISaXr8UI9I-CszZhB5BlUNmdDopjFZvM
223
223
  phoenix/session/evaluation.py,sha256=aKeV8UVOyq3b7CYOwt3cWuLz0xzvMjX7vlEPILJ_fcs,5311
224
224
  phoenix/session/session.py,sha256=rjIuSSK2gAYIUPQTJc4E2ebew5o6I070FWRoFn4W3EI,26620
225
225
  phoenix/trace/__init__.py,sha256=ujk_uYjM8gmm-YqnyXxF-kekfwid0bcaPMTtNNcaw6U,407
226
- phoenix/trace/attributes.py,sha256=xSr2EvlkDS9Wiij7FywXzw7UmMAMLIARSEm_P686BKM,12434
226
+ phoenix/trace/attributes.py,sha256=B_OrzVaxZwFkrAFXZyicYoIti1UdUysURsvUS2GyW1U,12488
227
227
  phoenix/trace/errors.py,sha256=wB1z8qdPckngdfU-TORToekvg3344oNFAA83_hC2yFY,180
228
228
  phoenix/trace/evaluation_conventions.py,sha256=t8jydM3U0-T5YpiQKRJ3tWdWGlHtzKyttYdw-ddvPOk,1048
229
229
  phoenix/trace/exporter.py,sha256=eAYemdvDCHMugDJiaR29BFFMTQBdf3oerdkz34Cl3hE,4736
230
230
  phoenix/trace/fixtures.py,sha256=tDso17oAYMBQ8GJsAlHFzrC0otXPzUOEh4TgIjEfB7M,14260
231
231
  phoenix/trace/otel.py,sha256=WA720jvRadiZBAKjsYoPyXzypHwbyEK2OZRVUwtbjB8,9976
232
232
  phoenix/trace/projects.py,sha256=2BwlNjFE-uwpqYtCu5YyBiYZk9wRPpM13vh3-Cv7GkA,2157
233
- phoenix/trace/schemas.py,sha256=Mjc6fD9OyeMnEk5wPPSbveqnNUYWK3p3BxpOvSGanHU,5950
233
+ phoenix/trace/schemas.py,sha256=HpWSyzec0yDHEQXEDuwyLbhpvKrqkGps8BJqGiIFj8Y,5978
234
234
  phoenix/trace/span_evaluations.py,sha256=GaADtJLi2njra4aYaie0BIwkSgdxPB_SNseglI4ykZA,13104
235
- phoenix/trace/span_json_decoder.py,sha256=W6T1U0xndE2a-85O1QalJmStJK1zF1IoSU97h1RoWeY,3231
235
+ phoenix/trace/span_json_decoder.py,sha256=jkpYSmOUsSptvahOvetrPjVkPIuI4h6b87eizL8wHp8,3230
236
236
  phoenix/trace/span_json_encoder.py,sha256=tzSCIQJbeFBm33K68G8A5M12n_86tCDyuU0WAobxEz4,2010
237
237
  phoenix/trace/trace_dataset.py,sha256=Wq89jJ4hYQ1Qt-Uj11ZNzKQYQeKmGY6NqWStQiiTlMw,14351
238
238
  phoenix/trace/utils.py,sha256=7LurVGXn245cjj4MJsc7v6jq4DSJkpK6YGBfIaSywuw,1307
@@ -258,8 +258,8 @@ phoenix/utilities/logging.py,sha256=lDXd6EGaamBNcQxL4vP1au9-i_SXe0OraUDiJOcszSw,
258
258
  phoenix/utilities/project.py,sha256=qWsvKnG1oKhOFUowXf9qiOL2ia7jaFe_ijFFHEt8GJo,431
259
259
  phoenix/utilities/re.py,sha256=PDve_OLjRTM8yQQJHC8-n3HdIONi7aNils3ZKRZ5uBM,2045
260
260
  phoenix/utilities/span_store.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
261
- arize_phoenix-4.10.2rc1.dist-info/METADATA,sha256=kvMhdHvg67eriHuvnz3zfwCN-P9ISpjC_3LrYshITeY,11486
262
- arize_phoenix-4.10.2rc1.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
263
- arize_phoenix-4.10.2rc1.dist-info/licenses/IP_NOTICE,sha256=JBqyyCYYxGDfzQ0TtsQgjts41IJoa-hiwDrBjCb9gHM,469
264
- arize_phoenix-4.10.2rc1.dist-info/licenses/LICENSE,sha256=HFkW9REuMOkvKRACuwLPT0hRydHb3zNg-fdFt94td18,3794
265
- arize_phoenix-4.10.2rc1.dist-info/RECORD,,
261
+ arize_phoenix-4.11.0.dist-info/METADATA,sha256=0w3dc8vJIjxmwxzRI21vi5STtp5Gioffqy6k3EaqHAg,11452
262
+ arize_phoenix-4.11.0.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
263
+ arize_phoenix-4.11.0.dist-info/licenses/IP_NOTICE,sha256=JBqyyCYYxGDfzQ0TtsQgjts41IJoa-hiwDrBjCb9gHM,469
264
+ arize_phoenix-4.11.0.dist-info/licenses/LICENSE,sha256=HFkW9REuMOkvKRACuwLPT0hRydHb3zNg-fdFt94td18,3794
265
+ arize_phoenix-4.11.0.dist-info/RECORD,,
@@ -1,10 +1,12 @@
1
1
  from dataclasses import dataclass
2
2
  from datetime import datetime
3
3
  from pathlib import Path
4
- from typing import AsyncContextManager, Callable, Optional
4
+ from typing import AsyncContextManager, Callable, Optional, Union
5
5
 
6
6
  from sqlalchemy.ext.asyncio import AsyncSession
7
- from strawberry.fastapi import BaseContext
7
+ from starlette.requests import Request
8
+ from starlette.responses import Response
9
+ from starlette.websockets import WebSocket
8
10
  from typing_extensions import TypeAlias
9
11
 
10
12
  from phoenix.core.model_schema import Model
@@ -65,7 +67,9 @@ ProjectRowId: TypeAlias = int
65
67
 
66
68
 
67
69
  @dataclass
68
- class Context(BaseContext):
70
+ class Context:
71
+ request: Union[Request, WebSocket]
72
+ response: Optional[Response]
69
73
  db: Callable[[], AsyncContextManager[AsyncSession]]
70
74
  data_loaders: DataLoaders
71
75
  cache_for_dataloaders: Optional[CacheForDataLoaders]
@@ -1,22 +1,6 @@
1
- import json
2
- from argparse import ArgumentParser
3
- from typing import Optional, Tuple
4
-
5
1
  from .schema import get_openapi_schema
6
2
 
7
3
  if __name__ == "__main__":
8
- parser = ArgumentParser()
9
- parser.add_argument(
10
- "--compress",
11
- action="store_true",
12
- help="Whether to output a compressed version of the OpenAPI schema",
13
- )
14
- args = parser.parse_args()
4
+ import yaml # type: ignore
15
5
 
16
- indent: Optional[int] = None
17
- separator: Optional[Tuple[str, str]] = None
18
- if args.compress:
19
- separator = (",", ":")
20
- else:
21
- indent = 2
22
- print(json.dumps(get_openapi_schema(), indent=indent, separators=separator))
6
+ print(yaml.dump(get_openapi_schema(), indent=2))
@@ -1,16 +1,16 @@
1
- from typing import Any, Dict
1
+ from typing import Any
2
2
 
3
- from fastapi.openapi.utils import get_openapi
3
+ from starlette.schemas import SchemaGenerator
4
4
 
5
- from phoenix.server.api.routers.v1 import REST_API_VERSION
6
- from phoenix.server.api.routers.v1 import router as v1_router
5
+ from phoenix.server.api.routers.v1 import V1_ROUTES
7
6
 
7
+ OPENAPI_SCHEMA_GENERATOR = SchemaGenerator(
8
+ {"openapi": "3.0.0", "info": {"title": "Arize-Phoenix API", "version": "1.0"}}
9
+ )
8
10
 
9
- def get_openapi_schema() -> Dict[str, Any]:
10
- return get_openapi(
11
- title="Arize-Phoenix REST API",
12
- version=REST_API_VERSION,
13
- openapi_version="3.1.0",
14
- description="Schema for Arize-Phoenix REST API",
15
- routes=v1_router.routes,
16
- )
11
+
12
+ def get_openapi_schema() -> Any:
13
+ """
14
+ Exports an OpenAPI schema for the Phoenix REST API as a JSON object.
15
+ """
16
+ return OPENAPI_SCHEMA_GENERATOR.get_schema(V1_ROUTES) # type: ignore
@@ -1,42 +1,89 @@
1
- from fastapi import APIRouter, Depends, HTTPException, Request
2
- from starlette.status import HTTP_403_FORBIDDEN
1
+ from typing import Any, Awaitable, Callable, Mapping, Tuple
3
2
 
4
- from .datasets import router as datasets_router
5
- from .evaluations import router as evaluations_router
6
- from .experiment_evaluations import router as experiment_evaluations_router
7
- from .experiment_runs import router as experiment_runs_router
8
- from .experiments import router as experiments_router
9
- from .spans import router as spans_router
10
- from .traces import router as traces_router
11
- from .utils import add_errors_to_responses
3
+ import wrapt
4
+ from starlette import routing
5
+ from starlette.requests import Request
6
+ from starlette.responses import Response
7
+ from starlette.status import HTTP_403_FORBIDDEN
12
8
 
13
- REST_API_VERSION = "1.0"
9
+ from . import (
10
+ datasets,
11
+ evaluations,
12
+ experiment_evaluations,
13
+ experiment_runs,
14
+ experiments,
15
+ spans,
16
+ traces,
17
+ )
18
+ from .dataset_examples import list_dataset_examples
14
19
 
15
20
 
16
- async def prevent_access_in_read_only_mode(request: Request) -> None:
17
- """
18
- Prevents access to the REST API in read-only mode.
19
- """
21
+ @wrapt.decorator # type: ignore
22
+ async def forbid_if_readonly(
23
+ wrapped: Callable[[Request], Awaitable[Response]],
24
+ _: Any,
25
+ args: Tuple[Request],
26
+ kwargs: Mapping[str, Any],
27
+ ) -> Response:
28
+ request, *_ = args
20
29
  if request.app.state.read_only:
21
- raise HTTPException(
22
- detail="The Phoenix REST API is disabled in read-only mode.",
23
- status_code=HTTP_403_FORBIDDEN,
24
- )
25
-
26
-
27
- router = APIRouter(
28
- prefix="/v1",
29
- dependencies=[Depends(prevent_access_in_read_only_mode)],
30
- responses=add_errors_to_responses(
31
- [
32
- HTTP_403_FORBIDDEN # adds a 403 response to each route in the generated OpenAPI schema
33
- ]
30
+ return Response(status_code=HTTP_403_FORBIDDEN)
31
+ return await wrapped(*args, **kwargs)
32
+
33
+
34
+ class Route(routing.Route):
35
+ def __init__(self, path: str, endpoint: Callable[..., Any], **kwargs: Any) -> None:
36
+ super().__init__(path, forbid_if_readonly(endpoint), **kwargs)
37
+
38
+
39
+ V1_ROUTES = [
40
+ Route("/v1/evaluations", evaluations.post_evaluations, methods=["POST"]),
41
+ Route("/v1/evaluations", evaluations.get_evaluations, methods=["GET"]),
42
+ Route("/v1/traces", traces.post_traces, methods=["POST"]),
43
+ Route("/v1/trace_annotations", traces.annotate_traces, methods=["POST"]),
44
+ Route("/v1/spans", spans.query_spans_handler, methods=["POST"]),
45
+ Route("/v1/spans", spans.get_spans_handler, methods=["GET"]),
46
+ Route("/v1/span_annotations", spans.annotate_spans, methods=["POST"]),
47
+ Route("/v1/datasets/upload", datasets.post_datasets_upload, methods=["POST"]),
48
+ Route("/v1/datasets", datasets.list_datasets, methods=["GET"]),
49
+ Route("/v1/datasets/{id:str}", datasets.delete_dataset_by_id, methods=["DELETE"]),
50
+ Route("/v1/datasets/{id:str}", datasets.get_dataset_by_id, methods=["GET"]),
51
+ Route("/v1/datasets/{id:str}/csv", datasets.get_dataset_csv, methods=["GET"]),
52
+ Route(
53
+ "/v1/datasets/{id:str}/jsonl/openai_ft",
54
+ datasets.get_dataset_jsonl_openai_ft,
55
+ methods=["GET"],
34
56
  ),
35
- )
36
- router.include_router(datasets_router)
37
- router.include_router(experiments_router)
38
- router.include_router(experiment_runs_router)
39
- router.include_router(experiment_evaluations_router)
40
- router.include_router(traces_router)
41
- router.include_router(spans_router)
42
- router.include_router(evaluations_router)
57
+ Route(
58
+ "/v1/datasets/{id:str}/jsonl/openai_evals",
59
+ datasets.get_dataset_jsonl_openai_evals,
60
+ methods=["GET"],
61
+ ),
62
+ Route("/v1/datasets/{id:str}/examples", list_dataset_examples, methods=["GET"]),
63
+ Route("/v1/datasets/{id:str}/versions", datasets.get_dataset_versions, methods=["GET"]),
64
+ Route(
65
+ "/v1/datasets/{dataset_id:str}/experiments",
66
+ experiments.create_experiment,
67
+ methods=["POST"],
68
+ ),
69
+ Route(
70
+ "/v1/experiments/{experiment_id:str}",
71
+ experiments.read_experiment,
72
+ methods=["GET"],
73
+ ),
74
+ Route(
75
+ "/v1/experiments/{experiment_id:str}/runs",
76
+ experiment_runs.create_experiment_run,
77
+ methods=["POST"],
78
+ ),
79
+ Route(
80
+ "/v1/experiments/{experiment_id:str}/runs",
81
+ experiment_runs.list_experiment_runs,
82
+ methods=["GET"],
83
+ ),
84
+ Route(
85
+ "/v1/experiment_evaluations",
86
+ experiment_evaluations.upsert_experiment_evaluation,
87
+ methods=["POST"],
88
+ ),
89
+ ]