arize-phoenix 11.14.0__py3-none-any.whl → 11.16.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.4
2
2
  Name: arize-phoenix
3
- Version: 11.14.0
3
+ Version: 11.16.0
4
4
  Summary: AI Observability and Evaluation
5
5
  Project-URL: Documentation, https://arize.com/docs/phoenix/
6
6
  Project-URL: Issues, https://github.com/Arize-ai/phoenix/issues
@@ -1,12 +1,12 @@
1
1
  phoenix/__init__.py,sha256=xkpXH76HFbEDCq8IhiFp-2GnEHx39xPMdOpV5Skew1w,5481
2
2
  phoenix/auth.py,sha256=yW78f1xWNjTE30ACGUM14nOd5BzkukhlzA9B45kSUkM,11053
3
- phoenix/config.py,sha256=NqSYbx1-Fdr0SSOt5RSQ5jmTz3r3xvGElVXvd9kK1gc,61495
3
+ phoenix/config.py,sha256=VWYsWA9yzL0ml_1dQ9Q-vnEZxBri1TO8zJocBBUVeZc,61985
4
4
  phoenix/datetime_utils.py,sha256=pRD-nzxXYKlMWNtd3r2tKGKfPFhwuJhfOAtlGLVAO60,8784
5
5
  phoenix/exceptions.py,sha256=n2L2KKuecrdflB9MsCdAYCiSEvGJptIsfRkXMoJle7A,169
6
6
  phoenix/py.typed,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
7
7
  phoenix/services.py,sha256=ngkyKGVatX3cO2WJdo2hKdaVKP-xJCMvqthvga6kJss,5196
8
8
  phoenix/settings.py,sha256=2kHfT3BNOVd4dAO1bq-syEQbHSG8oX2-7NhOwK2QREk,896
9
- phoenix/version.py,sha256=gGg2eO2k7EvDDGm04_TDhi2iMqo5QC7vEO36A1qcspc,24
9
+ phoenix/version.py,sha256=1jPwVRFknFjr1Z2-4KMQGv_ONw2Eybch5xZM1zNP1rg,24
10
10
  phoenix/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
11
  phoenix/core/embedding_dimension.py,sha256=zKGbcvwOXgLf-yrJBpQyKtd-LEOPRKHnUToyAU8Owis,87
12
12
  phoenix/core/model.py,sha256=qBFraOtmwCCnWJltKNP18DDG0mULXigytlFsa6YOz6k,4837
@@ -22,7 +22,7 @@ phoenix/db/enums.py,sha256=w3O5YuJEEzVTwVDZb8b2UUFhU8yK_GosF081VVrrno0,188
22
22
  phoenix/db/facilitator.py,sha256=aRbkIJkIDP2zMsLKbO7Y8jJq4U2HbV7Lf6GYVWXVImU,20151
23
23
  phoenix/db/helpers.py,sha256=dsGONSgkhmVtjMpJh-84KRVTf5uPdQ5c8O2AhUgHkRg,14150
24
24
  phoenix/db/migrate.py,sha256=oUrXH8yEbcpL4eh09aSCuUiSrhFli0eT5D_j4ZmYChY,2797
25
- phoenix/db/models.py,sha256=0avhbUmDEBZ1_NgBSr9Ck9BYxXtJTraPfQqDGZFE2-Y,60388
25
+ phoenix/db/models.py,sha256=bxyBRSST8rqBKcAyPyyDHmkv9AadaE3XmQnpcaMvvnk,61588
26
26
  phoenix/db/pg_config.py,sha256=h6mB7qF7t4Zk6VGvAiyefHGVu74o-yJynaWzeE39k9Y,6001
27
27
  phoenix/db/insertion/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
28
28
  phoenix/db/insertion/constants.py,sha256=8wifm7X-1XvroZ__R2Gc96NsgLhTDn0zXl4lehlXtcA,70
@@ -58,15 +58,15 @@ phoenix/db/types/model_provider.py,sha256=zKYGcEQqbAxtPwnq5dL0fYPgDC8nrh_ABLBMR9
58
58
  phoenix/db/types/token_price_customization.py,sha256=LAb8IwyFJGDCje7CvcPcxNp4NOU8si5hSYaf1fyi624,857
59
59
  phoenix/db/types/trace_retention.py,sha256=fyqAQCvDiD7mpJ_WUqbPyQvuSdERof4DpKpHLJsdROk,9897
60
60
  phoenix/experiments/__init__.py,sha256=6JGwgUd7xCbGpuHqYZlsmErmYvVgv7N_j43bn3dUqsk,123
61
- phoenix/experiments/functions.py,sha256=iUBk6sLFkK2wHeN-cxax8tku2tFmU_pHRsjNYO0PhIk,39967
61
+ phoenix/experiments/functions.py,sha256=J9Bfp7ptDB2g6DpSqgf2iw4cDL09P_h4UWAAtJNS9Mg,39971
62
62
  phoenix/experiments/tracing.py,sha256=X-wlgbWEzP1oHkLmjop3fGjONo6JK5a0kPXc9YYD014,2856
63
- phoenix/experiments/types.py,sha256=yntt6fnAny1U4Q9Y5Mm4ZYIb9319OaJovl-kyXFtGQE,23475
63
+ phoenix/experiments/types.py,sha256=O4vvm9WOp0fevTDobStXEJpFKn3acveXgsRClxlnzCM,23477
64
64
  phoenix/experiments/utils.py,sha256=MZ1-OnTcavk_KUtbfGqt55Fk9TGtJpYG_K71WsN-zDk,785
65
65
  phoenix/experiments/evaluators/__init__.py,sha256=CPWW1EiufLqc0JWghE4wVAPG_z6Wt4mD_-yf_4IckB4,772
66
66
  phoenix/experiments/evaluators/base.py,sha256=zefFLqyYLMxJnZxDs1S0QCrnb43YJraoadCMqRMU72A,5576
67
67
  phoenix/experiments/evaluators/code_evaluators.py,sha256=JIu_8GezA3UKA7isUmZvBxjcJeXllIDESEgdF2zeDck,6755
68
68
  phoenix/experiments/evaluators/llm_evaluators.py,sha256=1HsZQsKNWA_19EHrjI6OXqm1aBwvIKS-qHYc3R0bOqc,20551
69
- phoenix/experiments/evaluators/utils.py,sha256=W-k2bHL67ST-B7ne8t5LvCFHGBaKCPHbOv3x1SlDENU,9330
69
+ phoenix/experiments/evaluators/utils.py,sha256=2YoVyrexiaJSltHKk_ETTsxDB20TUrsNGkz-9EM3vMY,9332
70
70
  phoenix/inferences/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
71
71
  phoenix/inferences/errors.py,sha256=AOsCs-xR1LV469Gygje16EOK3qGheiPGW0Ylg-MakhQ,8282
72
72
  phoenix/inferences/fixtures.py,sha256=fessNJmbx1AUJLdwvf7UhXwzGMRfn7ZkDWK8YNWJSi8,20871
@@ -91,11 +91,11 @@ phoenix/pointcloud/pointcloud.py,sha256=SN_1wXZcwKrtSnHGZLDZGx71orqE1WyVF7E-D58d
91
91
  phoenix/pointcloud/projectors.py,sha256=TQgwc9cJDjJkin1WZyZzgl3HsYrLLiyWD7Czy4jNW3U,1088
92
92
  phoenix/pointcloud/umap_parameters.py,sha256=db_WEPoamuWtopZx7tQfAXPnoE0MS8FkAV0_ThjEx_Q,1735
93
93
  phoenix/server/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
94
- phoenix/server/app.py,sha256=Ja937LsaTx_u1EUR76BM_tpYSBpyWkv27tmBsDZlwKg,47708
94
+ phoenix/server/app.py,sha256=00un2qg4eUmHr37TtZlccmPgRnI1D5FB5r2zwIfI9W4,48047
95
95
  phoenix/server/authorization.py,sha256=OxROn7ibpKtCTrcgDkzWuNxVaQcSQ8MAx7zbjZiliK0,3201
96
96
  phoenix/server/bearer_auth.py,sha256=f4v4W94KyTdGGCPsK1tXOe0vouPuvanAEa03XSdCvPE,6650
97
97
  phoenix/server/dml_event.py,sha256=8UciN7W8X_IqQfAnAeAh68BezNmfxSxuTeD6IUerTW8,2911
98
- phoenix/server/dml_event_handler.py,sha256=gkDIONyTz9sLbSA6qOZCigiO5val-fvVcLzDrWNcVcg,8306
98
+ phoenix/server/dml_event_handler.py,sha256=71_iPcHiJ4E-8Z7sGL2j0vx_RpkmcMVEUFIBsWrdp-E,8483
99
99
  phoenix/server/grpc_server.py,sha256=ahHC394gFZYM3h4FmjQxZwL-a4x3mWmV2EdXYFlNEC8,4676
100
100
  phoenix/server/jwt_store.py,sha256=B6uVildN_dQDTG_-aHHvuVSI7wIVK1yvED-_y6se2GU,16905
101
101
  phoenix/server/main.py,sha256=UBwxrQIEE7ci-SbE6GAlRYmbMHooI6JYG6sG-UpBFFs,18905
@@ -243,7 +243,7 @@ phoenix/server/api/mutations/prompt_label_mutations.py,sha256=uCiVcULtmgaNaav4M0
243
243
  phoenix/server/api/mutations/prompt_mutations.py,sha256=Yg-6L2PiKUZfFyNarptu3OdE0uA2_Nyl3VrLVP8FJ9Y,12114
244
244
  phoenix/server/api/mutations/prompt_version_tag_mutations.py,sha256=t77osYb5he2Am4UeNis7pzY9MnaA9PNEQhsQelRH8k8,5767
245
245
  phoenix/server/api/mutations/span_annotations_mutations.py,sha256=LQPcODp7-ZobXspjmtLaamyQa8UkTONC_va-ST9r-k8,15015
246
- phoenix/server/api/mutations/trace_annotations_mutations.py,sha256=PLNNzSlk3fyJHkAVaMGR8pbWB63nOos-cStUWbTi7f8,11995
246
+ phoenix/server/api/mutations/trace_annotations_mutations.py,sha256=zWoMfOMSQZqw7gZl7Le2PRojkDcG_KOiP1iIuqZpZ8Q,11971
247
247
  phoenix/server/api/mutations/trace_mutations.py,sha256=AvtQAfqNWBQpJOZm4e0DZFimhVJ6HQHtSSZtezRadCo,4698
248
248
  phoenix/server/api/mutations/user_mutations.py,sha256=9vFWfvfhb6RUdxL8xajV2-P2kVDtFRijRD58OFeBY4M,15373
249
249
  phoenix/server/api/openapi/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -257,16 +257,16 @@ phoenix/server/api/routers/utils.py,sha256=M41BoH-fl37izhRuN2aX7lWm7jOC20A_3uClv
257
257
  phoenix/server/api/routers/v1/__init__.py,sha256=ngLMPjC7lgZxgKy_Is33KxTRnMzSqy25qTTChCVx_Mo,2696
258
258
  phoenix/server/api/routers/v1/annotation_configs.py,sha256=xp5lJmKYlRsINCUrRD9-lTAElw2v4hdFndS5BWrxICA,16048
259
259
  phoenix/server/api/routers/v1/annotations.py,sha256=fVl2qeh_ZbWXGvFBTZgeL7aGkkINIScdjuyxnOoSzNM,6817
260
- phoenix/server/api/routers/v1/datasets.py,sha256=WntQxxOYbuWR4c3ikm5Hq7q1JYGgHRplSGDvjsgJnqc,38343
261
- phoenix/server/api/routers/v1/evaluations.py,sha256=ni_OJcroE93ZmKoU8I8LYqEgCngG6TyHXpFlcYzoabQ,12937
260
+ phoenix/server/api/routers/v1/datasets.py,sha256=9iPORLmbOrPKgUUcRDMs6ZczSIz7hvc6bngJy3IbdR0,38331
261
+ phoenix/server/api/routers/v1/evaluations.py,sha256=_I0X01J8EZmTlfAGkvMkZ05IB3x691xzUmHV05ov26Y,12914
262
262
  phoenix/server/api/routers/v1/experiment_evaluations.py,sha256=_xnVqFCwZoOUPravdPixZLSQiU1H3sB5EzMknB7E1CI,4837
263
263
  phoenix/server/api/routers/v1/experiment_runs.py,sha256=LZeCQWQIEOZ9jK5Gp_C4JbiYY6AmnnWe85cVcvdkCLE,7107
264
264
  phoenix/server/api/routers/v1/experiments.py,sha256=osy0JG_iVSCkoRi__0tjldfS5zzBDvNfv-GimbP4ShA,20537
265
265
  phoenix/server/api/routers/v1/models.py,sha256=p3gJN-9SWiUYTUTft4bZMsZVCBNTb4nN1Foy68eRZzQ,1997
266
266
  phoenix/server/api/routers/v1/projects.py,sha256=32GwTLsaFgQLVNdjrlrGe90XT3pIX1N7-zX9D9_J_4w,12701
267
267
  phoenix/server/api/routers/v1/prompts.py,sha256=chRYcLkOYDJdJfVZVukVTUyIRnLPvsJCg41CuPxOIU8,26695
268
- phoenix/server/api/routers/v1/spans.py,sha256=oFoDT2XLB4chsiFQIa0fAsY2rQOa4ApioH232_utJLo,44226
269
- phoenix/server/api/routers/v1/traces.py,sha256=63T-WYiwh8X3Sp6u_OFfA9zLLKk6cNsnciiDyUzKLVk,8561
268
+ phoenix/server/api/routers/v1/spans.py,sha256=ETH6I14O_zY9IW69Fo-LxL796BR3xgt8qdzwqzYAvbE,44208
269
+ phoenix/server/api/routers/v1/traces.py,sha256=uLASCHMgU13tUhuWXnXqaom1crrQVpXi9PUtsyDXU9Y,10318
270
270
  phoenix/server/api/routers/v1/users.py,sha256=hUZCe7ctJqEkSJBe046a0OAFMLZodtyO7NLP7U6S8Pg,11986
271
271
  phoenix/server/api/routers/v1/utils.py,sha256=oXIOGPzPTkE0ZWUTRCoRIQQ7wTzoSwtWFaUSjlGBqts,4960
272
272
  phoenix/server/api/types/Annotation.py,sha256=gsl8CwjIbDUbZRj4d9USwZ_w_Tkz4i7zuZh9ftV80jA,1132
@@ -321,7 +321,7 @@ phoenix/server/api/types/ModelInterface.py,sha256=Qe7H23wDb_Q2-HmeY2t0R5Jsn4aAfY
321
321
  phoenix/server/api/types/NumericRange.py,sha256=afEjgF97Go_OvmjMggbPBt-zGM8IONewAyEiKEHRds0,192
322
322
  phoenix/server/api/types/PerformanceMetric.py,sha256=KFkmJDqP43eDUtARQOUqR7NYcxvL6Vh2uisHWU6H3ko,387
323
323
  phoenix/server/api/types/PlaygroundModel.py,sha256=IqJFxsAAJMRyaFI9ryI3GQrpFOJ5Llf6kIutEO-tFvM,321
324
- phoenix/server/api/types/Project.py,sha256=u_Rlk61xrv5ZoJdOl5ghG1Wo7TK1eqydDZ7GeNPDgLM,69630
324
+ phoenix/server/api/types/Project.py,sha256=AxKlA7FHlI48uRKx5-MRzMzEyyWPZPffX_iZOV0jeJs,69652
325
325
  phoenix/server/api/types/ProjectSession.py,sha256=uwqTsDTfSGz13AvP-cwS_mJR5JZ1lHqu10ungbl7g5s,6245
326
326
  phoenix/server/api/types/ProjectTraceRetentionPolicy.py,sha256=tYy2kgalPDyuaYZr0VUHjH0YpXaiF_QOzg5yfaV_c7c,3782
327
327
  phoenix/server/api/types/Prompt.py,sha256=ccP4eq1e38xbF0afclGWLOuDpBVpNbJ3AOSRClF8yFQ,4955
@@ -336,7 +336,7 @@ phoenix/server/api/types/ScalarDriftMetricEnum.py,sha256=IUAcRPpgL41WdoIgK6cNk2T
336
336
  phoenix/server/api/types/Segments.py,sha256=vT2v0efoa5cuBKxLtxTnsUP5YJJCZfTloM71Spu0tMI,2915
337
337
  phoenix/server/api/types/ServerStatus.py,sha256=t92OHuVhK9DXDk2vsBuHceQNKqYGpHwUp8DNGKz2wOk,88
338
338
  phoenix/server/api/types/SortDir.py,sha256=OUpXhlCzCxPoXSDkJJygEs9Rw9pMymfaZUG5zPTrw4Y,152
339
- phoenix/server/api/types/Span.py,sha256=0o1lyceeZhEeBLBdd8gYo324nQ1P6eTPOi3aKdZZUd4,32015
339
+ phoenix/server/api/types/Span.py,sha256=6vurLa8yoBs7GH7Jpj5niPAX7JxKPKVUp2qEJbaZxCI,32000
340
340
  phoenix/server/api/types/SpanAnnotation.py,sha256=uPWu7Z8rmpfKhaaxbged4_o00pPCR3nkn7Gji9vB8jY,1959
341
341
  phoenix/server/api/types/SpanCostDetailSummaryEntry.py,sha256=RXAdOC6MFyR9mwaoj8lMMdI3_9r3z6mR2izJvlsj12U,252
342
342
  phoenix/server/api/types/SpanCostSummary.py,sha256=wo03FCMcFzB5m4P5kvA5jzi9ACLbht38ozQbDJUh94g,357
@@ -366,7 +366,7 @@ phoenix/server/cost_tracking/model_cost_manifest.json,sha256=XKOgaRE9bq109Mnopfy
366
366
  phoenix/server/cost_tracking/regex_specificity.py,sha256=9kqWuQ68C-hlwW25hr7BhFlRt5y2Nnpy0Ax3n9UN6Xk,11622
367
367
  phoenix/server/cost_tracking/token_cost_calculator.py,sha256=2JEZnvusx2-xbhp8krp9EarjWuyGH2KO4e-ZwJX-K0s,1598
368
368
  phoenix/server/daemons/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
369
- phoenix/server/daemons/db_disk_usage_monitor.py,sha256=_MckKf9GbQ3Is4WZ3RmwJmvVElkF9Ipss3yNHjF8R3c,8016
369
+ phoenix/server/daemons/db_disk_usage_monitor.py,sha256=2WBkrL1QyRGbLtskXEdxwAdnWLjtdQ-mix95AkLQSbg,7997
370
370
  phoenix/server/daemons/generative_model_store.py,sha256=CkMG0jFWtxcUNP_7iFTgzHPyl5IgnXUwwJb7584pmkI,1566
371
371
  phoenix/server/daemons/span_cost_calculator.py,sha256=M7bG8fas99xz37bZUkBXnG37U2otUcu1-FI5RmrtPgU,3052
372
372
  phoenix/server/email/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -401,9 +401,9 @@ phoenix/server/static/assets/vendor-recharts-Cu431IpB.js,sha256=-RxCpZURhh5aUEh1
401
401
  phoenix/server/static/assets/vendor-shiki-Ce9e01lU.js,sha256=FPFdF-MxIINIy5ujia044AyVID8jqcjjMvuYnbBZI6w,8980312
402
402
  phoenix/server/static/assets/vendor-three-C5WAXd5r.js,sha256=ELkg06u70N7h8oFmvqdoHyPuUf9VgGEWeT4LKFx4VWo,620975
403
403
  phoenix/server/templates/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
404
- phoenix/server/templates/index.html,sha256=ld4wU6Agx8Cr5Bi3fvNNX6bO0mKo_Kvqd9dQn4I_HfI,6973
404
+ phoenix/server/templates/index.html,sha256=0sqTnrrfw-BxrXaj2PayCgOUu-MseC6eUGBJwZx7KO8,7116
405
405
  phoenix/session/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
406
- phoenix/session/client.py,sha256=uw5WlCuFcN_eEj7Ko2bhJVcaihEIp7Evy50KnL6Sq-k,35602
406
+ phoenix/session/client.py,sha256=Bl0Ov1tPrKX2-wBr7Kr49hQHgdBtyVfdhlMKcd5tURM,35583
407
407
  phoenix/session/data_extractor.py,sha256=Y0RzYFaNy9fQj8PEIeQ76TBZ90_E1FW7bXu3K5x0EZY,2782
408
408
  phoenix/session/evaluation.py,sha256=tMElekWeLKOPHdLm1Pu_sXYWYaSU5rHAc7y8qi3jYhE,5359
409
409
  phoenix/session/session.py,sha256=PKNeRxo7M1AZRKv4ZdGUS5rXRrQu5XSGV0vtCOfHLRk,27621
@@ -425,7 +425,7 @@ phoenix/trace/dsl/README.md,sha256=ihmP9zGUC5V-TDbzKla76LuyDqPDQIBUH2BORwxNI68,2
425
425
  phoenix/trace/dsl/__init__.py,sha256=WIQIjJg362XD3s50OsPJJ0xbDsGp41bSv7vDllLrPuA,144
426
426
  phoenix/trace/dsl/filter.py,sha256=FYOzH1gkwlKBYepscZzwHeeXnJdTadC_m4v0cYRs00Y,31557
427
427
  phoenix/trace/dsl/helpers.py,sha256=Hc0HRqvYWl71waee0vKLNwmszc2Q1ba4Q8svXxeEqJI,7708
428
- phoenix/trace/dsl/query.py,sha256=I7iDsJk1cwxYh0EUFXLu2DDqPU5WYxVa_ntVOe5v8s0,36350
428
+ phoenix/trace/dsl/query.py,sha256=pJdws0gkFoMoJKxvcrbgd0FDshA6BaDplqs8DmnIQJM,36350
429
429
  phoenix/trace/v1/__init__.py,sha256=-IbAD0ruESMjvQLvGAg9CTfjBUATFDx1OXseDPis6-0,88
430
430
  phoenix/trace/v1/evaluation_pb2.py,sha256=8sXvv2BW_vqD30MOMbmkeE2zpmm7ncik21kl3e-HzeQ,2254
431
431
  phoenix/trace/v1/evaluation_pb2.pyi,sha256=cCbbx06gwQmaH14s3J1X25TtaARh-k1abbxQdQCXGm8,4500
@@ -439,9 +439,9 @@ phoenix/utilities/project.py,sha256=auVpARXkDb-JgeX5f2aStyFIkeKvGwN9l7qrFeJMVxI,
439
439
  phoenix/utilities/re.py,sha256=6YyUWIkv0zc2SigsxfOWIHzdpjKA_TZo2iqKq7zJKvw,2081
440
440
  phoenix/utilities/span_store.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
441
441
  phoenix/utilities/template_formatters.py,sha256=gh9PJD6WEGw7TEYXfSst1UR4pWWwmjxMLrDVQ_CkpkQ,2779
442
- arize_phoenix-11.14.0.dist-info/METADATA,sha256=fRHnS-i2U-gc5C6W0G3mM_DFJ-NuIjIAuSvrB714TRk,30851
443
- arize_phoenix-11.14.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
444
- arize_phoenix-11.14.0.dist-info/entry_points.txt,sha256=Pgpn8Upxx9P8z8joPXZWl2LlnAlGc3gcQoVchb06X1Q,94
445
- arize_phoenix-11.14.0.dist-info/licenses/IP_NOTICE,sha256=JBqyyCYYxGDfzQ0TtsQgjts41IJoa-hiwDrBjCb9gHM,469
446
- arize_phoenix-11.14.0.dist-info/licenses/LICENSE,sha256=HFkW9REuMOkvKRACuwLPT0hRydHb3zNg-fdFt94td18,3794
447
- arize_phoenix-11.14.0.dist-info/RECORD,,
442
+ arize_phoenix-11.16.0.dist-info/METADATA,sha256=Vhoaw8m0XPZKoPzmUJxOrEfcQ-UZhTdIGXceg5fEiuU,30851
443
+ arize_phoenix-11.16.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
444
+ arize_phoenix-11.16.0.dist-info/entry_points.txt,sha256=Pgpn8Upxx9P8z8joPXZWl2LlnAlGc3gcQoVchb06X1Q,94
445
+ arize_phoenix-11.16.0.dist-info/licenses/IP_NOTICE,sha256=JBqyyCYYxGDfzQ0TtsQgjts41IJoa-hiwDrBjCb9gHM,469
446
+ arize_phoenix-11.16.0.dist-info/licenses/LICENSE,sha256=HFkW9REuMOkvKRACuwLPT0hRydHb3zNg-fdFt94td18,3794
447
+ arize_phoenix-11.16.0.dist-info/RECORD,,
phoenix/config.py CHANGED
@@ -57,6 +57,11 @@ ENV_PHOENIX_FULLSTORY_ORG = "PHOENIX_FULLSTORY_ORG"
57
57
  The FullStory organization ID for web analytics tracking. When set, FullStory tracking
58
58
  will be enabled in the Phoenix web interface.
59
59
  """
60
+ ENV_PHOENIX_ALLOW_EXTERNAL_RESOURCES = "PHOENIX_ALLOW_EXTERNAL_RESOURCES"
61
+ """
62
+ Allows calls to external resources, like Google Fonts in the web interface
63
+ Defaults to True. Set to False in air-gapped environments to prevent external requests.
64
+ """
60
65
  ENV_PHOENIX_SQL_DATABASE_URL = "PHOENIX_SQL_DATABASE_URL"
61
66
  """
62
67
  The SQL database URL to use when logging traces and evals.
@@ -1690,3 +1695,11 @@ def _validate_file_exists_and_is_readable(
1690
1695
  f.read(1) # Read just one byte to verify readability
1691
1696
  except Exception as e:
1692
1697
  raise ValueError(f"{description} file is not readable: {e}")
1698
+
1699
+
1700
+ def get_env_allow_external_resources() -> bool:
1701
+ """
1702
+ Gets the value of the PHOENIX_ALLOW_EXTERNAL_RESOURCES environment variable.
1703
+ Defaults to True if not set.
1704
+ """
1705
+ return _bool_val(ENV_PHOENIX_ALLOW_EXTERNAL_RESOURCES, True)
phoenix/db/models.py CHANGED
@@ -841,6 +841,41 @@ def _(element: Any, compiler: Any, **kw: Any) -> Any:
841
841
  return compiler.process(func.text_contains(string, substring) > 0, **kw)
842
842
 
843
843
 
844
+ class CaseInsensitiveContains(expression.FunctionElement[bool]):
845
+ # See https://docs.sqlalchemy.org/en/20/core/compiler.html
846
+ inherit_cache = True
847
+ type = Boolean()
848
+ name = "case_insensitive_contains"
849
+
850
+
851
+ @compiles(CaseInsensitiveContains)
852
+ def _(element: Any, compiler: Any, **kw: Any) -> Any:
853
+ string, substring = list(element.clauses)
854
+ result = compiler.process(func.lower(string).contains(func.lower(substring)), **kw)
855
+ return result
856
+
857
+
858
+ @compiles(CaseInsensitiveContains, "postgresql")
859
+ def _(element: Any, compiler: Any, **kw: Any) -> Any:
860
+ string, substring = list(element.clauses)
861
+ escaped = func.replace(
862
+ func.replace(func.replace(substring, "\\", "\\\\"), "%", "\\%"), "_", "\\_"
863
+ )
864
+ pattern = func.concat("%", escaped, "%")
865
+ result = compiler.process(string.ilike(pattern), **kw)
866
+ return result
867
+
868
+
869
+ @compiles(CaseInsensitiveContains, "sqlite")
870
+ def _(element: Any, compiler: Any, **kw: Any) -> Any:
871
+ # Use sqlean's `text_lower` to handle non-ASCII characters
872
+ string, substring = list(element.clauses)
873
+ result = compiler.process(
874
+ func.text_contains(func.text_lower(string), func.text_lower(substring)), **kw
875
+ )
876
+ return result
877
+
878
+
844
879
  async def init_models(engine: AsyncEngine) -> None:
845
880
  async with engine.begin() as conn:
846
881
  await conn.run_sync(Base.metadata.create_all)
@@ -19,9 +19,9 @@ def unwrap_json(obj: JSONSerializable) -> JSONSerializable:
19
19
  if len(obj) == 1:
20
20
  key = next(iter(obj.keys()))
21
21
  output = obj[key]
22
- assert isinstance(
23
- output, (dict, list, str, int, float, bool, type(None))
24
- ), "Output must be JSON serializable"
22
+ assert isinstance(output, (dict, list, str, int, float, bool, type(None))), (
23
+ "Output must be JSON serializable"
24
+ )
25
25
  return output
26
26
  return obj
27
27
 
@@ -363,9 +363,9 @@ def run_experiment(
363
363
  span.set_attribute(SpanAttributes.OPENINFERENCE_SPAN_KIND, root_span_kind)
364
364
  span.set_status(status)
365
365
 
366
- assert isinstance(
367
- output, (dict, list, str, int, float, bool, type(None))
368
- ), "Output must be JSON serializable"
366
+ assert isinstance(output, (dict, list, str, int, float, bool, type(None))), (
367
+ "Output must be JSON serializable"
368
+ )
369
369
 
370
370
  exp_run = ExperimentRun(
371
371
  start_time=_decode_unix_nano(cast(int, span.start_time)),
@@ -477,9 +477,9 @@ def run_experiment(
477
477
  span.set_attribute(OPENINFERENCE_SPAN_KIND, root_span_kind)
478
478
  span.set_status(status)
479
479
 
480
- assert isinstance(
481
- output, (dict, list, str, int, float, bool, type(None))
482
- ), "Output must be JSON serializable"
480
+ assert isinstance(output, (dict, list, str, int, float, bool, type(None))), (
481
+ "Output must be JSON serializable"
482
+ )
483
483
 
484
484
  exp_run = ExperimentRun(
485
485
  start_time=_decode_unix_nano(cast(int, span.start_time)),
@@ -322,7 +322,7 @@ class _HasStats:
322
322
  text = self.stats.__str__()
323
323
  else:
324
324
  text = self.stats.to_markdown(index=False)
325
- return f"{self.title}\n{'-'*len(self.title)}\n" + text
325
+ return f"{self.title}\n{'-' * len(self.title)}\n" + text
326
326
 
327
327
 
328
328
  @dataclass(frozen=True)
@@ -49,8 +49,7 @@ class TraceAnnotationMutationMixin:
49
49
  trace_rowid = from_global_id_with_expected_type(annotation_input.trace_id, "Trace")
50
50
  except ValueError:
51
51
  raise BadRequest(
52
- f"Invalid trace ID for annotation at index {idx}: "
53
- f"{annotation_input.trace_id}"
52
+ f"Invalid trace ID for annotation at index {idx}: {annotation_input.trace_id}"
54
53
  )
55
54
  trace_rowids.append(trace_rowid)
56
55
 
@@ -714,7 +714,7 @@ async def get_dataset_examples(
714
714
  version_id: Optional[str] = Query(
715
715
  default=None,
716
716
  description=(
717
- "The ID of the dataset version " "(if omitted, returns data from the latest version)"
717
+ "The ID of the dataset version (if omitted, returns data from the latest version)"
718
718
  ),
719
719
  ),
720
720
  ) -> ListDatasetExamplesResponseBody:
@@ -833,7 +833,7 @@ async def get_dataset_csv(
833
833
  version_id: Optional[str] = Query(
834
834
  default=None,
835
835
  description=(
836
- "The ID of the dataset version " "(if omitted, returns data from the latest version)"
836
+ "The ID of the dataset version (if omitted, returns data from the latest version)"
837
837
  ),
838
838
  ),
839
839
  ) -> Response:
@@ -876,7 +876,7 @@ async def get_dataset_jsonl_openai_ft(
876
876
  version_id: Optional[str] = Query(
877
877
  default=None,
878
878
  description=(
879
- "The ID of the dataset version " "(if omitted, returns data from the latest version)"
879
+ "The ID of the dataset version (if omitted, returns data from the latest version)"
880
880
  ),
881
881
  ),
882
882
  ) -> bytes:
@@ -916,7 +916,7 @@ async def get_dataset_jsonl_openai_evals(
916
916
  version_id: Optional[str] = Query(
917
917
  default=None,
918
918
  description=(
919
- "The ID of the dataset version " "(if omitted, returns data from the latest version)"
919
+ "The ID of the dataset version (if omitted, returns data from the latest version)"
920
920
  ),
921
921
  ),
922
922
  ) -> bytes:
@@ -55,8 +55,7 @@ router = APIRouter(tags=["traces"], include_in_schema=True)
55
55
  {
56
56
  "status_code": HTTP_415_UNSUPPORTED_MEDIA_TYPE,
57
57
  "description": (
58
- "Unsupported content type, "
59
- "only gzipped protobuf and pandas-arrow are supported"
58
+ "Unsupported content type, only gzipped protobuf and pandas-arrow are supported"
60
59
  ),
61
60
  },
62
61
  HTTP_422_UNPROCESSABLE_ENTITY,
@@ -205,8 +205,7 @@ class OtlpEvent(BaseModel):
205
205
  name: Optional[str] = Field(
206
206
  None,
207
207
  description=(
208
- "name of the event. "
209
- "This field is semantically required to be set to non-empty string."
208
+ "name of the event. This field is semantically required to be set to non-empty string."
210
209
  ),
211
210
  )
212
211
  time_unix_nano: Optional[
@@ -282,7 +281,7 @@ class OtlpSpan(BaseModel):
282
281
  )
283
282
  events: Optional[list[OtlpEvent]] = Field(
284
283
  None,
285
- description=("events is a collection of Event items. " "A span with no events is valid."),
284
+ description=("events is a collection of Event items. A span with no events is valid."),
286
285
  )
287
286
  flags: Optional[Annotated[int, Field(ge=0, le=4294967295)]] = Field(
288
287
  None,
@@ -2,14 +2,14 @@ import gzip
2
2
  import zlib
3
3
  from typing import Any, Literal, Optional
4
4
 
5
- from fastapi import APIRouter, BackgroundTasks, Depends, Header, HTTPException, Query
5
+ from fastapi import APIRouter, BackgroundTasks, Depends, Header, HTTPException, Path, Query
6
6
  from google.protobuf.message import DecodeError
7
7
  from opentelemetry.proto.collector.trace.v1.trace_service_pb2 import (
8
8
  ExportTraceServiceRequest,
9
9
  ExportTraceServiceResponse,
10
10
  )
11
11
  from pydantic import Field
12
- from sqlalchemy import insert, select
12
+ from sqlalchemy import delete, insert, select
13
13
  from starlette.concurrency import run_in_threadpool
14
14
  from starlette.datastructures import State
15
15
  from starlette.requests import Request
@@ -26,7 +26,7 @@ from phoenix.db.insertion.helpers import as_kv
26
26
  from phoenix.db.insertion.types import Precursors
27
27
  from phoenix.server.authorization import is_not_locked
28
28
  from phoenix.server.bearer_auth import PhoenixUser
29
- from phoenix.server.dml_event import TraceAnnotationInsertEvent
29
+ from phoenix.server.dml_event import SpanDeleteEvent, TraceAnnotationInsertEvent
30
30
  from phoenix.trace.otel import decode_otlp_span
31
31
  from phoenix.utilities.project import get_project_name
32
32
 
@@ -225,3 +225,52 @@ async def _add_spans(req: ExportTraceServiceRequest, state: State) -> None:
225
225
  for otlp_span in scope_span.spans:
226
226
  span = await run_in_threadpool(decode_otlp_span, otlp_span)
227
227
  await state.queue_span_for_bulk_insert(span, project_name)
228
+
229
+
230
+ @router.delete(
231
+ "/traces/{trace_id}",
232
+ operation_id="deleteTrace",
233
+ summary="Delete a trace by trace_id",
234
+ description=(
235
+ "Delete an entire trace by its OpenTelemetry trace_id. "
236
+ "This will permanently remove all spans in the trace and their associated data."
237
+ ),
238
+ responses=add_errors_to_responses([HTTP_404_NOT_FOUND]),
239
+ status_code=204, # No Content for successful deletion
240
+ )
241
+ async def delete_trace(
242
+ request: Request,
243
+ trace_id: str = Path(description="The OpenTelemetry trace_id of the trace to delete"),
244
+ ) -> None:
245
+ """
246
+ Delete a trace by trace_id.
247
+
248
+ This endpoint will:
249
+ 1. Find and delete the trace with the given trace_id (and all its spans via CASCADE)
250
+ 2. Trigger cache invalidation events
251
+ 3. Return 204 No Content on success
252
+
253
+ Note: This deletes the entire trace, including all spans, which maintains data consistency
254
+ and avoids orphaned spans or inconsistent cached cumulative fields.
255
+ """
256
+ async with request.app.state.db() as session:
257
+ # Delete the trace directly and get project_id for cache invalidation
258
+ delete_stmt = (
259
+ delete(models.Trace)
260
+ .where(models.Trace.trace_id == trace_id)
261
+ .returning(models.Trace.project_rowid)
262
+ )
263
+
264
+ project_id = await session.scalar(delete_stmt)
265
+
266
+ if project_id is None:
267
+ raise HTTPException(
268
+ status_code=HTTP_404_NOT_FOUND,
269
+ detail=f"Trace with trace_id '{trace_id}' not found",
270
+ )
271
+
272
+ # Trigger cache invalidation event
273
+ request.state.event_queue.put(SpanDeleteEvent((project_id,)))
274
+
275
+ # Return 204 No Content (successful deletion with no response body)
276
+ return None
@@ -404,11 +404,11 @@ class Project(Node):
404
404
  .where(models.Span.parent_id.is_(None))
405
405
  .where(
406
406
  or_(
407
- models.TextContains(
407
+ models.CaseInsensitiveContains(
408
408
  models.Span.attributes[INPUT_VALUE].as_string(),
409
409
  filter_io_substring,
410
410
  ),
411
- models.TextContains(
411
+ models.CaseInsensitiveContains(
412
412
  models.Span.attributes[OUTPUT_VALUE].as_string(),
413
413
  filter_io_substring,
414
414
  ),
@@ -537,8 +537,7 @@ class Span(Node):
537
537
 
538
538
  @strawberry.field(
539
539
  description=(
540
- "Annotations associated with the span. This encompasses both "
541
- "LLM and human annotations."
540
+ "Annotations associated with the span. This encompasses both LLM and human annotations."
542
541
  )
543
542
  ) # type: ignore
544
543
  async def span_annotations(
phoenix/server/app.py CHANGED
@@ -55,6 +55,7 @@ from phoenix.config import (
55
55
  ENV_PHOENIX_CSRF_TRUSTED_ORIGINS,
56
56
  SERVER_DIR,
57
57
  OAuth2ClientConfig,
58
+ get_env_allow_external_resources,
58
59
  get_env_csrf_trusted_origins,
59
60
  get_env_database_allocated_storage_capacity_gibibytes,
60
61
  get_env_database_usage_insertion_blocking_threshold_percentage,
@@ -245,6 +246,8 @@ class AppConfig(NamedTuple):
245
246
  """ Support email address for user assistance """
246
247
  has_db_threshold: bool = False
247
248
  """ Whether the database has a threshold for usage """
249
+ allow_external_resources: bool = True
250
+ """ Whether to allow external resources like Google Fonts in the web interface """
248
251
 
249
252
 
250
253
  class Static(StaticFiles):
@@ -314,6 +317,7 @@ class Static(StaticFiles):
314
317
  "management_url": self._app_config.management_url,
315
318
  "support_email": self._app_config.support_email,
316
319
  "has_db_threshold": self._app_config.has_db_threshold,
320
+ "allow_external_resources": self._app_config.allow_external_resources,
317
321
  },
318
322
  )
319
323
  except Exception as e:
@@ -1085,6 +1089,7 @@ def create_app(
1085
1089
  get_env_database_allocated_storage_capacity_gibibytes()
1086
1090
  and get_env_database_usage_insertion_blocking_threshold_percentage()
1087
1091
  ),
1092
+ allow_external_resources=get_env_allow_external_resources(),
1088
1093
  ),
1089
1094
  ),
1090
1095
  name="static",
@@ -159,8 +159,7 @@ class DbDiskUsageMonitor(DaemonTask):
159
159
  admin_emails = (await session.scalars(stmt)).all()
160
160
  except Exception:
161
161
  logger.exception(
162
- "Failed to fetch admin emails from database, "
163
- "skipping database usage warning emails"
162
+ "Failed to fetch admin emails from database, skipping database usage warning emails"
164
163
  )
165
164
  return
166
165
 
@@ -128,6 +128,10 @@ class _SpanDmlEventHandler(_DmlEventHandler[SpanDmlEvent]):
128
128
  class _SpanDeleteEventHandler(_SpanDmlEventHandler):
129
129
  @staticmethod
130
130
  def _clear(cache: CacheForDataLoaders, project_id: int) -> None:
131
+ # Call parent's cache invalidation first (core span caches)
132
+ _SpanDmlEventHandler._clear(cache, project_id)
133
+
134
+ # Then invalidate annotation-specific caches
131
135
  cache.annotation_summary.invalidate_project(project_id)
132
136
  cache.document_evaluation_summary.invalidate_project(project_id)
133
137
 
@@ -55,9 +55,11 @@
55
55
  <meta property="og:description" content="AI Observability & Evaluation" />
56
56
  <meta property="og:image" content="https://raw.githubusercontent.com/Arize-ai/phoenix-assets/main/images/socal/social-preview-horizontal.jpg" />
57
57
  <meta name="theme-color" content="#ffffff" />
58
+ {% if allow_external_resources %}
58
59
  <link rel="preconnect" href="https://fonts.googleapis.com">
59
60
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
60
61
  <link href="https://fonts.googleapis.com/css2?family=Geist:wght@100..900&display=swap" rel="stylesheet">
62
+ {% endif %}
61
63
  {% if not is_development -%}
62
64
  {% set _ = collect_assets('index.tsx') -%}
63
65
  {{- render_css() -}}
@@ -111,6 +113,7 @@
111
113
  managementUrl: {{management_url | tojson}},
112
114
  supportEmail: {{support_email | tojson}},
113
115
  hasDbThreshold: Boolean("{{has_db_threshold}}" == "True"),
116
+ allowExternalResources: Boolean("{{allow_external_resources}}" == "True"),
114
117
  }),
115
118
  writable: false
116
119
  });
phoenix/session/client.py CHANGED
@@ -68,8 +68,7 @@ class Client(TraceDataExtractor):
68
68
  """
69
69
  if kwargs.pop("use_active_session_if_available", None) is not None:
70
70
  print(
71
- "`use_active_session_if_available` is deprecated "
72
- "and will be removed in the future."
71
+ "`use_active_session_if_available` is deprecated and will be removed in the future."
73
72
  )
74
73
  if kwargs:
75
74
  raise TypeError(f"Unexpected keyword arguments: {', '.join(kwargs)}")
@@ -456,16 +456,16 @@ class SpanQuery(_HasTmpSuffix):
456
456
  return replace(self, _filter=_filter)
457
457
 
458
458
  def explode(self, key: str, **kwargs: str) -> "SpanQuery":
459
- assert (
460
- isinstance(key, str) and key
461
- ), "The field name for explosion must be a non-empty string."
459
+ assert isinstance(key, str) and key, (
460
+ "The field name for explosion must be a non-empty string."
461
+ )
462
462
  _explode = Explosion(key=key, kwargs=kwargs, primary_index_key=self._index.key)
463
463
  return replace(self, _explode=_explode)
464
464
 
465
465
  def concat(self, key: str, **kwargs: str) -> "SpanQuery":
466
- assert (
467
- isinstance(key, str) and key
468
- ), "The field name for concatenation must be a non-empty string."
466
+ assert isinstance(key, str) and key, (
467
+ "The field name for concatenation must be a non-empty string."
468
+ )
469
469
  _concat = (
470
470
  Concatenation(key=key, kwargs=kwargs, separator=self._concat.separator)
471
471
  if self._concat
phoenix/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "11.14.0"
1
+ __version__ = "11.16.0"