arize-phoenix 4.26.0__tar.gz → 4.28.1__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 (311) hide show
  1. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/PKG-INFO +2 -3
  2. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/pyproject.toml +1 -2
  3. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/auth.py +3 -0
  4. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/inferences/fixtures.py +14 -8
  5. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/context.py +10 -1
  6. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/mutations/__init__.py +4 -2
  7. arize_phoenix-4.28.1/src/phoenix/server/api/mutations/auth_mutations.py +63 -0
  8. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/routers/v1/experiments.py +55 -1
  9. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/routers/v1/utils.py +2 -2
  10. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/app.py +149 -29
  11. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/main.py +71 -7
  12. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/static/.vite/manifest.json +9 -9
  13. arize_phoenix-4.26.0/src/phoenix/server/static/assets/components-1Ahruijo.js → arize_phoenix-4.28.1/src/phoenix/server/static/assets/components-BYH03rjA.js +108 -100
  14. arize_phoenix-4.28.1/src/phoenix/server/static/assets/index-fqdjNpYm.js +100 -0
  15. arize_phoenix-4.26.0/src/phoenix/server/static/assets/pages-CFS6mPnW.js → arize_phoenix-4.28.1/src/phoenix/server/static/assets/pages-DnbxgoTK.js +271 -215
  16. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/session/client.py +17 -1
  17. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/trace/dsl/helpers.py +3 -1
  18. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/trace/fixtures.py +47 -4
  19. arize_phoenix-4.28.1/src/phoenix/version.py +1 -0
  20. arize_phoenix-4.26.0/src/phoenix/server/api/routers/auth.py +0 -52
  21. arize_phoenix-4.26.0/src/phoenix/server/static/assets/index-BEE_RWJx.js +0 -100
  22. arize_phoenix-4.26.0/src/phoenix/version.py +0 -1
  23. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/.gitignore +0 -0
  24. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/IP_NOTICE +0 -0
  25. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/LICENSE +0 -0
  26. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/README.md +0 -0
  27. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/examples/manually-instrumented-chatbot/chat-service/chat/__init__.py +0 -0
  28. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/examples/manually-instrumented-chatbot/chat-service/chat/app.py +0 -0
  29. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/examples/manually-instrumented-chatbot/chat-service/chat/types.py +0 -0
  30. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/examples/manually-instrumented-chatbot/frontend/Dockerfile +0 -0
  31. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/examples/manually-instrumented-chatbot/frontend/Makefile +0 -0
  32. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/examples/manually-instrumented-chatbot/frontend/__init__.py +0 -0
  33. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/examples/manually-instrumented-chatbot/frontend/pyproject.toml +0 -0
  34. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/examples/manually-instrumented-chatbot/frontend/requirements.txt +0 -0
  35. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/examples/manually-instrumented-chatbot/frontend/schema.json +0 -0
  36. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/__init__.py +0 -0
  37. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/config.py +0 -0
  38. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/core/__init__.py +0 -0
  39. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/core/embedding_dimension.py +0 -0
  40. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/core/model.py +0 -0
  41. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/core/model_schema.py +0 -0
  42. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/core/model_schema_adapter.py +0 -0
  43. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/datetime_utils.py +0 -0
  44. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/db/README.md +0 -0
  45. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/db/__init__.py +0 -0
  46. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/db/alembic.ini +0 -0
  47. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/db/bulk_inserter.py +0 -0
  48. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/db/engines.py +0 -0
  49. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/db/helpers.py +0 -0
  50. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/db/insertion/__init__.py +0 -0
  51. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/db/insertion/constants.py +0 -0
  52. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/db/insertion/dataset.py +0 -0
  53. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/db/insertion/document_annotation.py +0 -0
  54. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/db/insertion/evaluation.py +0 -0
  55. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/db/insertion/helpers.py +0 -0
  56. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/db/insertion/span.py +0 -0
  57. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/db/insertion/span_annotation.py +0 -0
  58. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/db/insertion/trace_annotation.py +0 -0
  59. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/db/insertion/types.py +0 -0
  60. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/db/migrate.py +0 -0
  61. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/db/migrations/__init__.py +0 -0
  62. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/db/migrations/env.py +0 -0
  63. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/db/migrations/future_versions/README.md +0 -0
  64. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/db/migrations/future_versions/cd164e83824f_users_and_tokens.py +0 -0
  65. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/db/migrations/script.py.mako +0 -0
  66. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/db/migrations/versions/.gitignore +0 -0
  67. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/db/migrations/versions/10460e46d750_datasets.py +0 -0
  68. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/db/migrations/versions/3be8647b87d8_add_token_columns_to_spans_table.py +0 -0
  69. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/db/migrations/versions/cf03bd6bae1d_init.py +0 -0
  70. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/db/models.py +0 -0
  71. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/exceptions.py +0 -0
  72. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/experiments/__init__.py +0 -0
  73. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/experiments/evaluators/__init__.py +0 -0
  74. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/experiments/evaluators/base.py +0 -0
  75. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/experiments/evaluators/code_evaluators.py +0 -0
  76. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/experiments/evaluators/llm_evaluators.py +0 -0
  77. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/experiments/evaluators/utils.py +0 -0
  78. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/experiments/functions.py +0 -0
  79. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/experiments/tracing.py +0 -0
  80. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/experiments/types.py +0 -0
  81. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/experiments/utils.py +0 -0
  82. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/inferences/__init__.py +0 -0
  83. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/inferences/errors.py +0 -0
  84. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/inferences/inferences.py +0 -0
  85. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/inferences/schema.py +0 -0
  86. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/inferences/validation.py +0 -0
  87. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/metrics/README.md +0 -0
  88. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/metrics/__init__.py +0 -0
  89. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/metrics/binning.py +0 -0
  90. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/metrics/metrics.py +0 -0
  91. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/metrics/mixins.py +0 -0
  92. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/metrics/retrieval_metrics.py +0 -0
  93. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/metrics/timeseries.py +0 -0
  94. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/metrics/wrappers.py +0 -0
  95. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/pointcloud/__init__.py +0 -0
  96. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/pointcloud/clustering.py +0 -0
  97. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/pointcloud/pointcloud.py +0 -0
  98. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/pointcloud/projectors.py +0 -0
  99. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/pointcloud/umap_parameters.py +0 -0
  100. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/py.typed +0 -0
  101. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/__init__.py +0 -0
  102. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/__init__.py +0 -0
  103. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/dataloaders/__init__.py +0 -0
  104. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/dataloaders/annotation_summaries.py +0 -0
  105. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/dataloaders/average_experiment_run_latency.py +0 -0
  106. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/dataloaders/cache/__init__.py +0 -0
  107. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/dataloaders/cache/two_tier_cache.py +0 -0
  108. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/dataloaders/dataset_example_revisions.py +0 -0
  109. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/dataloaders/dataset_example_spans.py +0 -0
  110. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/dataloaders/document_evaluation_summaries.py +0 -0
  111. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/dataloaders/document_evaluations.py +0 -0
  112. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/dataloaders/document_retrieval_metrics.py +0 -0
  113. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/dataloaders/experiment_annotation_summaries.py +0 -0
  114. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/dataloaders/experiment_error_rates.py +0 -0
  115. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/dataloaders/experiment_run_counts.py +0 -0
  116. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/dataloaders/experiment_sequence_number.py +0 -0
  117. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/dataloaders/latency_ms_quantile.py +0 -0
  118. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/dataloaders/min_start_or_max_end_times.py +0 -0
  119. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/dataloaders/project_by_name.py +0 -0
  120. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/dataloaders/record_counts.py +0 -0
  121. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/dataloaders/span_annotations.py +0 -0
  122. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/dataloaders/span_dataset_examples.py +0 -0
  123. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/dataloaders/span_descendants.py +0 -0
  124. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/dataloaders/span_projects.py +0 -0
  125. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/dataloaders/token_counts.py +0 -0
  126. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/dataloaders/trace_row_ids.py +0 -0
  127. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/helpers/__init__.py +0 -0
  128. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/helpers/dataset_helpers.py +0 -0
  129. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/input_types/AddExamplesToDatasetInput.py +0 -0
  130. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/input_types/AddSpansToDatasetInput.py +0 -0
  131. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/input_types/ClearProjectInput.py +0 -0
  132. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/input_types/ClusterInput.py +0 -0
  133. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/input_types/Coordinates.py +0 -0
  134. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/input_types/CreateDatasetInput.py +0 -0
  135. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/input_types/CreateSpanAnnotationInput.py +0 -0
  136. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/input_types/CreateTraceAnnotationInput.py +0 -0
  137. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/input_types/DataQualityMetricInput.py +0 -0
  138. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/input_types/DatasetExampleInput.py +0 -0
  139. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/input_types/DatasetSort.py +0 -0
  140. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/input_types/DatasetVersionSort.py +0 -0
  141. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/input_types/DeleteAnnotationsInput.py +0 -0
  142. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/input_types/DeleteDatasetExamplesInput.py +0 -0
  143. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/input_types/DeleteDatasetInput.py +0 -0
  144. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/input_types/DeleteExperimentsInput.py +0 -0
  145. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/input_types/DimensionFilter.py +0 -0
  146. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/input_types/DimensionInput.py +0 -0
  147. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/input_types/Granularity.py +0 -0
  148. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/input_types/PatchAnnotationInput.py +0 -0
  149. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/input_types/PatchDatasetExamplesInput.py +0 -0
  150. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/input_types/PatchDatasetInput.py +0 -0
  151. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/input_types/PerformanceMetricInput.py +0 -0
  152. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/input_types/SpanAnnotationSort.py +0 -0
  153. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/input_types/SpanSort.py +0 -0
  154. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/input_types/TimeRange.py +0 -0
  155. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/input_types/TraceAnnotationSort.py +0 -0
  156. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/input_types/UserRoleInput.py +0 -0
  157. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/input_types/__init__.py +0 -0
  158. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/interceptor.py +0 -0
  159. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/mutations/api_key_mutations.py +0 -0
  160. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/mutations/auth.py +0 -0
  161. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/mutations/dataset_mutations.py +0 -0
  162. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/mutations/experiment_mutations.py +0 -0
  163. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/mutations/export_events_mutations.py +0 -0
  164. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/mutations/project_mutations.py +0 -0
  165. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/mutations/span_annotations_mutations.py +0 -0
  166. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/mutations/trace_annotations_mutations.py +0 -0
  167. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/mutations/user_mutations.py +0 -0
  168. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/openapi/__init__.py +0 -0
  169. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/openapi/main.py +0 -0
  170. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/openapi/schema.py +0 -0
  171. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/queries.py +0 -0
  172. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/routers/__init__.py +0 -0
  173. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/routers/utils.py +0 -0
  174. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/routers/v1/__init__.py +0 -0
  175. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/routers/v1/datasets.py +0 -0
  176. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/routers/v1/evaluations.py +0 -0
  177. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/routers/v1/experiment_evaluations.py +0 -0
  178. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/routers/v1/experiment_runs.py +0 -0
  179. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/routers/v1/pydantic_compat.py +0 -0
  180. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/routers/v1/spans.py +0 -0
  181. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/routers/v1/traces.py +0 -0
  182. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/schema.py +0 -0
  183. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/Annotation.py +0 -0
  184. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/AnnotationSummary.py +0 -0
  185. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/AnnotatorKind.py +0 -0
  186. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/ApiKey.py +0 -0
  187. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/Cluster.py +0 -0
  188. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/CreateDatasetPayload.py +0 -0
  189. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/DataQualityMetric.py +0 -0
  190. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/Dataset.py +0 -0
  191. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/DatasetExample.py +0 -0
  192. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/DatasetExampleRevision.py +0 -0
  193. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/DatasetValues.py +0 -0
  194. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/DatasetVersion.py +0 -0
  195. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/Dimension.py +0 -0
  196. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/DimensionDataType.py +0 -0
  197. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/DimensionShape.py +0 -0
  198. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/DimensionType.py +0 -0
  199. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/DimensionWithValue.py +0 -0
  200. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/DocumentEvaluationSummary.py +0 -0
  201. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/DocumentRetrievalMetrics.py +0 -0
  202. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/EmbeddingDimension.py +0 -0
  203. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/EmbeddingMetadata.py +0 -0
  204. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/Evaluation.py +0 -0
  205. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/EvaluationSummary.py +0 -0
  206. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/Event.py +0 -0
  207. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/EventMetadata.py +0 -0
  208. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/ExampleRevisionInterface.py +0 -0
  209. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/Experiment.py +0 -0
  210. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/ExperimentAnnotationSummary.py +0 -0
  211. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/ExperimentComparison.py +0 -0
  212. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/ExperimentRun.py +0 -0
  213. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/ExperimentRunAnnotation.py +0 -0
  214. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/ExportedFile.py +0 -0
  215. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/Functionality.py +0 -0
  216. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/Inferences.py +0 -0
  217. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/InferencesRole.py +0 -0
  218. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/LabelFraction.py +0 -0
  219. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/MimeType.py +0 -0
  220. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/Model.py +0 -0
  221. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/NumericRange.py +0 -0
  222. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/PerformanceMetric.py +0 -0
  223. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/Project.py +0 -0
  224. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/PromptResponse.py +0 -0
  225. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/Retrieval.py +0 -0
  226. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/ScalarDriftMetricEnum.py +0 -0
  227. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/Segments.py +0 -0
  228. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/SortDir.py +0 -0
  229. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/Span.py +0 -0
  230. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/SpanAnnotation.py +0 -0
  231. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/SystemApiKey.py +0 -0
  232. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/TimeSeries.py +0 -0
  233. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/Trace.py +0 -0
  234. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/TraceAnnotation.py +0 -0
  235. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/UMAPPoints.py +0 -0
  236. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/User.py +0 -0
  237. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/UserApiKey.py +0 -0
  238. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/UserRole.py +0 -0
  239. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/ValidationResult.py +0 -0
  240. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/VectorDriftMetricEnum.py +0 -0
  241. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/__init__.py +0 -0
  242. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/node.py +0 -0
  243. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/types/pagination.py +0 -0
  244. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/api/utils.py +0 -0
  245. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/dml_event.py +0 -0
  246. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/dml_event_handler.py +0 -0
  247. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/grpc_server.py +0 -0
  248. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/openapi/__init__.py +0 -0
  249. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/prometheus.py +0 -0
  250. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/static/apple-touch-icon-114x114.png +0 -0
  251. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/static/apple-touch-icon-120x120.png +0 -0
  252. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/static/apple-touch-icon-144x144.png +0 -0
  253. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/static/apple-touch-icon-152x152.png +0 -0
  254. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/static/apple-touch-icon-180x180.png +0 -0
  255. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/static/apple-touch-icon-72x72.png +0 -0
  256. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/static/apple-touch-icon-76x76.png +0 -0
  257. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/static/apple-touch-icon.png +0 -0
  258. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/static/assets/vendor-DxkFTwjz.css +0 -0
  259. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/static/assets/vendor-aSQri0vz.js +0 -0
  260. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/static/assets/vendor-arizeai-CsdcB1NH.js +0 -0
  261. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/static/assets/vendor-codemirror-CYHkhs7D.js +0 -0
  262. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/static/assets/vendor-recharts-B0sannek.js +0 -0
  263. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/static/assets/vendor-three-DwGkEfCM.js +0 -0
  264. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/static/favicon.ico +0 -0
  265. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/static/modernizr.js +0 -0
  266. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/telemetry.py +0 -0
  267. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/templates/__init__.py +0 -0
  268. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/templates/index.html +0 -0
  269. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/thread_server.py +0 -0
  270. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/server/types.py +0 -0
  271. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/services.py +0 -0
  272. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/session/__init__.py +0 -0
  273. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/session/data_extractor.py +0 -0
  274. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/session/evaluation.py +0 -0
  275. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/session/session.py +0 -0
  276. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/settings.py +0 -0
  277. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/trace/__init__.py +0 -0
  278. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/trace/attributes.py +0 -0
  279. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/trace/dsl/README.md +0 -0
  280. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/trace/dsl/__init__.py +0 -0
  281. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/trace/dsl/filter.py +0 -0
  282. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/trace/dsl/query.py +0 -0
  283. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/trace/errors.py +0 -0
  284. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/trace/evaluation_conventions.py +0 -0
  285. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/trace/exporter.py +0 -0
  286. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/trace/langchain/__init__.py +0 -0
  287. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/trace/langchain/instrumentor.py +0 -0
  288. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/trace/llama_index/__init__.py +0 -0
  289. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/trace/llama_index/callback.py +0 -0
  290. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/trace/openai/__init__.py +0 -0
  291. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/trace/openai/instrumentor.py +0 -0
  292. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/trace/otel.py +0 -0
  293. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/trace/projects.py +0 -0
  294. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/trace/schemas.py +0 -0
  295. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/trace/span_evaluations.py +0 -0
  296. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/trace/span_json_decoder.py +0 -0
  297. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/trace/span_json_encoder.py +0 -0
  298. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/trace/trace_dataset.py +0 -0
  299. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/trace/utils.py +0 -0
  300. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/trace/v1/__init__.py +0 -0
  301. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/trace/v1/evaluation_pb2.py +0 -0
  302. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/trace/v1/evaluation_pb2.pyi +0 -0
  303. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/utilities/__init__.py +0 -0
  304. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/utilities/client.py +0 -0
  305. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/utilities/deprecation.py +0 -0
  306. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/utilities/error_handling.py +0 -0
  307. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/utilities/json.py +0 -0
  308. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/utilities/logging.py +0 -0
  309. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/utilities/project.py +0 -0
  310. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/src/phoenix/utilities/re.py +0 -0
  311. {arize_phoenix-4.26.0 → arize_phoenix-4.28.1}/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.26.0
3
+ Version: 4.28.1
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
@@ -45,8 +45,7 @@ Requires-Dist: pydantic!=2.0.*,<3,>=1.0
45
45
  Requires-Dist: pyjwt
46
46
  Requires-Dist: python-multipart
47
47
  Requires-Dist: scikit-learn
48
- Requires-Dist: scipy!=1.14.1; platform_system == 'Darwin'
49
- Requires-Dist: scipy; platform_system != 'Darwin'
48
+ Requires-Dist: scipy
50
49
  Requires-Dist: sqlalchemy[asyncio]<3,>=2.0.4
51
50
  Requires-Dist: sqlean-py>=3.45.1
52
51
  Requires-Dist: starlette
@@ -36,8 +36,7 @@ dependencies = [
36
36
  "typing-extensions>=4.5; python_version<'3.12'",
37
37
  # A minimum version of typing-extensions==4.6.0 is needed to avoid this issue on Python 3.12: https://github.com/Azure/azure-sdk-for-python/issues/33442#issuecomment-1847886784
38
38
  "typing-extensions>=4.6; python_version>='3.12'",
39
- "scipy!=1.14.1; platform_system == 'Darwin'", # MacOS installation issue: https://github.com/scipy/scipy/issues/21424
40
- "scipy; platform_system != 'Darwin'",
39
+ "scipy",
41
40
  "wrapt",
42
41
  "protobuf>=3.20, <6.0",
43
42
  "grpcio",
@@ -39,7 +39,10 @@ def validate_password_format(password: str) -> None:
39
39
  raise ValueError("Password cannot contain whitespace characters")
40
40
  if not password.isascii():
41
41
  raise ValueError("Password can contain only ASCII characters")
42
+ if not len(password) >= MIN_PASSWORD_LENGTH:
43
+ raise ValueError(f"Password must be at least {MIN_PASSWORD_LENGTH} characters long")
42
44
 
43
45
 
44
46
  EMAIL_PATTERN = re.compile(r"^[^@\s]+@[^@\s]+[.][^@\s]+\Z")
45
47
  NUM_ITERATIONS = 10_000
48
+ MIN_PASSWORD_LENGTH = 4
@@ -422,7 +422,7 @@ def get_inferences(
422
422
  Downloads primary and reference inferences for a fixture if they are not found
423
423
  locally.
424
424
  """
425
- fixture = _get_fixture_by_name(fixture_name=fixture_name)
425
+ fixture = get_fixture_by_name(fixture_name=fixture_name)
426
426
  if no_internet:
427
427
  paths = {role: INFERENCES_DIR / path for role, path in fixture.paths()}
428
428
  else:
@@ -436,9 +436,11 @@ def get_inferences(
436
436
  if fixture.reference_file_name is not None:
437
437
  reference_inferences = Inferences(
438
438
  read_parquet(paths[InferencesRole.REFERENCE]),
439
- fixture.reference_schema
440
- if fixture.reference_schema is not None
441
- else fixture.primary_schema,
439
+ (
440
+ fixture.reference_schema
441
+ if fixture.reference_schema is not None
442
+ else fixture.primary_schema
443
+ ),
442
444
  "training",
443
445
  )
444
446
  corpus_inferences = None
@@ -451,10 +453,14 @@ def get_inferences(
451
453
  return primary_inferences, reference_inferences, corpus_inferences
452
454
 
453
455
 
454
- def _get_fixture_by_name(fixture_name: str) -> Fixture:
456
+ def get_fixture_by_name(fixture_name: str) -> Fixture:
455
457
  """
456
- Returns the fixture whose name matches the input name. Raises a ValueError
457
- if the input fixture name does not match any known fixture names.
458
+ Returns the fixture whose name matches the input name.
459
+
460
+ Raises
461
+ ------
462
+ ValueError
463
+ if the input fixture name does not match any known fixture names.
458
464
  """
459
465
  if fixture_name not in NAME_TO_FIXTURE:
460
466
  valid_fixture_names = ", ".join(NAME_TO_FIXTURE.keys())
@@ -496,7 +502,7 @@ def load_example(use_case: str) -> ExampleInferences:
496
502
  reference).
497
503
 
498
504
  """
499
- fixture = _get_fixture_by_name(use_case)
505
+ fixture = get_fixture_by_name(use_case)
500
506
  primary_inferences, reference_inferences, corpus_inferences = get_inferences(use_case)
501
507
  print(f"📥 Loaded {use_case} example datasets.")
502
508
  print("ℹ️ About this use-case:")
@@ -2,6 +2,7 @@ from dataclasses import dataclass
2
2
  from pathlib import Path
3
3
  from typing import Any, Optional
4
4
 
5
+ from starlette.responses import Response as StarletteResponse
5
6
  from strawberry.fastapi import BaseContext
6
7
 
7
8
  from phoenix.core.model_schema import Model
@@ -77,7 +78,7 @@ class Context(BaseContext):
77
78
  secret: Optional[str] = None
78
79
 
79
80
  def get_secret(self) -> str:
80
- """A type safe way to get the application secret. Throws an error if the secret is not set.
81
+ """A type-safe way to get the application secret. Throws an error if the secret is not set.
81
82
 
82
83
  Returns:
83
84
  str: the phoenix secret
@@ -88,3 +89,11 @@ class Context(BaseContext):
88
89
  " Please set the PHOENIX_SECRET environment variable and re-deploy the application."
89
90
  )
90
91
  return self.secret
92
+
93
+ def get_response(self) -> StarletteResponse:
94
+ """
95
+ A type-safe way to get the response object. Throws an error if the response is not set.
96
+ """
97
+ if (response := self.response) is None:
98
+ raise ValueError("no response is set")
99
+ return response
@@ -1,6 +1,7 @@
1
1
  import strawberry
2
2
 
3
3
  from phoenix.server.api.mutations.api_key_mutations import ApiKeyMutationMixin
4
+ from phoenix.server.api.mutations.auth_mutations import AuthMutationMixin
4
5
  from phoenix.server.api.mutations.dataset_mutations import DatasetMutationMixin
5
6
  from phoenix.server.api.mutations.experiment_mutations import ExperimentMutationMixin
6
7
  from phoenix.server.api.mutations.export_events_mutations import ExportEventsMutationMixin
@@ -12,13 +13,14 @@ from phoenix.server.api.mutations.user_mutations import UserMutationMixin
12
13
 
13
14
  @strawberry.type
14
15
  class Mutation(
15
- ProjectMutationMixin,
16
+ ApiKeyMutationMixin,
17
+ AuthMutationMixin,
16
18
  DatasetMutationMixin,
17
19
  ExperimentMutationMixin,
18
20
  ExportEventsMutationMixin,
21
+ ProjectMutationMixin,
19
22
  SpanAnnotationMutationMixin,
20
23
  TraceAnnotationMutationMixin,
21
- ApiKeyMutationMixin,
22
24
  UserMutationMixin,
23
25
  ):
24
26
  pass
@@ -0,0 +1,63 @@
1
+ import asyncio
2
+ from datetime import timedelta
3
+
4
+ import strawberry
5
+ from sqlalchemy import select
6
+ from strawberry.types import Info
7
+
8
+ from phoenix.auth import is_valid_password
9
+ from phoenix.db import models
10
+ from phoenix.server.api.context import Context
11
+ from phoenix.server.api.mutations.auth import HasSecret
12
+
13
+ PHOENIX_ACCESS_TOKEN_COOKIE_NAME = "phoenix-access-token"
14
+ PHOENIX_ACCESS_TOKEN_COOKIE_MAX_AGE_IN_SECONDS = int(timedelta(days=31).total_seconds())
15
+
16
+
17
+ @strawberry.input
18
+ class LoginMutationInput:
19
+ email: str
20
+ password: str
21
+
22
+
23
+ @strawberry.type
24
+ class AuthMutationMixin:
25
+ @strawberry.mutation(permission_classes=[HasSecret]) # type: ignore
26
+ async def login(
27
+ self,
28
+ info: Info[Context, None],
29
+ input: LoginMutationInput,
30
+ ) -> None:
31
+ async with info.context.db() as session:
32
+ if (
33
+ user := await session.scalar(
34
+ select(models.User).where(models.User.email == input.email)
35
+ )
36
+ ) is None or (password_hash := user.password_hash) is None:
37
+ raise ValueError
38
+ secret = info.context.get_secret()
39
+ loop = asyncio.get_running_loop()
40
+ if not await loop.run_in_executor(
41
+ executor=None,
42
+ func=lambda: is_valid_password(
43
+ password=input.password, salt=secret, password_hash=password_hash
44
+ ),
45
+ ):
46
+ raise ValueError
47
+ response = info.context.get_response()
48
+ response.set_cookie(
49
+ key=PHOENIX_ACCESS_TOKEN_COOKIE_NAME,
50
+ value="token", # todo: compute access token
51
+ secure=True,
52
+ httponly=True,
53
+ samesite="strict",
54
+ max_age=PHOENIX_ACCESS_TOKEN_COOKIE_MAX_AGE_IN_SECONDS,
55
+ )
56
+
57
+ @strawberry.mutation(permission_classes=[HasSecret]) # type: ignore
58
+ async def logout(
59
+ self,
60
+ info: Info[Context, None],
61
+ ) -> None:
62
+ response = info.context.get_response()
63
+ response.delete_cookie(key=PHOENIX_ACCESS_TOKEN_COOKIE_NAME)
@@ -1,6 +1,6 @@
1
1
  from datetime import datetime
2
2
  from random import getrandbits
3
- from typing import Any, Dict, Optional
3
+ from typing import Any, Dict, List, Optional
4
4
 
5
5
  from fastapi import APIRouter, HTTPException
6
6
  from pydantic import Field
@@ -252,3 +252,57 @@ async def get_experiment(request: Request, experiment_id: str) -> GetExperimentR
252
252
  updated_at=experiment.updated_at,
253
253
  )
254
254
  )
255
+
256
+
257
+ class ListExperimentsResponseBody(ResponseBody[List[Experiment]]):
258
+ pass
259
+
260
+
261
+ @router.get(
262
+ "/datasets/{dataset_id}/experiments",
263
+ operation_id="listExperiments",
264
+ summary="List experiments by dataset",
265
+ response_description="Experiments retrieved successfully",
266
+ )
267
+ async def list_experiments(
268
+ request: Request,
269
+ dataset_id: str,
270
+ ) -> ListExperimentsResponseBody:
271
+ dataset_gid = GlobalID.from_id(dataset_id)
272
+ try:
273
+ dataset_rowid = from_global_id_with_expected_type(dataset_gid, "Dataset")
274
+ except ValueError:
275
+ raise HTTPException(
276
+ detail=f"Dataset with ID {dataset_gid} does not exist",
277
+ status_code=HTTP_404_NOT_FOUND,
278
+ )
279
+ async with request.app.state.db() as session:
280
+ query = (
281
+ select(models.Experiment)
282
+ .where(models.Experiment.dataset_id == dataset_rowid)
283
+ .order_by(models.Experiment.id.desc())
284
+ )
285
+
286
+ result = await session.execute(query)
287
+ experiments = result.scalars().all()
288
+
289
+ if not experiments:
290
+ return ListExperimentsResponseBody(data=[])
291
+
292
+ data = [
293
+ Experiment(
294
+ id=str(GlobalID("Experiment", str(experiment.id))),
295
+ dataset_id=str(GlobalID("Dataset", str(experiment.dataset_id))),
296
+ dataset_version_id=str(
297
+ GlobalID("DatasetVersion", str(experiment.dataset_version_id))
298
+ ),
299
+ repetitions=experiment.repetitions,
300
+ metadata=experiment.metadata_,
301
+ project_name=None,
302
+ created_at=experiment.created_at,
303
+ updated_at=experiment.updated_at,
304
+ )
305
+ for experiment in experiments
306
+ ]
307
+
308
+ return ListExperimentsResponseBody(data=data)
@@ -1,6 +1,6 @@
1
- from typing import Any, Dict, Generic, List, Optional, TypedDict, Union
1
+ from typing import Any, Dict, Generic, List, Optional, TypedDict, TypeVar, Union
2
2
 
3
- from typing_extensions import TypeAlias, TypeVar, assert_never
3
+ from typing_extensions import TypeAlias, assert_never
4
4
 
5
5
  from .pydantic_compat import V1RoutesBaseModel
6
6
 
@@ -2,6 +2,7 @@ import asyncio
2
2
  import contextlib
3
3
  import json
4
4
  import logging
5
+ from datetime import datetime, timedelta, timezone
5
6
  from functools import cached_property
6
7
  from pathlib import Path
7
8
  from types import MethodType
@@ -10,12 +11,14 @@ from typing import (
10
11
  Any,
11
12
  AsyncContextManager,
12
13
  AsyncIterator,
14
+ Awaitable,
13
15
  Callable,
14
16
  Dict,
15
17
  Iterable,
16
18
  List,
17
19
  NamedTuple,
18
20
  Optional,
21
+ Set,
19
22
  Tuple,
20
23
  Union,
21
24
  cast,
@@ -26,11 +29,8 @@ from fastapi import APIRouter, FastAPI
26
29
  from fastapi.middleware.gzip import GZipMiddleware
27
30
  from fastapi.responses import FileResponse
28
31
  from fastapi.utils import is_body_allowed_for_status_code
29
- from sqlalchemy.ext.asyncio import (
30
- AsyncEngine,
31
- AsyncSession,
32
- async_sessionmaker,
33
- )
32
+ from sqlalchemy import select
33
+ from sqlalchemy.ext.asyncio import AsyncEngine, AsyncSession, async_sessionmaker
34
34
  from starlette.datastructures import State as StarletteState
35
35
  from starlette.exceptions import HTTPException
36
36
  from starlette.middleware import Middleware
@@ -46,12 +46,9 @@ from typing_extensions import TypeAlias
46
46
 
47
47
  import phoenix
48
48
  import phoenix.trace.v1 as pb
49
- from phoenix.config import (
50
- DEFAULT_PROJECT_NAME,
51
- SERVER_DIR,
52
- server_instrumentation_is_enabled,
53
- )
49
+ from phoenix.config import DEFAULT_PROJECT_NAME, SERVER_DIR, server_instrumentation_is_enabled
54
50
  from phoenix.core.model_schema import Model
51
+ from phoenix.db import models
55
52
  from phoenix.db.bulk_inserter import BulkInserter
56
53
  from phoenix.db.engines import create_engine
57
54
  from phoenix.db.helpers import SupportedSQLDialect
@@ -82,7 +79,6 @@ from phoenix.server.api.dataloaders import (
82
79
  TokenCountDataLoader,
83
80
  TraceRowIdsDataLoader,
84
81
  )
85
- from phoenix.server.api.routers.auth import router as auth_router
86
82
  from phoenix.server.api.routers.v1 import REST_API_VERSION
87
83
  from phoenix.server.api.routers.v1 import router as v1_router
88
84
  from phoenix.server.api.schema import schema
@@ -93,9 +89,17 @@ from phoenix.server.telemetry import initialize_opentelemetry_tracer_provider
93
89
  from phoenix.server.types import (
94
90
  CanGetLastUpdatedAt,
95
91
  CanPutItem,
92
+ DaemonTask,
96
93
  DbSessionFactory,
97
94
  LastUpdatedAt,
98
95
  )
96
+ from phoenix.trace.fixtures import (
97
+ get_evals_from_fixture,
98
+ get_trace_fixture_by_name,
99
+ load_example_traces,
100
+ reset_fixture_span_ids_and_timestamps,
101
+ )
102
+ from phoenix.trace.otel import decode_otlp_span, encode_span_to_otlp
99
103
  from phoenix.trace.schemas import Span
100
104
  from phoenix.utilities.client import PHOENIX_SERVER_VERSION_HEADER
101
105
 
@@ -103,12 +107,23 @@ if TYPE_CHECKING:
103
107
  from opentelemetry.trace import TracerProvider
104
108
 
105
109
  logger = logging.getLogger(__name__)
110
+ logger.setLevel(logging.INFO)
106
111
  logger.addHandler(logging.NullHandler())
107
112
 
108
113
  router = APIRouter(include_in_schema=False)
109
114
 
110
115
  templates = Jinja2Templates(directory=SERVER_DIR / "templates")
111
116
 
117
+ """
118
+ Threshold (in minutes) to determine if database is booted up for the first time.
119
+
120
+ Used to assess whether the `default` project was created recently.
121
+ If so, demo data is automatically ingested upon initial boot up to populate the database.
122
+ """
123
+ NEW_DB_AGE_THRESHOLD_MINUTES = 2
124
+
125
+ ProjectName: TypeAlias = str
126
+
112
127
 
113
128
  class AppConfig(NamedTuple):
114
129
  has_inferences: bool
@@ -226,9 +241,99 @@ def _db(engine: AsyncEngine) -> Callable[[], AsyncContextManager[AsyncSession]]:
226
241
  return factory
227
242
 
228
243
 
244
+ class Scaffolder(DaemonTask):
245
+ def __init__(
246
+ self,
247
+ db: DbSessionFactory,
248
+ queue_span: Callable[[Span, ProjectName], Awaitable[None]],
249
+ queue_evaluation: Callable[[pb.Evaluation], Awaitable[None]],
250
+ tracing_fixture_names: Set[str] = set(),
251
+ force_fixture_ingestion: bool = False,
252
+ ) -> None:
253
+ super().__init__()
254
+ self._db = db
255
+ self._queue_span = queue_span
256
+ self._queue_evaluation = queue_evaluation
257
+ self._tracing_fixtures = set(
258
+ get_trace_fixture_by_name(name) for name in tracing_fixture_names
259
+ )
260
+ self._force_fixture_ingestion = force_fixture_ingestion
261
+
262
+ async def __aenter__(self) -> None:
263
+ await self.start()
264
+
265
+ async def __aexit__(self, *args: Any, **kwargs: Any) -> None:
266
+ await self.stop()
267
+
268
+ async def _run(self) -> None:
269
+ """
270
+ Main entry point for Scaffolder.
271
+ Determines whether to load fixtures and handles them.
272
+ """
273
+ if await self._should_load_fixtures():
274
+ logger.info("Loading trace fixtures.")
275
+ await self._handle_tracing_fixtures()
276
+ logger.info("Finished loading fixtures.")
277
+ else:
278
+ logger.info("DB is not new, avoid loading demo fixtures.")
279
+
280
+ async def _should_load_fixtures(self) -> bool:
281
+ if self._force_fixture_ingestion:
282
+ return True
283
+
284
+ async with self._db() as session:
285
+ created_at = await session.scalar(
286
+ select(models.Project.created_at).where(models.Project.name == "default")
287
+ )
288
+ if created_at is None:
289
+ return False
290
+
291
+ is_new_db = datetime.now(timezone.utc) - created_at < timedelta(
292
+ minutes=NEW_DB_AGE_THRESHOLD_MINUTES
293
+ )
294
+ return is_new_db
295
+
296
+ async def _handle_tracing_fixtures(self) -> None:
297
+ """
298
+ Main handler for processing trace fixtures. Process each fixture by
299
+ loading its trace dataframe, gettting and processings its
300
+ spans and evals, and queuing.
301
+ """
302
+ loop = asyncio.get_running_loop()
303
+ for fixture in self._tracing_fixtures:
304
+ try:
305
+ trace_ds = await loop.run_in_executor(None, load_example_traces, fixture.name)
306
+
307
+ fixture_spans, fixture_evals = await loop.run_in_executor(
308
+ None,
309
+ reset_fixture_span_ids_and_timestamps,
310
+ (
311
+ # Apply `encode` here because legacy jsonl files contains UUIDs as strings.
312
+ # `encode` removes the hyphens in the UUIDs.
313
+ decode_otlp_span(encode_span_to_otlp(span))
314
+ for span in trace_ds.to_spans()
315
+ ),
316
+ get_evals_from_fixture(fixture.name),
317
+ )
318
+
319
+ project_name = fixture.project_name or fixture.name
320
+ logger.info(f"Loading '{project_name}' fixtures...")
321
+ for span in fixture_spans:
322
+ await self._queue_span(span, project_name)
323
+ for evaluation in fixture_evals:
324
+ await self._queue_evaluation(evaluation)
325
+
326
+ except FileNotFoundError:
327
+ logger.warning(f"Fixture file not found for '{fixture.name}'")
328
+ except ValueError as e:
329
+ logger.error(f"Error processing fixture '{fixture.name}': {e}")
330
+ except Exception as e:
331
+ logger.error(f"Unexpected error processing fixture '{fixture.name}': {e}")
332
+
333
+
229
334
  def _lifespan(
230
335
  *,
231
- dialect: SupportedSQLDialect,
336
+ db: DbSessionFactory,
232
337
  bulk_inserter: BulkInserter,
233
338
  dml_event_handler: DmlEventHandler,
234
339
  tracer_provider: Optional["TracerProvider"] = None,
@@ -236,11 +341,13 @@ def _lifespan(
236
341
  startup_callbacks: Iterable[Callable[[], None]] = (),
237
342
  shutdown_callbacks: Iterable[Callable[[], None]] = (),
238
343
  read_only: bool = False,
344
+ tracing_fixture_names: Set[str] = set(),
345
+ force_fixture_ingestion: bool = False,
239
346
  ) -> StatefulLifespan[FastAPI]:
240
347
  @contextlib.asynccontextmanager
241
348
  async def lifespan(_: FastAPI) -> AsyncIterator[Dict[str, Any]]:
242
349
  global DB_MUTEX
243
- DB_MUTEX = asyncio.Lock() if dialect is SupportedSQLDialect.SQLITE else None
350
+ DB_MUTEX = asyncio.Lock() if db.dialect is SupportedSQLDialect.SQLITE else None
244
351
  async with bulk_inserter as (
245
352
  enqueue,
246
353
  queue_span,
@@ -251,7 +358,13 @@ def _lifespan(
251
358
  disabled=read_only,
252
359
  tracer_provider=tracer_provider,
253
360
  enable_prometheus=enable_prometheus,
254
- ), dml_event_handler:
361
+ ), dml_event_handler, Scaffolder(
362
+ db=db,
363
+ queue_span=queue_span,
364
+ queue_evaluation=queue_evaluation,
365
+ tracing_fixture_names=tracing_fixture_names,
366
+ force_fixture_ingestion=force_fixture_ingestion,
367
+ ):
255
368
  for callback in startup_callbacks:
256
369
  callback()
257
370
  yield {
@@ -317,17 +430,19 @@ def create_graphql_router(
317
430
  dataset_example_spans=DatasetExampleSpansDataLoader(db),
318
431
  document_evaluation_summaries=DocumentEvaluationSummaryDataLoader(
319
432
  db,
320
- cache_map=cache_for_dataloaders.document_evaluation_summary
321
- if cache_for_dataloaders
322
- else None,
433
+ cache_map=(
434
+ cache_for_dataloaders.document_evaluation_summary
435
+ if cache_for_dataloaders
436
+ else None
437
+ ),
323
438
  ),
324
439
  document_evaluations=DocumentEvaluationsDataLoader(db),
325
440
  document_retrieval_metrics=DocumentRetrievalMetricsDataLoader(db),
326
441
  annotation_summaries=AnnotationSummaryDataLoader(
327
442
  db,
328
- cache_map=cache_for_dataloaders.annotation_summary
329
- if cache_for_dataloaders
330
- else None,
443
+ cache_map=(
444
+ cache_for_dataloaders.annotation_summary if cache_for_dataloaders else None
445
+ ),
331
446
  ),
332
447
  experiment_annotation_summaries=ExperimentAnnotationSummaryDataLoader(db),
333
448
  experiment_error_rates=ExperimentErrorRatesDataLoader(db),
@@ -335,15 +450,17 @@ def create_graphql_router(
335
450
  experiment_sequence_number=ExperimentSequenceNumberDataLoader(db),
336
451
  latency_ms_quantile=LatencyMsQuantileDataLoader(
337
452
  db,
338
- cache_map=cache_for_dataloaders.latency_ms_quantile
339
- if cache_for_dataloaders
340
- else None,
453
+ cache_map=(
454
+ cache_for_dataloaders.latency_ms_quantile if cache_for_dataloaders else None
455
+ ),
341
456
  ),
342
457
  min_start_or_max_end_times=MinStartOrMaxEndTimeDataLoader(
343
458
  db,
344
- cache_map=cache_for_dataloaders.min_start_or_max_end_time
345
- if cache_for_dataloaders
346
- else None,
459
+ cache_map=(
460
+ cache_for_dataloaders.min_start_or_max_end_time
461
+ if cache_for_dataloaders
462
+ else None
463
+ ),
347
464
  ),
348
465
  record_counts=RecordCountDataLoader(
349
466
  db,
@@ -438,6 +555,8 @@ def create_app(
438
555
  startup_callbacks: Iterable[Callable[[], None]] = (),
439
556
  shutdown_callbacks: Iterable[Callable[[], None]] = (),
440
557
  secret: Optional[str] = None,
558
+ tracing_fixture_names: Set[str] = set(),
559
+ force_fixture_ingestion: bool = False,
441
560
  ) -> FastAPI:
442
561
  startup_callbacks_list: List[Callable[[], None]] = list(startup_callbacks)
443
562
  shutdown_callbacks_list: List[Callable[[], None]] = list(shutdown_callbacks)
@@ -510,11 +629,12 @@ def create_app(
510
629
  prometheus_middlewares = [Middleware(PrometheusMiddleware)]
511
630
  else:
512
631
  prometheus_middlewares = []
632
+
513
633
  app = FastAPI(
514
634
  title="Arize-Phoenix REST API",
515
635
  version=REST_API_VERSION,
516
636
  lifespan=_lifespan(
517
- dialect=db.dialect,
637
+ db=db,
518
638
  read_only=read_only,
519
639
  bulk_inserter=bulk_inserter,
520
640
  dml_event_handler=dml_event_handler,
@@ -522,6 +642,8 @@ def create_app(
522
642
  enable_prometheus=enable_prometheus,
523
643
  shutdown_callbacks=shutdown_callbacks_list,
524
644
  startup_callbacks=startup_callbacks_list,
645
+ tracing_fixture_names=tracing_fixture_names,
646
+ force_fixture_ingestion=force_fixture_ingestion,
525
647
  ),
526
648
  middleware=[
527
649
  Middleware(HeadersMiddleware),
@@ -539,8 +661,6 @@ def create_app(
539
661
  app.include_router(router)
540
662
  app.include_router(graphql_router)
541
663
  app.add_middleware(GZipMiddleware)
542
- if authentication_enabled:
543
- app.include_router(auth_router)
544
664
  if serve_ui:
545
665
  app.mount(
546
666
  "/",