arize-phoenix 4.14.1__tar.gz → 4.16.0__tar.gz

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 (308) hide show
  1. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/PKG-INFO +5 -3
  2. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/pyproject.toml +17 -7
  3. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/db/bulk_inserter.py +131 -5
  4. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/db/engines.py +2 -1
  5. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/db/helpers.py +23 -1
  6. arize_phoenix-4.16.0/src/phoenix/db/insertion/constants.py +2 -0
  7. arize_phoenix-4.16.0/src/phoenix/db/insertion/document_annotation.py +157 -0
  8. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/db/insertion/helpers.py +13 -0
  9. arize_phoenix-4.16.0/src/phoenix/db/insertion/span_annotation.py +144 -0
  10. arize_phoenix-4.16.0/src/phoenix/db/insertion/trace_annotation.py +144 -0
  11. arize_phoenix-4.16.0/src/phoenix/db/insertion/types.py +261 -0
  12. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/experiments/functions.py +3 -2
  13. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/experiments/types.py +3 -3
  14. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/context.py +7 -9
  15. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/dataloaders/__init__.py +2 -0
  16. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/dataloaders/average_experiment_run_latency.py +3 -3
  17. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/dataloaders/dataset_example_revisions.py +2 -4
  18. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/dataloaders/dataset_example_spans.py +2 -4
  19. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/dataloaders/document_evaluation_summaries.py +2 -4
  20. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/dataloaders/document_evaluations.py +2 -4
  21. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/dataloaders/document_retrieval_metrics.py +2 -4
  22. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/dataloaders/evaluation_summaries.py +2 -4
  23. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/dataloaders/experiment_annotation_summaries.py +2 -4
  24. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/dataloaders/experiment_error_rates.py +2 -4
  25. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/dataloaders/experiment_run_counts.py +2 -4
  26. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/dataloaders/experiment_sequence_number.py +2 -4
  27. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/dataloaders/latency_ms_quantile.py +2 -3
  28. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/dataloaders/min_start_or_max_end_times.py +2 -4
  29. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/dataloaders/project_by_name.py +3 -3
  30. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/dataloaders/record_counts.py +2 -4
  31. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/dataloaders/span_annotations.py +2 -4
  32. arize_phoenix-4.16.0/src/phoenix/server/api/dataloaders/span_dataset_examples.py +36 -0
  33. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/dataloaders/span_descendants.py +2 -4
  34. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/dataloaders/span_evaluations.py +2 -4
  35. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/dataloaders/span_projects.py +3 -3
  36. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/dataloaders/token_counts.py +2 -4
  37. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/dataloaders/trace_evaluations.py +2 -4
  38. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/dataloaders/trace_row_ids.py +2 -4
  39. arize_phoenix-4.16.0/src/phoenix/server/api/input_types/SpanAnnotationSort.py +17 -0
  40. arize_phoenix-4.16.0/src/phoenix/server/api/input_types/TraceAnnotationSort.py +17 -0
  41. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/mutations/span_annotations_mutations.py +8 -3
  42. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/mutations/trace_annotations_mutations.py +8 -3
  43. arize_phoenix-4.16.0/src/phoenix/server/api/openapi/main.py +22 -0
  44. arize_phoenix-4.16.0/src/phoenix/server/api/openapi/schema.py +16 -0
  45. arize_phoenix-4.16.0/src/phoenix/server/api/routers/v1/__init__.py +42 -0
  46. arize_phoenix-4.16.0/src/phoenix/server/api/routers/v1/datasets.py +1029 -0
  47. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/routers/v1/evaluations.py +164 -73
  48. arize_phoenix-4.16.0/src/phoenix/server/api/routers/v1/experiment_evaluations.py +113 -0
  49. arize_phoenix-4.16.0/src/phoenix/server/api/routers/v1/experiment_runs.py +160 -0
  50. arize_phoenix-4.16.0/src/phoenix/server/api/routers/v1/experiments.py +252 -0
  51. arize_phoenix-4.16.0/src/phoenix/server/api/routers/v1/pydantic_compat.py +78 -0
  52. arize_phoenix-4.16.0/src/phoenix/server/api/routers/v1/spans.py +236 -0
  53. arize_phoenix-4.16.0/src/phoenix/server/api/routers/v1/traces.py +203 -0
  54. arize_phoenix-4.16.0/src/phoenix/server/api/routers/v1/utils.py +95 -0
  55. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/types/Span.py +27 -3
  56. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/types/Trace.py +21 -4
  57. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/utils.py +4 -4
  58. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/app.py +172 -192
  59. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/grpc_server.py +2 -2
  60. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/main.py +5 -9
  61. arize_phoenix-4.16.0/src/phoenix/server/static/.vite/manifest.json +78 -0
  62. arize_phoenix-4.16.0/src/phoenix/server/static/assets/components-Ci5kMOk5.js +1175 -0
  63. arize_phoenix-4.14.1/src/phoenix/server/static/assets/index-CQgXRwU0.js → arize_phoenix-4.16.0/src/phoenix/server/static/assets/index-BQG5WVX7.js +2 -2
  64. arize_phoenix-4.14.1/src/phoenix/server/static/assets/pages-hdjlFZhO.js → arize_phoenix-4.16.0/src/phoenix/server/static/assets/pages-BrevprVW.js +451 -275
  65. arize_phoenix-4.14.1/src/phoenix/server/static/assets/vendor-DPvSDRn3.js → arize_phoenix-4.16.0/src/phoenix/server/static/assets/vendor-CP0b0YG0.js +2 -2
  66. arize_phoenix-4.14.1/src/phoenix/server/static/assets/vendor-arizeai-CkvPT67c.js → arize_phoenix-4.16.0/src/phoenix/server/static/assets/vendor-arizeai-DTbiPGp6.js +27 -27
  67. arize_phoenix-4.16.0/src/phoenix/server/static/assets/vendor-codemirror-DtdPDzrv.js +15 -0
  68. arize_phoenix-4.14.1/src/phoenix/server/static/assets/vendor-recharts-5jlNaZuF.js → arize_phoenix-4.16.0/src/phoenix/server/static/assets/vendor-recharts-A0DA1O99.js +1 -1
  69. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/thread_server.py +2 -2
  70. arize_phoenix-4.16.0/src/phoenix/server/types.py +18 -0
  71. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/session/client.py +5 -3
  72. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/session/session.py +2 -2
  73. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/trace/dsl/filter.py +2 -6
  74. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/trace/fixtures.py +17 -23
  75. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/trace/utils.py +23 -0
  76. arize_phoenix-4.16.0/src/phoenix/utilities/client.py +116 -0
  77. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/utilities/project.py +1 -1
  78. arize_phoenix-4.16.0/src/phoenix/version.py +1 -0
  79. arize_phoenix-4.14.1/src/phoenix/server/api/openapi/main.py +0 -6
  80. arize_phoenix-4.14.1/src/phoenix/server/api/openapi/schema.py +0 -16
  81. arize_phoenix-4.14.1/src/phoenix/server/api/routers/v1/__init__.py +0 -89
  82. arize_phoenix-4.14.1/src/phoenix/server/api/routers/v1/dataset_examples.py +0 -178
  83. arize_phoenix-4.14.1/src/phoenix/server/api/routers/v1/datasets.py +0 -1023
  84. arize_phoenix-4.14.1/src/phoenix/server/api/routers/v1/experiment_evaluations.py +0 -136
  85. arize_phoenix-4.14.1/src/phoenix/server/api/routers/v1/experiment_runs.py +0 -217
  86. arize_phoenix-4.14.1/src/phoenix/server/api/routers/v1/experiments.py +0 -301
  87. arize_phoenix-4.14.1/src/phoenix/server/api/routers/v1/spans.py +0 -275
  88. arize_phoenix-4.14.1/src/phoenix/server/api/routers/v1/traces.py +0 -228
  89. arize_phoenix-4.14.1/src/phoenix/server/openapi/docs.py +0 -221
  90. arize_phoenix-4.14.1/src/phoenix/server/static/.vite/manifest.json +0 -78
  91. arize_phoenix-4.14.1/src/phoenix/server/static/assets/components-DeS0YEmv.js +0 -1142
  92. arize_phoenix-4.14.1/src/phoenix/server/static/assets/vendor-codemirror-Cqwpwlua.js +0 -12
  93. arize_phoenix-4.14.1/src/phoenix/version.py +0 -1
  94. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/.gitignore +0 -0
  95. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/IP_NOTICE +0 -0
  96. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/LICENSE +0 -0
  97. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/README.md +0 -0
  98. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/examples/manually-instrumented-chatbot/chat-service/chat/__init__.py +0 -0
  99. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/examples/manually-instrumented-chatbot/chat-service/chat/app.py +0 -0
  100. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/examples/manually-instrumented-chatbot/chat-service/chat/types.py +0 -0
  101. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/examples/manually-instrumented-chatbot/frontend/Dockerfile +0 -0
  102. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/examples/manually-instrumented-chatbot/frontend/Makefile +0 -0
  103. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/examples/manually-instrumented-chatbot/frontend/__init__.py +0 -0
  104. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/examples/manually-instrumented-chatbot/frontend/pyproject.toml +0 -0
  105. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/examples/manually-instrumented-chatbot/frontend/requirements.txt +0 -0
  106. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/examples/manually-instrumented-chatbot/frontend/schema.json +0 -0
  107. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/__init__.py +0 -0
  108. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/config.py +0 -0
  109. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/core/__init__.py +0 -0
  110. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/core/embedding_dimension.py +0 -0
  111. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/core/model.py +0 -0
  112. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/core/model_schema.py +0 -0
  113. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/core/model_schema_adapter.py +0 -0
  114. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/datetime_utils.py +0 -0
  115. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/db/README.md +0 -0
  116. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/db/__init__.py +0 -0
  117. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/db/alembic.ini +0 -0
  118. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/db/insertion/__init__.py +0 -0
  119. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/db/insertion/dataset.py +0 -0
  120. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/db/insertion/evaluation.py +0 -0
  121. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/db/insertion/span.py +0 -0
  122. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/db/migrate.py +0 -0
  123. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/db/migrations/__init__.py +0 -0
  124. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/db/migrations/env.py +0 -0
  125. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/db/migrations/script.py.mako +0 -0
  126. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/db/migrations/types.py +0 -0
  127. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/db/migrations/versions/10460e46d750_datasets.py +0 -0
  128. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/db/migrations/versions/cf03bd6bae1d_init.py +0 -0
  129. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/db/models.py +0 -0
  130. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/exceptions.py +0 -0
  131. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/experiments/__init__.py +0 -0
  132. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/experiments/evaluators/__init__.py +0 -0
  133. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/experiments/evaluators/base.py +0 -0
  134. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/experiments/evaluators/code_evaluators.py +0 -0
  135. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/experiments/evaluators/llm_evaluators.py +0 -0
  136. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/experiments/evaluators/utils.py +0 -0
  137. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/experiments/tracing.py +0 -0
  138. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/experiments/utils.py +0 -0
  139. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/inferences/__init__.py +0 -0
  140. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/inferences/errors.py +0 -0
  141. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/inferences/fixtures.py +0 -0
  142. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/inferences/inferences.py +0 -0
  143. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/inferences/schema.py +0 -0
  144. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/inferences/validation.py +0 -0
  145. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/metrics/README.md +0 -0
  146. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/metrics/__init__.py +0 -0
  147. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/metrics/binning.py +0 -0
  148. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/metrics/metrics.py +0 -0
  149. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/metrics/mixins.py +0 -0
  150. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/metrics/retrieval_metrics.py +0 -0
  151. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/metrics/timeseries.py +0 -0
  152. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/metrics/wrappers.py +0 -0
  153. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/pointcloud/__init__.py +0 -0
  154. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/pointcloud/clustering.py +0 -0
  155. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/pointcloud/pointcloud.py +0 -0
  156. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/pointcloud/projectors.py +0 -0
  157. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/pointcloud/umap_parameters.py +0 -0
  158. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/py.typed +0 -0
  159. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/__init__.py +0 -0
  160. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/__init__.py +0 -0
  161. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/dataloaders/cache/__init__.py +0 -0
  162. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/dataloaders/cache/two_tier_cache.py +0 -0
  163. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/helpers/__init__.py +0 -0
  164. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/helpers/dataset_helpers.py +0 -0
  165. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/input_types/AddExamplesToDatasetInput.py +0 -0
  166. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/input_types/AddSpansToDatasetInput.py +0 -0
  167. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/input_types/ClearProjectInput.py +0 -0
  168. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/input_types/ClusterInput.py +0 -0
  169. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/input_types/Coordinates.py +0 -0
  170. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/input_types/CreateDatasetInput.py +0 -0
  171. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/input_types/CreateSpanAnnotationInput.py +0 -0
  172. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/input_types/CreateTraceAnnotationInput.py +0 -0
  173. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/input_types/DataQualityMetricInput.py +0 -0
  174. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/input_types/DatasetExampleInput.py +0 -0
  175. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/input_types/DatasetSort.py +0 -0
  176. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/input_types/DatasetVersionSort.py +0 -0
  177. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/input_types/DeleteAnnotationsInput.py +0 -0
  178. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/input_types/DeleteDatasetExamplesInput.py +0 -0
  179. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/input_types/DeleteDatasetInput.py +0 -0
  180. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/input_types/DeleteExperimentsInput.py +0 -0
  181. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/input_types/DimensionFilter.py +0 -0
  182. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/input_types/DimensionInput.py +0 -0
  183. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/input_types/Granularity.py +0 -0
  184. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/input_types/PatchAnnotationInput.py +0 -0
  185. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/input_types/PatchDatasetExamplesInput.py +0 -0
  186. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/input_types/PatchDatasetInput.py +0 -0
  187. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/input_types/PerformanceMetricInput.py +0 -0
  188. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/input_types/SpanSort.py +0 -0
  189. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/input_types/TimeRange.py +0 -0
  190. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/input_types/__init__.py +0 -0
  191. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/interceptor.py +0 -0
  192. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/mutations/__init__.py +0 -0
  193. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/mutations/auth.py +0 -0
  194. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/mutations/dataset_mutations.py +0 -0
  195. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/mutations/experiment_mutations.py +0 -0
  196. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/mutations/export_events_mutations.py +0 -0
  197. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/mutations/project_mutations.py +0 -0
  198. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/openapi/__init__.py +0 -0
  199. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/queries.py +0 -0
  200. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/routers/__init__.py +0 -0
  201. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/routers/utils.py +0 -0
  202. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/schema.py +0 -0
  203. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/types/Annotation.py +0 -0
  204. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/types/AnnotatorKind.py +0 -0
  205. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/types/Cluster.py +0 -0
  206. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/types/CreateDatasetPayload.py +0 -0
  207. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/types/DataQualityMetric.py +0 -0
  208. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/types/Dataset.py +0 -0
  209. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/types/DatasetExample.py +0 -0
  210. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/types/DatasetExampleRevision.py +0 -0
  211. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/types/DatasetValues.py +0 -0
  212. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/types/DatasetVersion.py +0 -0
  213. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/types/Dimension.py +0 -0
  214. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/types/DimensionDataType.py +0 -0
  215. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/types/DimensionShape.py +0 -0
  216. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/types/DimensionType.py +0 -0
  217. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/types/DimensionWithValue.py +0 -0
  218. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/types/DocumentEvaluationSummary.py +0 -0
  219. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/types/DocumentRetrievalMetrics.py +0 -0
  220. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/types/EmbeddingDimension.py +0 -0
  221. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/types/EmbeddingMetadata.py +0 -0
  222. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/types/Evaluation.py +0 -0
  223. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/types/EvaluationSummary.py +0 -0
  224. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/types/Event.py +0 -0
  225. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/types/EventMetadata.py +0 -0
  226. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/types/ExampleRevisionInterface.py +0 -0
  227. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/types/Experiment.py +0 -0
  228. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/types/ExperimentAnnotationSummary.py +0 -0
  229. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/types/ExperimentComparison.py +0 -0
  230. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/types/ExperimentRun.py +0 -0
  231. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/types/ExperimentRunAnnotation.py +0 -0
  232. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/types/ExportedFile.py +0 -0
  233. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/types/Functionality.py +0 -0
  234. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/types/Inferences.py +0 -0
  235. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/types/InferencesRole.py +0 -0
  236. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/types/MimeType.py +0 -0
  237. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/types/Model.py +0 -0
  238. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/types/NumericRange.py +0 -0
  239. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/types/PerformanceMetric.py +0 -0
  240. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/types/Project.py +0 -0
  241. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/types/PromptResponse.py +0 -0
  242. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/types/Retrieval.py +0 -0
  243. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/types/ScalarDriftMetricEnum.py +0 -0
  244. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/types/Segments.py +0 -0
  245. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/types/SortDir.py +0 -0
  246. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/types/SpanAnnotation.py +0 -0
  247. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/types/TimeSeries.py +0 -0
  248. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/types/TraceAnnotation.py +0 -0
  249. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/types/UMAPPoints.py +0 -0
  250. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/types/ValidationResult.py +0 -0
  251. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/types/VectorDriftMetricEnum.py +0 -0
  252. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/types/__init__.py +0 -0
  253. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/types/node.py +0 -0
  254. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/api/types/pagination.py +0 -0
  255. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/openapi/__init__.py +0 -0
  256. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/prometheus.py +0 -0
  257. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/static/apple-touch-icon-114x114.png +0 -0
  258. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/static/apple-touch-icon-120x120.png +0 -0
  259. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/static/apple-touch-icon-144x144.png +0 -0
  260. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/static/apple-touch-icon-152x152.png +0 -0
  261. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/static/apple-touch-icon-180x180.png +0 -0
  262. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/static/apple-touch-icon-72x72.png +0 -0
  263. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/static/apple-touch-icon-76x76.png +0 -0
  264. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/static/apple-touch-icon.png +0 -0
  265. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/static/assets/vendor-DxkFTwjz.css +0 -0
  266. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/static/assets/vendor-three-DwGkEfCM.js +0 -0
  267. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/static/favicon.ico +0 -0
  268. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/static/modernizr.js +0 -0
  269. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/telemetry.py +0 -0
  270. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/templates/__init__.py +0 -0
  271. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/server/templates/index.html +0 -0
  272. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/services.py +0 -0
  273. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/session/__init__.py +0 -0
  274. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/session/data_extractor.py +0 -0
  275. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/session/evaluation.py +0 -0
  276. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/settings.py +0 -0
  277. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/trace/__init__.py +0 -0
  278. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/trace/attributes.py +0 -0
  279. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/trace/dsl/README.md +0 -0
  280. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/trace/dsl/__init__.py +0 -0
  281. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/trace/dsl/helpers.py +0 -0
  282. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/trace/dsl/query.py +0 -0
  283. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/trace/errors.py +0 -0
  284. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/trace/evaluation_conventions.py +0 -0
  285. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/trace/exporter.py +0 -0
  286. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/trace/langchain/__init__.py +0 -0
  287. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/trace/langchain/instrumentor.py +0 -0
  288. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/trace/llama_index/__init__.py +0 -0
  289. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/trace/llama_index/callback.py +0 -0
  290. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/trace/openai/__init__.py +0 -0
  291. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/trace/openai/instrumentor.py +0 -0
  292. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/trace/otel.py +0 -0
  293. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/trace/projects.py +0 -0
  294. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/trace/schemas.py +0 -0
  295. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/trace/span_evaluations.py +0 -0
  296. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/trace/span_json_decoder.py +0 -0
  297. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/trace/span_json_encoder.py +0 -0
  298. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/trace/trace_dataset.py +0 -0
  299. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/trace/v1/__init__.py +0 -0
  300. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/trace/v1/evaluation_pb2.py +0 -0
  301. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/trace/v1/evaluation_pb2.pyi +0 -0
  302. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/utilities/__init__.py +0 -0
  303. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/utilities/deprecation.py +0 -0
  304. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/utilities/error_handling.py +0 -0
  305. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/utilities/json.py +0 -0
  306. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/utilities/logging.py +0 -0
  307. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/utilities/re.py +0 -0
  308. {arize_phoenix-4.14.1 → arize_phoenix-4.16.0}/src/phoenix/utilities/span_store.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: arize-phoenix
3
- Version: 4.14.1
3
+ Version: 4.16.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,6 +22,7 @@ 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
25
26
  Requires-Dist: grpcio
26
27
  Requires-Dist: hdbscan>=0.8.33
27
28
  Requires-Dist: httpx
@@ -40,8 +41,8 @@ Requires-Dist: pandas>=1.0
40
41
  Requires-Dist: protobuf<6.0,>=3.20
41
42
  Requires-Dist: psutil
42
43
  Requires-Dist: pyarrow
44
+ Requires-Dist: pydantic!=2.0.*,<3,>=1.0
43
45
  Requires-Dist: python-multipart
44
- Requires-Dist: pyyaml
45
46
  Requires-Dist: scikit-learn
46
47
  Requires-Dist: scipy
47
48
  Requires-Dist: sqlalchemy[asyncio]<3,>=2.0.4
@@ -56,9 +57,9 @@ Requires-Dist: uvicorn
56
57
  Requires-Dist: wrapt
57
58
  Provides-Extra: container
58
59
  Requires-Dist: opentelemetry-exporter-otlp; extra == 'container'
60
+ Requires-Dist: opentelemetry-instrumentation-fastapi; extra == 'container'
59
61
  Requires-Dist: opentelemetry-instrumentation-grpc; extra == 'container'
60
62
  Requires-Dist: opentelemetry-instrumentation-sqlalchemy; extra == 'container'
61
- Requires-Dist: opentelemetry-instrumentation-starlette; extra == 'container'
62
63
  Requires-Dist: opentelemetry-proto>=1.12.0; extra == 'container'
63
64
  Requires-Dist: opentelemetry-sdk; extra == 'container'
64
65
  Requires-Dist: opentelemetry-semantic-conventions; extra == 'container'
@@ -71,6 +72,7 @@ Requires-Dist: anthropic; extra == 'dev'
71
72
  Requires-Dist: arize[autoembeddings,llm-evaluation]; extra == 'dev'
72
73
  Requires-Dist: asgi-lifespan; extra == 'dev'
73
74
  Requires-Dist: asyncpg; extra == 'dev'
75
+ Requires-Dist: faker>=26.0.0; extra == 'dev'
74
76
  Requires-Dist: gcsfs; extra == 'dev'
75
77
  Requires-Dist: google-cloud-aiplatform>=1.3; extra == 'dev'
76
78
  Requires-Dist: hatch; extra == 'dev'
@@ -59,7 +59,8 @@ dependencies = [
59
59
  "cachetools",
60
60
  "python-multipart", # see https://www.starlette.io/#dependencies
61
61
  "arize-phoenix-evals>=0.13.1",
62
- "pyyaml", # for OpenAPI
62
+ "fastapi",
63
+ "pydantic>=1.0,!=2.0.*,<3,", # exclude 2.0.* since it does not support the `json_encoders` configuration setting
63
64
  ]
64
65
  dynamic = ["version"]
65
66
 
@@ -92,6 +93,7 @@ dev = [
92
93
  "anthropic",
93
94
  "prometheus_client",
94
95
  "asgi-lifespan",
96
+ "Faker>=26.0.0",
95
97
  ]
96
98
  evals = []
97
99
  experimental = []
@@ -111,7 +113,7 @@ container = [
111
113
  "opentelemetry-proto>=1.12.0",
112
114
  "opentelemetry-exporter-otlp",
113
115
  "opentelemetry-semantic-conventions",
114
- "opentelemetry-instrumentation-starlette",
116
+ "opentelemetry-instrumentation-fastapi",
115
117
  "opentelemetry-instrumentation-sqlalchemy",
116
118
  "opentelemetry-instrumentation-grpc",
117
119
  "py-grpc-prometheus",
@@ -161,13 +163,16 @@ dependencies = [
161
163
  "protobuf==3.20", # version minimum (for tests)
162
164
  "responses",
163
165
  "tiktoken",
164
- "typing-extensions==4.5.0; python_version<'3.12'",
165
- "typing-extensions==4.6.0; python_version>='3.12'",
166
+ "typing-extensions==4.5.0; python_version=='3.8'",
167
+ "typing-extensions==4.6.0; python_version=='3.9'",
168
+ "pydantic==1.9.0; python_version<='3.9'", # minimum version of pydantic compatible with openai
169
+ "pydantic==2.8.2; python_version=='3.12'",
166
170
  "httpx", # For OpenAI testing
167
171
  "respx", # For OpenAI testing
168
172
  "nest-asyncio", # for executor testing
169
173
  "astunparse; python_version<'3.9'", # `ast.unparse(...)` is only available starting with Python 3.9
170
174
  "asgi-lifespan",
175
+ "Faker>=26.0.0",
171
176
  ]
172
177
 
173
178
  [tool.hatch.envs.type]
@@ -190,12 +195,15 @@ dependencies = [
190
195
  "opentelemetry-proto>=1.12.0",
191
196
  "opentelemetry-exporter-otlp",
192
197
  "opentelemetry-semantic-conventions",
193
- "opentelemetry-instrumentation-starlette",
198
+ "opentelemetry-instrumentation-fastapi",
194
199
  "opentelemetry-instrumentation-sqlalchemy",
195
200
  "opentelemetry-instrumentation-grpc",
196
201
  "py-grpc-prometheus",
197
202
  "strawberry-graphql[opentelemetry]==0.236.0", # need to pin version because we're monkey-patching
198
203
  "requests", # this is needed to type-check third-party packages
204
+ "pydantic==1.10.17; python_version=='3.8'", # lower minor versions of pydantic break strawberry mypy plugin
205
+ "pydantic==1.10.17; python_version=='3.9'", # lower minor versions of pydantic break strawberry mypy plugin
206
+ "pydantic==2.8.2; python_version=='3.12'",
199
207
  ]
200
208
 
201
209
  [[tool.hatch.envs.type.matrix]]
@@ -310,11 +318,12 @@ build = 'strawberry export-schema phoenix.server.api.schema:schema > app/schema.
310
318
 
311
319
  [tool.hatch.envs.openapi]
312
320
  dependencies = [
313
- "pyyaml",
321
+ "pydantic==2.8.2",
322
+ "fastapi==0.111.0",
314
323
  ]
315
324
 
316
325
  [tool.hatch.envs.openapi.scripts]
317
- build = 'python -m phoenix.server.api.openapi.main > schemas/openapi.yaml'
326
+ build = "python -m phoenix.server.api.openapi.main > schemas/openapi.json"
318
327
 
319
328
  [tool.hatch.envs.proto]
320
329
  detached = true
@@ -379,6 +388,7 @@ module = [
379
388
  "sqlean",
380
389
  "grpc.*",
381
390
  "py_grpc_prometheus.*",
391
+ "orjson", # suppress fastapi internal type errors
382
392
  ]
383
393
  ignore_missing_imports = true
384
394
 
@@ -1,28 +1,36 @@
1
1
  import asyncio
2
2
  import logging
3
- from asyncio import Queue
3
+ from asyncio import Queue, as_completed
4
+ from collections import defaultdict
4
5
  from dataclasses import dataclass, field
5
6
  from datetime import datetime, timezone
7
+ from functools import singledispatchmethod
6
8
  from itertools import islice
7
9
  from time import perf_counter
8
10
  from typing import (
9
11
  Any,
10
- AsyncContextManager,
11
12
  Awaitable,
12
13
  Callable,
14
+ DefaultDict,
15
+ Dict,
13
16
  Iterable,
14
17
  List,
18
+ Mapping,
15
19
  Optional,
16
20
  Set,
17
21
  Tuple,
22
+ Type,
18
23
  cast,
19
24
  )
20
25
 
21
26
  from cachetools import LRUCache
22
- from sqlalchemy.ext.asyncio import AsyncSession
27
+ from sqlalchemy import Select, select
23
28
  from typing_extensions import TypeAlias
24
29
 
25
30
  import phoenix.trace.v1 as pb
31
+ from phoenix.db import models
32
+ from phoenix.db.insertion.constants import DEFAULT_RETRY_ALLOWANCE, DEFAULT_RETRY_DELAY_SEC
33
+ from phoenix.db.insertion.document_annotation import DocumentAnnotationQueueInserter
26
34
  from phoenix.db.insertion.evaluation import (
27
35
  EvaluationInsertionEvent,
28
36
  InsertEvaluationError,
@@ -30,7 +38,11 @@ from phoenix.db.insertion.evaluation import (
30
38
  )
31
39
  from phoenix.db.insertion.helpers import DataManipulation, DataManipulationEvent
32
40
  from phoenix.db.insertion.span import SpanInsertionEvent, insert_span
41
+ from phoenix.db.insertion.span_annotation import SpanAnnotationQueueInserter
42
+ from phoenix.db.insertion.trace_annotation import TraceAnnotationQueueInserter
43
+ from phoenix.db.insertion.types import Insertables, Precursors
33
44
  from phoenix.server.api.dataloaders import CacheForDataLoaders
45
+ from phoenix.server.types import DbSessionFactory
34
46
  from phoenix.trace.schemas import Span
35
47
 
36
48
  logger = logging.getLogger(__name__)
@@ -46,7 +58,7 @@ class TransactionResult:
46
58
  class BulkInserter:
47
59
  def __init__(
48
60
  self,
49
- db: Callable[[], AsyncContextManager[AsyncSession]],
61
+ db: DbSessionFactory,
50
62
  *,
51
63
  cache_for_dataloaders: Optional[CacheForDataLoaders] = None,
52
64
  initial_batch_of_operations: Iterable[DataManipulation] = (),
@@ -56,6 +68,8 @@ class BulkInserter:
56
68
  max_ops_per_transaction: int = 1000,
57
69
  max_queue_size: int = 1000,
58
70
  enable_prometheus: bool = False,
71
+ retry_delay_sec: float = DEFAULT_RETRY_DELAY_SEC,
72
+ retry_allowance: int = DEFAULT_RETRY_ALLOWANCE,
59
73
  ) -> None:
60
74
  """
61
75
  :param db: A function to initiate a new database session.
@@ -82,6 +96,9 @@ class BulkInserter:
82
96
  self._last_updated_at_by_project: LRUCache[ProjectRowId, datetime] = LRUCache(maxsize=100)
83
97
  self._cache_for_dataloaders = cache_for_dataloaders
84
98
  self._enable_prometheus = enable_prometheus
99
+ self._retry_delay_sec = retry_delay_sec
100
+ self._retry_allowance = retry_allowance
101
+ self._queue_inserters = _QueueInserters(db, self._retry_delay_sec, self._retry_allowance)
85
102
 
86
103
  def last_updated_at(self, project_rowid: Optional[ProjectRowId] = None) -> Optional[datetime]:
87
104
  if isinstance(project_rowid, ProjectRowId):
@@ -91,6 +108,7 @@ class BulkInserter:
91
108
  async def __aenter__(
92
109
  self,
93
110
  ) -> Tuple[
111
+ Callable[[Any], Awaitable[None]],
94
112
  Callable[[Span, str], Awaitable[None]],
95
113
  Callable[[pb.Evaluation], Awaitable[None]],
96
114
  Callable[[DataManipulation], None],
@@ -99,6 +117,7 @@ class BulkInserter:
99
117
  self._operations = Queue(maxsize=self._max_queue_size)
100
118
  self._task = asyncio.create_task(self._bulk_insert())
101
119
  return (
120
+ self._enqueue,
102
121
  self._queue_span,
103
122
  self._queue_evaluation,
104
123
  self._enqueue_operation,
@@ -110,6 +129,9 @@ class BulkInserter:
110
129
  self._task.cancel()
111
130
  self._task = None
112
131
 
132
+ async def _enqueue(self, *items: Any) -> None:
133
+ await self._queue_inserters.enqueue(*items)
134
+
113
135
  def _enqueue_operation(self, operation: DataManipulation) -> None:
114
136
  cast("Queue[DataManipulation]", self._operations).put_nowait(operation)
115
137
 
@@ -125,7 +147,17 @@ class BulkInserter:
125
147
  assert isinstance(self._operations, Queue)
126
148
  spans_buffer, evaluations_buffer = None, None
127
149
  # start first insert immediately if the inserter has not run recently
128
- while self._running or not self._operations.empty() or self._spans or self._evaluations:
150
+ while (
151
+ self._running
152
+ or not self._queue_inserters.empty
153
+ or not self._operations.empty()
154
+ or self._spans
155
+ or self._evaluations
156
+ ):
157
+ if not self._queue_inserters.empty:
158
+ if inserted_ids := await self._queue_inserters.insert():
159
+ for project_rowid in await self._get_project_rowids(inserted_ids):
160
+ self._last_updated_at_by_project[project_rowid] = datetime.now(timezone.utc)
129
161
  if self._operations.empty() and not (self._spans or self._evaluations):
130
162
  await asyncio.sleep(self._sleep)
131
163
  continue
@@ -245,3 +277,97 @@ class BulkInserter:
245
277
  BULK_LOADER_EXCEPTIONS.inc()
246
278
  logger.exception("Failed to insert evaluations")
247
279
  return transaction_result
280
+
281
+ async def _get_project_rowids(
282
+ self,
283
+ inserted_ids: Mapping[Type[models.Base], List[int]],
284
+ ) -> Set[int]:
285
+ ans: Set[int] = set()
286
+ if not inserted_ids:
287
+ return ans
288
+ stmt: Select[Tuple[int]]
289
+ for table, ids in inserted_ids.items():
290
+ if not ids:
291
+ continue
292
+ if issubclass(table, models.SpanAnnotation):
293
+ stmt = (
294
+ select(models.Project.id)
295
+ .join(models.Trace)
296
+ .join_from(models.Trace, models.Span)
297
+ .join_from(models.Span, models.SpanAnnotation)
298
+ .where(models.SpanAnnotation.id.in_(ids))
299
+ )
300
+ elif issubclass(table, models.DocumentAnnotation):
301
+ stmt = (
302
+ select(models.Project.id)
303
+ .join(models.Trace)
304
+ .join_from(models.Trace, models.Span)
305
+ .join_from(models.Span, models.DocumentAnnotation)
306
+ .where(models.DocumentAnnotation.id.in_(ids))
307
+ )
308
+ elif issubclass(table, models.TraceAnnotation):
309
+ stmt = (
310
+ select(models.Project.id)
311
+ .join(models.Trace)
312
+ .join_from(models.Trace, models.TraceAnnotation)
313
+ .where(models.TraceAnnotation.id.in_(ids))
314
+ )
315
+ else:
316
+ continue
317
+ async with self._db() as session:
318
+ project_rowids = [_ async for _ in await session.stream_scalars(stmt)]
319
+ ans.update(project_rowids)
320
+ return ans
321
+
322
+
323
+ class _QueueInserters:
324
+ def __init__(
325
+ self,
326
+ db: DbSessionFactory,
327
+ retry_delay_sec: float = DEFAULT_RETRY_DELAY_SEC,
328
+ retry_allowance: int = DEFAULT_RETRY_ALLOWANCE,
329
+ ) -> None:
330
+ self._db = db
331
+ args = (db, retry_delay_sec, retry_allowance)
332
+ self._span_annotations = SpanAnnotationQueueInserter(*args)
333
+ self._trace_annotations = TraceAnnotationQueueInserter(*args)
334
+ self._document_annotations = DocumentAnnotationQueueInserter(*args)
335
+ self._queues = (
336
+ self._span_annotations,
337
+ self._trace_annotations,
338
+ self._document_annotations,
339
+ )
340
+
341
+ async def insert(self) -> Dict[Type[models.Base], List[int]]:
342
+ ans: DefaultDict[Type[models.Base], List[int]] = defaultdict(list)
343
+ for coro in as_completed([q.insert() for q in self._queues]):
344
+ table, inserted_ids = await coro
345
+ if inserted_ids:
346
+ ans[table].extend(inserted_ids)
347
+ return ans
348
+
349
+ @property
350
+ def empty(self) -> bool:
351
+ return all(q.empty for q in self._queues)
352
+
353
+ async def enqueue(self, *items: Any) -> None:
354
+ for item in items:
355
+ await self._enqueue(item)
356
+
357
+ @singledispatchmethod
358
+ async def _enqueue(self, item: Any) -> None: ...
359
+
360
+ @_enqueue.register(Precursors.SpanAnnotation)
361
+ @_enqueue.register(Insertables.SpanAnnotation)
362
+ async def _(self, item: Precursors.SpanAnnotation) -> None:
363
+ await self._span_annotations.enqueue(item)
364
+
365
+ @_enqueue.register(Precursors.TraceAnnotation)
366
+ @_enqueue.register(Insertables.TraceAnnotation)
367
+ async def _(self, item: Precursors.TraceAnnotation) -> None:
368
+ await self._trace_annotations.enqueue(item)
369
+
370
+ @_enqueue.register(Precursors.DocumentAnnotation)
371
+ @_enqueue.register(Insertables.DocumentAnnotation)
372
+ async def _(self, item: Precursors.DocumentAnnotation) -> None:
373
+ await self._document_annotations.enqueue(item)
@@ -8,7 +8,7 @@ from typing import Any
8
8
  import aiosqlite
9
9
  import numpy as np
10
10
  import sqlean
11
- from sqlalchemy import URL, event, make_url
11
+ from sqlalchemy import URL, StaticPool, event, make_url
12
12
  from sqlalchemy.ext.asyncio import AsyncEngine, create_async_engine
13
13
  from typing_extensions import assert_never
14
14
 
@@ -105,6 +105,7 @@ def aio_sqlite_engine(
105
105
  echo=echo,
106
106
  json_serializer=_dumps,
107
107
  async_creator=async_creator,
108
+ poolclass=StaticPool,
108
109
  )
109
110
  event.listen(engine.sync_engine, "connect", set_sqlite_pragma)
110
111
  if not migrate:
@@ -1,5 +1,5 @@
1
1
  from enum import Enum
2
- from typing import Any, Optional, Tuple
2
+ from typing import Any, Callable, Hashable, Iterable, List, Optional, Set, Tuple, TypeVar
3
3
 
4
4
  from openinference.semconv.trace import (
5
5
  OpenInferenceSpanKindValues,
@@ -80,3 +80,25 @@ def get_project_names_for_experiments(*experiment_ids: int) -> Select[Tuple[Opti
80
80
  .where(models.Experiment.id.in_(set(experiment_ids)))
81
81
  .where(models.Experiment.project_name.isnot(None))
82
82
  )
83
+
84
+
85
+ _AnyT = TypeVar("_AnyT")
86
+ _KeyT = TypeVar("_KeyT", bound=Hashable)
87
+
88
+
89
+ def dedup(
90
+ items: Iterable[_AnyT],
91
+ key: Callable[[_AnyT], _KeyT],
92
+ ) -> List[_AnyT]:
93
+ """
94
+ Discard subsequent duplicates after the first appearance in `items`.
95
+ """
96
+ ans = []
97
+ seen: Set[_KeyT] = set()
98
+ for item in items:
99
+ if (k := key(item)) in seen:
100
+ continue
101
+ else:
102
+ ans.append(item)
103
+ seen.add(k)
104
+ return ans
@@ -0,0 +1,2 @@
1
+ DEFAULT_RETRY_DELAY_SEC: float = 60
2
+ DEFAULT_RETRY_ALLOWANCE: int = 10
@@ -0,0 +1,157 @@
1
+ from datetime import datetime
2
+ from typing import Any, List, Mapping, NamedTuple, Optional, Tuple
3
+
4
+ from sqlalchemy import Row, Select, and_, select, tuple_
5
+ from sqlalchemy.ext.asyncio import AsyncSession
6
+ from typing_extensions import TypeAlias
7
+
8
+ from phoenix.db import models
9
+ from phoenix.db.helpers import dedup, num_docs_col
10
+ from phoenix.db.insertion.types import (
11
+ Insertables,
12
+ Postponed,
13
+ Precursors,
14
+ QueueInserter,
15
+ Received,
16
+ )
17
+
18
+ _Name: TypeAlias = str
19
+ _SpanId: TypeAlias = str
20
+ _SpanRowId: TypeAlias = int
21
+ _DocumentPosition: TypeAlias = int
22
+ _AnnoRowId: TypeAlias = int
23
+ _NumDocs: TypeAlias = int
24
+
25
+ _Key: TypeAlias = Tuple[_Name, _SpanId, _DocumentPosition]
26
+ _UniqueBy: TypeAlias = Tuple[_Name, _SpanRowId, _DocumentPosition]
27
+ _Existing: TypeAlias = Tuple[
28
+ _SpanRowId,
29
+ _SpanId,
30
+ _NumDocs,
31
+ Optional[_AnnoRowId],
32
+ Optional[_Name],
33
+ Optional[_DocumentPosition],
34
+ Optional[datetime],
35
+ ]
36
+
37
+
38
+ class DocumentAnnotationQueueInserter(
39
+ QueueInserter[
40
+ Precursors.DocumentAnnotation,
41
+ Insertables.DocumentAnnotation,
42
+ models.DocumentAnnotation,
43
+ ],
44
+ table=models.DocumentAnnotation,
45
+ unique_by=("name", "span_rowid", "document_position"),
46
+ ):
47
+ async def _partition(
48
+ self,
49
+ session: AsyncSession,
50
+ *parcels: Received[Precursors.DocumentAnnotation],
51
+ ) -> Tuple[
52
+ List[Received[Insertables.DocumentAnnotation]],
53
+ List[Postponed[Precursors.DocumentAnnotation]],
54
+ List[Received[Precursors.DocumentAnnotation]],
55
+ ]:
56
+ to_insert: List[Received[Insertables.DocumentAnnotation]] = []
57
+ to_postpone: List[Postponed[Precursors.DocumentAnnotation]] = []
58
+ to_discard: List[Received[Precursors.DocumentAnnotation]] = []
59
+
60
+ stmt = self._select_existing(*map(_key, parcels))
61
+ existing: List[Row[_Existing]] = [_ async for _ in await session.stream(stmt)]
62
+ existing_spans: Mapping[str, _SpanAttr] = {
63
+ e.span_id: _SpanAttr(e.span_rowid, e.num_docs) for e in existing
64
+ }
65
+ existing_annos: Mapping[_Key, _AnnoAttr] = {
66
+ (e.name, e.span_id, e.document_position): _AnnoAttr(e.span_rowid, e.id, e.updated_at)
67
+ for e in existing
68
+ if e.id is not None
69
+ and e.name is not None
70
+ and e.document_position is not None
71
+ and e.updated_at is not None
72
+ }
73
+
74
+ for p in parcels:
75
+ if (anno := existing_annos.get(_key(p))) is not None:
76
+ if p.received_at <= anno.updated_at:
77
+ to_discard.append(p)
78
+ else:
79
+ to_insert.append(
80
+ Received(
81
+ received_at=p.received_at,
82
+ item=p.item.as_insertable(
83
+ span_rowid=anno.span_rowid,
84
+ id_=anno.id_,
85
+ ),
86
+ )
87
+ )
88
+ elif (span := existing_spans.get(p.item.span_id)) is not None:
89
+ if 0 <= p.item.document_position < span.num_docs:
90
+ to_insert.append(
91
+ Received(
92
+ received_at=p.received_at,
93
+ item=p.item.as_insertable(
94
+ span_rowid=span.span_rowid,
95
+ ),
96
+ )
97
+ )
98
+ else:
99
+ to_discard.append(p)
100
+ elif isinstance(p, Postponed):
101
+ if p.retries_left > 1:
102
+ to_postpone.append(p.postpone(p.retries_left - 1))
103
+ else:
104
+ to_discard.append(p)
105
+ elif isinstance(p, Received):
106
+ to_postpone.append(p.postpone(self._retry_allowance))
107
+ else:
108
+ to_discard.append(p)
109
+
110
+ assert len(to_insert) + len(to_postpone) + len(to_discard) == len(parcels)
111
+ to_insert = dedup(sorted(to_insert, key=_time, reverse=True), _unique_by)[::-1]
112
+ return to_insert, to_postpone, to_discard
113
+
114
+ def _select_existing(self, *keys: _Key) -> Select[_Existing]:
115
+ anno = self.table
116
+ span = (
117
+ select(models.Span.id, models.Span.span_id, num_docs_col(self._db.dialect))
118
+ .where(models.Span.span_id.in_({span_id for _, span_id, *_ in keys}))
119
+ .cte()
120
+ )
121
+ onclause = and_(
122
+ span.c.id == anno.span_rowid,
123
+ anno.name.in_({name for name, *_ in keys}),
124
+ tuple_(anno.name, span.c.span_id, anno.document_position).in_(keys),
125
+ )
126
+ return select(
127
+ span.c.id.label("span_rowid"),
128
+ span.c.span_id,
129
+ span.c.num_docs,
130
+ anno.id,
131
+ anno.name,
132
+ anno.document_position,
133
+ anno.updated_at,
134
+ ).outerjoin_from(span, anno, onclause)
135
+
136
+
137
+ class _SpanAttr(NamedTuple):
138
+ span_rowid: _SpanRowId
139
+ num_docs: _NumDocs
140
+
141
+
142
+ class _AnnoAttr(NamedTuple):
143
+ span_rowid: _SpanRowId
144
+ id_: _AnnoRowId
145
+ updated_at: datetime
146
+
147
+
148
+ def _key(p: Received[Precursors.DocumentAnnotation]) -> _Key:
149
+ return p.item.obj.name, p.item.span_id, p.item.document_position
150
+
151
+
152
+ def _unique_by(p: Received[Insertables.DocumentAnnotation]) -> _UniqueBy:
153
+ return p.item.obj.name, p.item.span_rowid, p.item.document_position
154
+
155
+
156
+ def _time(p: Received[Any]) -> datetime:
157
+ return p.received_at
@@ -20,6 +20,7 @@ from sqlalchemy.ext.asyncio import AsyncSession
20
20
  from sqlalchemy.sql.elements import KeyedColumnElement
21
21
  from typing_extensions import TypeAlias, assert_never
22
22
 
23
+ from phoenix.db import models
23
24
  from phoenix.db.helpers import SupportedSQLDialect
24
25
  from phoenix.db.models import Base
25
26
 
@@ -93,3 +94,15 @@ def _clean(
93
94
  yield "metadata", v
94
95
  else:
95
96
  yield k, v
97
+
98
+
99
+ def as_kv(obj: models.Base) -> Iterator[Tuple[str, Any]]:
100
+ for k, c in obj.__table__.c.items():
101
+ if k in ["created_at", "updated_at"]:
102
+ continue
103
+ k = "metadata_" if k == "metadata" else k
104
+ v = getattr(obj, k, None)
105
+ if c.primary_key and v is None:
106
+ # postgresql disallows None for primary key
107
+ continue
108
+ yield k, v