arize-phoenix 4.25.0__tar.gz → 4.27.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 (312) hide show
  1. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/PKG-INFO +4 -4
  2. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/pyproject.toml +4 -4
  3. arize_phoenix-4.27.0/src/phoenix/auth.py +45 -0
  4. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/db/engines.py +1 -1
  5. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/inferences/fixtures.py +14 -8
  6. arize_phoenix-4.27.0/src/phoenix/server/api/input_types/UserRoleInput.py +9 -0
  7. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/mutations/__init__.py +2 -0
  8. arize_phoenix-4.27.0/src/phoenix/server/api/mutations/user_mutations.py +89 -0
  9. arize_phoenix-4.27.0/src/phoenix/server/api/routers/auth.py +52 -0
  10. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/routers/v1/experiments.py +55 -1
  11. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/routers/v1/utils.py +2 -2
  12. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/app.py +174 -28
  13. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/main.py +71 -7
  14. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/static/.vite/manifest.json +9 -9
  15. arize_phoenix-4.25.0/src/phoenix/server/static/assets/components-1Ahruijo.js → arize_phoenix-4.27.0/src/phoenix/server/static/assets/components-1MfQimGx.js +3 -3
  16. arize_phoenix-4.27.0/src/phoenix/server/static/assets/index-B263sE2x.js +100 -0
  17. arize_phoenix-4.25.0/src/phoenix/server/static/assets/pages-CFS6mPnW.js → arize_phoenix-4.27.0/src/phoenix/server/static/assets/pages-CqZDVx20.js +180 -171
  18. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/session/client.py +17 -1
  19. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/trace/dsl/helpers.py +3 -1
  20. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/trace/fixtures.py +47 -4
  21. arize_phoenix-4.27.0/src/phoenix/version.py +1 -0
  22. arize_phoenix-4.25.0/src/phoenix/auth/utils.py +0 -15
  23. arize_phoenix-4.25.0/src/phoenix/server/static/assets/index-BEE_RWJx.js +0 -100
  24. arize_phoenix-4.25.0/src/phoenix/utilities/__init__.py +0 -0
  25. arize_phoenix-4.25.0/src/phoenix/version.py +0 -1
  26. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/.gitignore +0 -0
  27. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/IP_NOTICE +0 -0
  28. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/LICENSE +0 -0
  29. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/README.md +0 -0
  30. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/examples/manually-instrumented-chatbot/chat-service/chat/__init__.py +0 -0
  31. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/examples/manually-instrumented-chatbot/chat-service/chat/app.py +0 -0
  32. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/examples/manually-instrumented-chatbot/chat-service/chat/types.py +0 -0
  33. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/examples/manually-instrumented-chatbot/frontend/Dockerfile +0 -0
  34. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/examples/manually-instrumented-chatbot/frontend/Makefile +0 -0
  35. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/examples/manually-instrumented-chatbot/frontend/__init__.py +0 -0
  36. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/examples/manually-instrumented-chatbot/frontend/pyproject.toml +0 -0
  37. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/examples/manually-instrumented-chatbot/frontend/requirements.txt +0 -0
  38. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/examples/manually-instrumented-chatbot/frontend/schema.json +0 -0
  39. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/__init__.py +0 -0
  40. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/config.py +0 -0
  41. {arize_phoenix-4.25.0/src/phoenix/auth → arize_phoenix-4.27.0/src/phoenix/core}/__init__.py +0 -0
  42. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/core/embedding_dimension.py +0 -0
  43. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/core/model.py +0 -0
  44. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/core/model_schema.py +0 -0
  45. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/core/model_schema_adapter.py +0 -0
  46. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/datetime_utils.py +0 -0
  47. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/db/README.md +0 -0
  48. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/db/__init__.py +0 -0
  49. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/db/alembic.ini +0 -0
  50. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/db/bulk_inserter.py +0 -0
  51. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/db/helpers.py +0 -0
  52. {arize_phoenix-4.25.0/src/phoenix/core → arize_phoenix-4.27.0/src/phoenix/db/insertion}/__init__.py +0 -0
  53. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/db/insertion/constants.py +0 -0
  54. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/db/insertion/dataset.py +0 -0
  55. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/db/insertion/document_annotation.py +0 -0
  56. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/db/insertion/evaluation.py +0 -0
  57. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/db/insertion/helpers.py +0 -0
  58. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/db/insertion/span.py +0 -0
  59. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/db/insertion/span_annotation.py +0 -0
  60. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/db/insertion/trace_annotation.py +0 -0
  61. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/db/insertion/types.py +0 -0
  62. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/db/migrate.py +0 -0
  63. {arize_phoenix-4.25.0/src/phoenix/db/insertion → arize_phoenix-4.27.0/src/phoenix/db/migrations}/__init__.py +0 -0
  64. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/db/migrations/env.py +0 -0
  65. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/db/migrations/future_versions/README.md +0 -0
  66. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/db/migrations/future_versions/cd164e83824f_users_and_tokens.py +0 -0
  67. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/db/migrations/script.py.mako +0 -0
  68. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/db/migrations/versions/.gitignore +0 -0
  69. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/db/migrations/versions/10460e46d750_datasets.py +0 -0
  70. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/db/migrations/versions/3be8647b87d8_add_token_columns_to_spans_table.py +0 -0
  71. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/db/migrations/versions/cf03bd6bae1d_init.py +0 -0
  72. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/db/models.py +0 -0
  73. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/exceptions.py +0 -0
  74. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/experiments/__init__.py +0 -0
  75. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/experiments/evaluators/__init__.py +0 -0
  76. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/experiments/evaluators/base.py +0 -0
  77. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/experiments/evaluators/code_evaluators.py +0 -0
  78. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/experiments/evaluators/llm_evaluators.py +0 -0
  79. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/experiments/evaluators/utils.py +0 -0
  80. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/experiments/functions.py +0 -0
  81. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/experiments/tracing.py +0 -0
  82. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/experiments/types.py +0 -0
  83. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/experiments/utils.py +0 -0
  84. {arize_phoenix-4.25.0/src/phoenix/db/migrations → arize_phoenix-4.27.0/src/phoenix/inferences}/__init__.py +0 -0
  85. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/inferences/errors.py +0 -0
  86. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/inferences/inferences.py +0 -0
  87. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/inferences/schema.py +0 -0
  88. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/inferences/validation.py +0 -0
  89. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/metrics/README.md +0 -0
  90. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/metrics/__init__.py +0 -0
  91. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/metrics/binning.py +0 -0
  92. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/metrics/metrics.py +0 -0
  93. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/metrics/mixins.py +0 -0
  94. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/metrics/retrieval_metrics.py +0 -0
  95. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/metrics/timeseries.py +0 -0
  96. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/metrics/wrappers.py +0 -0
  97. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/pointcloud/__init__.py +0 -0
  98. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/pointcloud/clustering.py +0 -0
  99. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/pointcloud/pointcloud.py +0 -0
  100. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/pointcloud/projectors.py +0 -0
  101. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/pointcloud/umap_parameters.py +0 -0
  102. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/py.typed +0 -0
  103. {arize_phoenix-4.25.0/src/phoenix/inferences → arize_phoenix-4.27.0/src/phoenix/server}/__init__.py +0 -0
  104. {arize_phoenix-4.25.0/src/phoenix/server → arize_phoenix-4.27.0/src/phoenix/server/api}/__init__.py +0 -0
  105. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/context.py +0 -0
  106. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/dataloaders/__init__.py +0 -0
  107. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/dataloaders/annotation_summaries.py +0 -0
  108. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/dataloaders/average_experiment_run_latency.py +0 -0
  109. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/dataloaders/cache/__init__.py +0 -0
  110. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/dataloaders/cache/two_tier_cache.py +0 -0
  111. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/dataloaders/dataset_example_revisions.py +0 -0
  112. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/dataloaders/dataset_example_spans.py +0 -0
  113. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/dataloaders/document_evaluation_summaries.py +0 -0
  114. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/dataloaders/document_evaluations.py +0 -0
  115. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/dataloaders/document_retrieval_metrics.py +0 -0
  116. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/dataloaders/experiment_annotation_summaries.py +0 -0
  117. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/dataloaders/experiment_error_rates.py +0 -0
  118. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/dataloaders/experiment_run_counts.py +0 -0
  119. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/dataloaders/experiment_sequence_number.py +0 -0
  120. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/dataloaders/latency_ms_quantile.py +0 -0
  121. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/dataloaders/min_start_or_max_end_times.py +0 -0
  122. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/dataloaders/project_by_name.py +0 -0
  123. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/dataloaders/record_counts.py +0 -0
  124. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/dataloaders/span_annotations.py +0 -0
  125. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/dataloaders/span_dataset_examples.py +0 -0
  126. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/dataloaders/span_descendants.py +0 -0
  127. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/dataloaders/span_projects.py +0 -0
  128. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/dataloaders/token_counts.py +0 -0
  129. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/dataloaders/trace_row_ids.py +0 -0
  130. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/helpers/__init__.py +0 -0
  131. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/helpers/dataset_helpers.py +0 -0
  132. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/input_types/AddExamplesToDatasetInput.py +0 -0
  133. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/input_types/AddSpansToDatasetInput.py +0 -0
  134. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/input_types/ClearProjectInput.py +0 -0
  135. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/input_types/ClusterInput.py +0 -0
  136. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/input_types/Coordinates.py +0 -0
  137. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/input_types/CreateDatasetInput.py +0 -0
  138. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/input_types/CreateSpanAnnotationInput.py +0 -0
  139. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/input_types/CreateTraceAnnotationInput.py +0 -0
  140. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/input_types/DataQualityMetricInput.py +0 -0
  141. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/input_types/DatasetExampleInput.py +0 -0
  142. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/input_types/DatasetSort.py +0 -0
  143. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/input_types/DatasetVersionSort.py +0 -0
  144. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/input_types/DeleteAnnotationsInput.py +0 -0
  145. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/input_types/DeleteDatasetExamplesInput.py +0 -0
  146. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/input_types/DeleteDatasetInput.py +0 -0
  147. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/input_types/DeleteExperimentsInput.py +0 -0
  148. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/input_types/DimensionFilter.py +0 -0
  149. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/input_types/DimensionInput.py +0 -0
  150. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/input_types/Granularity.py +0 -0
  151. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/input_types/PatchAnnotationInput.py +0 -0
  152. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/input_types/PatchDatasetExamplesInput.py +0 -0
  153. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/input_types/PatchDatasetInput.py +0 -0
  154. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/input_types/PerformanceMetricInput.py +0 -0
  155. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/input_types/SpanAnnotationSort.py +0 -0
  156. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/input_types/SpanSort.py +0 -0
  157. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/input_types/TimeRange.py +0 -0
  158. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/input_types/TraceAnnotationSort.py +0 -0
  159. {arize_phoenix-4.25.0/src/phoenix/server/api → arize_phoenix-4.27.0/src/phoenix/server/api/input_types}/__init__.py +0 -0
  160. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/interceptor.py +0 -0
  161. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/mutations/api_key_mutations.py +0 -0
  162. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/mutations/auth.py +0 -0
  163. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/mutations/dataset_mutations.py +0 -0
  164. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/mutations/experiment_mutations.py +0 -0
  165. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/mutations/export_events_mutations.py +0 -0
  166. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/mutations/project_mutations.py +0 -0
  167. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/mutations/span_annotations_mutations.py +0 -0
  168. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/mutations/trace_annotations_mutations.py +0 -0
  169. {arize_phoenix-4.25.0/src/phoenix/server/api/input_types → arize_phoenix-4.27.0/src/phoenix/server/api/openapi}/__init__.py +0 -0
  170. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/openapi/main.py +0 -0
  171. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/openapi/schema.py +0 -0
  172. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/queries.py +0 -0
  173. {arize_phoenix-4.25.0/src/phoenix/server/api/openapi → arize_phoenix-4.27.0/src/phoenix/server/api/routers}/__init__.py +0 -0
  174. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/routers/utils.py +0 -0
  175. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/routers/v1/__init__.py +0 -0
  176. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/routers/v1/datasets.py +0 -0
  177. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/routers/v1/evaluations.py +0 -0
  178. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/routers/v1/experiment_evaluations.py +0 -0
  179. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/routers/v1/experiment_runs.py +0 -0
  180. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/routers/v1/pydantic_compat.py +0 -0
  181. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/routers/v1/spans.py +0 -0
  182. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/routers/v1/traces.py +0 -0
  183. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/schema.py +0 -0
  184. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/types/Annotation.py +0 -0
  185. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/types/AnnotationSummary.py +0 -0
  186. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/types/AnnotatorKind.py +0 -0
  187. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/types/ApiKey.py +0 -0
  188. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/types/Cluster.py +0 -0
  189. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/types/CreateDatasetPayload.py +0 -0
  190. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/types/DataQualityMetric.py +0 -0
  191. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/types/Dataset.py +0 -0
  192. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/types/DatasetExample.py +0 -0
  193. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/types/DatasetExampleRevision.py +0 -0
  194. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/types/DatasetValues.py +0 -0
  195. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/types/DatasetVersion.py +0 -0
  196. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/types/Dimension.py +0 -0
  197. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/types/DimensionDataType.py +0 -0
  198. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/types/DimensionShape.py +0 -0
  199. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/types/DimensionType.py +0 -0
  200. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/types/DimensionWithValue.py +0 -0
  201. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/types/DocumentEvaluationSummary.py +0 -0
  202. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/types/DocumentRetrievalMetrics.py +0 -0
  203. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/types/EmbeddingDimension.py +0 -0
  204. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/types/EmbeddingMetadata.py +0 -0
  205. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/types/Evaluation.py +0 -0
  206. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/types/EvaluationSummary.py +0 -0
  207. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/types/Event.py +0 -0
  208. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/types/EventMetadata.py +0 -0
  209. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/types/ExampleRevisionInterface.py +0 -0
  210. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/types/Experiment.py +0 -0
  211. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/types/ExperimentAnnotationSummary.py +0 -0
  212. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/types/ExperimentComparison.py +0 -0
  213. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/types/ExperimentRun.py +0 -0
  214. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/types/ExperimentRunAnnotation.py +0 -0
  215. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/types/ExportedFile.py +0 -0
  216. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/types/Functionality.py +0 -0
  217. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/types/Inferences.py +0 -0
  218. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/types/InferencesRole.py +0 -0
  219. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/types/LabelFraction.py +0 -0
  220. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/types/MimeType.py +0 -0
  221. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/types/Model.py +0 -0
  222. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/types/NumericRange.py +0 -0
  223. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/types/PerformanceMetric.py +0 -0
  224. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/types/Project.py +0 -0
  225. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/types/PromptResponse.py +0 -0
  226. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/types/Retrieval.py +0 -0
  227. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/types/ScalarDriftMetricEnum.py +0 -0
  228. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/types/Segments.py +0 -0
  229. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/types/SortDir.py +0 -0
  230. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/types/Span.py +0 -0
  231. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/types/SpanAnnotation.py +0 -0
  232. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/types/SystemApiKey.py +0 -0
  233. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/types/TimeSeries.py +0 -0
  234. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/types/Trace.py +0 -0
  235. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/types/TraceAnnotation.py +0 -0
  236. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/types/UMAPPoints.py +0 -0
  237. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/types/User.py +0 -0
  238. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/types/UserApiKey.py +0 -0
  239. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/types/UserRole.py +0 -0
  240. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/types/ValidationResult.py +0 -0
  241. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/types/VectorDriftMetricEnum.py +0 -0
  242. {arize_phoenix-4.25.0/src/phoenix/server/api/routers → arize_phoenix-4.27.0/src/phoenix/server/api/types}/__init__.py +0 -0
  243. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/types/node.py +0 -0
  244. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/types/pagination.py +0 -0
  245. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/api/utils.py +0 -0
  246. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/dml_event.py +0 -0
  247. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/dml_event_handler.py +0 -0
  248. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/grpc_server.py +0 -0
  249. {arize_phoenix-4.25.0/src/phoenix/server/api/types → arize_phoenix-4.27.0/src/phoenix/server/openapi}/__init__.py +0 -0
  250. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/prometheus.py +0 -0
  251. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/static/apple-touch-icon-114x114.png +0 -0
  252. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/static/apple-touch-icon-120x120.png +0 -0
  253. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/static/apple-touch-icon-144x144.png +0 -0
  254. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/static/apple-touch-icon-152x152.png +0 -0
  255. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/static/apple-touch-icon-180x180.png +0 -0
  256. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/static/apple-touch-icon-72x72.png +0 -0
  257. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/static/apple-touch-icon-76x76.png +0 -0
  258. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/static/apple-touch-icon.png +0 -0
  259. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/static/assets/vendor-DxkFTwjz.css +0 -0
  260. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/static/assets/vendor-aSQri0vz.js +0 -0
  261. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/static/assets/vendor-arizeai-CsdcB1NH.js +0 -0
  262. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/static/assets/vendor-codemirror-CYHkhs7D.js +0 -0
  263. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/static/assets/vendor-recharts-B0sannek.js +0 -0
  264. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/static/assets/vendor-three-DwGkEfCM.js +0 -0
  265. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/static/favicon.ico +0 -0
  266. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/static/modernizr.js +0 -0
  267. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/telemetry.py +0 -0
  268. {arize_phoenix-4.25.0/src/phoenix/server/openapi → arize_phoenix-4.27.0/src/phoenix/server/templates}/__init__.py +0 -0
  269. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/templates/index.html +0 -0
  270. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/thread_server.py +0 -0
  271. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/server/types.py +0 -0
  272. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/services.py +0 -0
  273. {arize_phoenix-4.25.0/src/phoenix/server/templates → arize_phoenix-4.27.0/src/phoenix/session}/__init__.py +0 -0
  274. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/session/data_extractor.py +0 -0
  275. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/session/evaluation.py +0 -0
  276. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/session/session.py +0 -0
  277. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/settings.py +0 -0
  278. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/trace/__init__.py +0 -0
  279. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/trace/attributes.py +0 -0
  280. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/trace/dsl/README.md +0 -0
  281. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/trace/dsl/__init__.py +0 -0
  282. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/trace/dsl/filter.py +0 -0
  283. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/trace/dsl/query.py +0 -0
  284. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/trace/errors.py +0 -0
  285. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/trace/evaluation_conventions.py +0 -0
  286. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/trace/exporter.py +0 -0
  287. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/trace/langchain/__init__.py +0 -0
  288. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/trace/langchain/instrumentor.py +0 -0
  289. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/trace/llama_index/__init__.py +0 -0
  290. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/trace/llama_index/callback.py +0 -0
  291. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/trace/openai/__init__.py +0 -0
  292. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/trace/openai/instrumentor.py +0 -0
  293. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/trace/otel.py +0 -0
  294. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/trace/projects.py +0 -0
  295. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/trace/schemas.py +0 -0
  296. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/trace/span_evaluations.py +0 -0
  297. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/trace/span_json_decoder.py +0 -0
  298. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/trace/span_json_encoder.py +0 -0
  299. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/trace/trace_dataset.py +0 -0
  300. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/trace/utils.py +0 -0
  301. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/trace/v1/__init__.py +0 -0
  302. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/trace/v1/evaluation_pb2.py +0 -0
  303. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/trace/v1/evaluation_pb2.pyi +0 -0
  304. {arize_phoenix-4.25.0/src/phoenix/session → arize_phoenix-4.27.0/src/phoenix/utilities}/__init__.py +0 -0
  305. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/utilities/client.py +0 -0
  306. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/utilities/deprecation.py +0 -0
  307. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/utilities/error_handling.py +0 -0
  308. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/utilities/json.py +0 -0
  309. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/utilities/logging.py +0 -0
  310. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/utilities/project.py +0 -0
  311. {arize_phoenix-4.25.0 → arize_phoenix-4.27.0}/src/phoenix/utilities/re.py +0 -0
  312. {arize_phoenix-4.25.0 → arize_phoenix-4.27.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.25.0
3
+ Version: 4.27.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
@@ -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
@@ -90,7 +89,7 @@ Requires-Dist: pandas>=1.0; extra == 'dev'
90
89
  Requires-Dist: portpicker; extra == 'dev'
91
90
  Requires-Dist: pre-commit; extra == 'dev'
92
91
  Requires-Dist: prometheus-client; extra == 'dev'
93
- Requires-Dist: psycopg[binary]; extra == 'dev'
92
+ Requires-Dist: psycopg[binary,pool]; extra == 'dev'
94
93
  Requires-Dist: pytest-asyncio; extra == 'dev'
95
94
  Requires-Dist: pytest-cov; extra == 'dev'
96
95
  Requires-Dist: pytest-postgresql; extra == 'dev'
@@ -111,6 +110,7 @@ Requires-Dist: llama-index-readers-file==0.1.25; extra == 'llama-index'
111
110
  Requires-Dist: llama-index==0.10.51; extra == 'llama-index'
112
111
  Provides-Extra: pg
113
112
  Requires-Dist: asyncpg; extra == 'pg'
113
+ Requires-Dist: psycopg[binary,pool]; extra == 'pg'
114
114
  Provides-Extra: test
115
115
  Description-Content-Type: text/markdown
116
116
 
@@ -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",
@@ -85,7 +84,7 @@ dev = [
85
84
  "pytest-cov",
86
85
  "pytest-postgresql",
87
86
  "asyncpg",
88
- "psycopg[binary]",
87
+ "psycopg[binary,pool]",
89
88
  "strawberry-graphql[debug-server,opentelemetry]==0.236.0", # need to pin version because we're monkey-patching
90
89
  "pre-commit",
91
90
  "arize[AutoEmbeddings, LLM_Evaluation]",
@@ -111,6 +110,7 @@ llama-index = [
111
110
  ]
112
111
  pg = [
113
112
  "asyncpg",
113
+ "psycopg[binary,pool]",
114
114
  ]
115
115
  container = [
116
116
  "prometheus-client",
@@ -163,7 +163,7 @@ dependencies = [
163
163
  "pytest-cov",
164
164
  "pytest-postgresql",
165
165
  "asyncpg",
166
- "psycopg[binary]",
166
+ "psycopg[binary,pool]",
167
167
  "arize",
168
168
  "litellm>=1.0.3",
169
169
  "openai>=1.0.0",
@@ -0,0 +1,45 @@
1
+ import re
2
+ from hashlib import pbkdf2_hmac
3
+
4
+
5
+ def compute_password_hash(*, password: str, salt: str) -> str:
6
+ """
7
+ Salts and hashes a password using PBKDF2, HMAC, and SHA256.
8
+ """
9
+ password_bytes = password.encode("utf-8")
10
+ salt_bytes = salt.encode("utf-8")
11
+ password_hash_bytes = pbkdf2_hmac("sha256", password_bytes, salt_bytes, NUM_ITERATIONS)
12
+ password_hash = password_hash_bytes.hex()
13
+ return password_hash
14
+
15
+
16
+ def is_valid_password(*, password: str, salt: str, password_hash: str) -> bool:
17
+ """
18
+ Determines whether the password is valid by salting and hashing the password
19
+ and comparing against the existing hash value.
20
+ """
21
+ return password_hash == compute_password_hash(password=password, salt=salt)
22
+
23
+
24
+ def validate_email_format(email: str) -> None:
25
+ """
26
+ Checks that the email has a valid format.
27
+ """
28
+ if EMAIL_PATTERN.match(email) is None:
29
+ raise ValueError("Invalid email address")
30
+
31
+
32
+ def validate_password_format(password: str) -> None:
33
+ """
34
+ Checks that the password has a valid format.
35
+ """
36
+ if not password:
37
+ raise ValueError("Password must be non-empty")
38
+ if any(char.isspace() for char in password):
39
+ raise ValueError("Password cannot contain whitespace characters")
40
+ if not password.isascii():
41
+ raise ValueError("Password can contain only ASCII characters")
42
+
43
+
44
+ EMAIL_PATTERN = re.compile(r"^[^@\s]+@[^@\s]+[.][^@\s]+\Z")
45
+ NUM_ITERATIONS = 10_000
@@ -139,7 +139,7 @@ def aio_postgresql_engine(
139
139
  if not migrate:
140
140
  return engine
141
141
  sync_engine = sqlalchemy.create_engine(
142
- url=url.set(drivername="postgresql"),
142
+ url=url.set(drivername="postgresql+psycopg"),
143
143
  echo=Settings.log_migrations,
144
144
  json_serializer=_dumps,
145
145
  )
@@ -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:")
@@ -0,0 +1,9 @@
1
+ from enum import Enum
2
+
3
+ import strawberry
4
+
5
+
6
+ @strawberry.enum
7
+ class UserRoleInput(Enum):
8
+ ADMIN = "ADMIN"
9
+ MEMBER = "MEMBER"
@@ -7,6 +7,7 @@ from phoenix.server.api.mutations.export_events_mutations import ExportEventsMut
7
7
  from phoenix.server.api.mutations.project_mutations import ProjectMutationMixin
8
8
  from phoenix.server.api.mutations.span_annotations_mutations import SpanAnnotationMutationMixin
9
9
  from phoenix.server.api.mutations.trace_annotations_mutations import TraceAnnotationMutationMixin
10
+ from phoenix.server.api.mutations.user_mutations import UserMutationMixin
10
11
 
11
12
 
12
13
  @strawberry.type
@@ -18,5 +19,6 @@ class Mutation(
18
19
  SpanAnnotationMutationMixin,
19
20
  TraceAnnotationMutationMixin,
20
21
  ApiKeyMutationMixin,
22
+ UserMutationMixin,
21
23
  ):
22
24
  pass
@@ -0,0 +1,89 @@
1
+ import asyncio
2
+ from typing import Optional
3
+
4
+ import strawberry
5
+ from sqlalchemy import insert, select
6
+ from sqlean.dbapi2 import IntegrityError # type: ignore[import-untyped]
7
+ from strawberry.types import Info
8
+
9
+ from phoenix.auth import compute_password_hash, validate_email_format, validate_password_format
10
+ from phoenix.db import models
11
+ from phoenix.server.api.context import Context
12
+ from phoenix.server.api.input_types.UserRoleInput import UserRoleInput
13
+ from phoenix.server.api.types.User import User
14
+ from phoenix.server.api.types.UserRole import UserRole
15
+
16
+
17
+ @strawberry.input
18
+ class CreateUserInput:
19
+ email: str
20
+ username: Optional[str]
21
+ password: str
22
+ role: UserRoleInput
23
+
24
+
25
+ @strawberry.type
26
+ class UserMutationPayload:
27
+ user: User
28
+
29
+
30
+ @strawberry.type
31
+ class UserMutationMixin:
32
+ @strawberry.mutation
33
+ async def create_user(
34
+ self,
35
+ info: Info[Context, None],
36
+ input: CreateUserInput,
37
+ ) -> UserMutationPayload:
38
+ validate_email_format(email := input.email)
39
+ validate_password_format(password := input.password)
40
+ role_name = input.role.value
41
+ user_role_id = (
42
+ select(models.UserRole.id).where(models.UserRole.name == role_name).scalar_subquery()
43
+ )
44
+ secret = info.context.get_secret()
45
+ loop = asyncio.get_running_loop()
46
+ password_hash = await loop.run_in_executor(
47
+ executor=None,
48
+ func=lambda: compute_password_hash(password=password, salt=secret),
49
+ )
50
+ try:
51
+ async with info.context.db() as session:
52
+ user = await session.scalar(
53
+ insert(models.User)
54
+ .values(
55
+ user_role_id=user_role_id,
56
+ username=input.username,
57
+ email=email,
58
+ auth_method="LOCAL",
59
+ password_hash=password_hash,
60
+ reset_password=True,
61
+ )
62
+ .returning(models.User)
63
+ )
64
+ assert user is not None
65
+ except IntegrityError as error:
66
+ raise ValueError(_get_user_create_error_message(error))
67
+ return UserMutationPayload(
68
+ user=User(
69
+ id_attr=user.id,
70
+ email=user.email,
71
+ username=user.username,
72
+ created_at=user.created_at,
73
+ role=UserRole(id_attr=user.user_role_id, name=role_name),
74
+ )
75
+ )
76
+
77
+
78
+ def _get_user_create_error_message(error: IntegrityError) -> str:
79
+ """
80
+ Gets a user-facing error message to explain why user creation failed.
81
+ """
82
+ original_error_message = str(error)
83
+ username_already_exists = "users.username" in original_error_message
84
+ email_already_exists = "users.email" in original_error_message
85
+ if username_already_exists:
86
+ return "Username already exists"
87
+ elif email_already_exists:
88
+ return "Email already exists"
89
+ return "Failed to create user"
@@ -0,0 +1,52 @@
1
+ import asyncio
2
+ from datetime import timedelta
3
+
4
+ from fastapi import APIRouter, Form, Request, Response
5
+ from sqlalchemy import select
6
+ from starlette.status import HTTP_204_NO_CONTENT, HTTP_401_UNAUTHORIZED
7
+ from typing_extensions import Annotated
8
+
9
+ from phoenix.auth import is_valid_password
10
+ from phoenix.db import models
11
+
12
+ router = APIRouter(include_in_schema=False)
13
+
14
+ PHOENIX_ACCESS_TOKEN_COOKIE_NAME = "phoenix-access-token"
15
+ PHOENIX_ACCESS_TOKEN_COOKIE_MAX_AGE_IN_SECONDS = int(timedelta(days=31).total_seconds())
16
+
17
+
18
+ @router.post("/login")
19
+ async def login(
20
+ request: Request,
21
+ email: Annotated[str, Form()],
22
+ password: Annotated[str, Form()],
23
+ ) -> Response:
24
+ async with request.app.state.db() as session:
25
+ if (
26
+ user := await session.scalar(select(models.User).where(models.User.email == email))
27
+ ) is None or (password_hash := user.password_hash) is None:
28
+ return Response(status_code=HTTP_401_UNAUTHORIZED)
29
+ secret = request.app.state.get_secret()
30
+ loop = asyncio.get_running_loop()
31
+ if not await loop.run_in_executor(
32
+ executor=None,
33
+ func=lambda: is_valid_password(password=password, salt=secret, password_hash=password_hash),
34
+ ):
35
+ return Response(status_code=HTTP_401_UNAUTHORIZED)
36
+ response = Response(status_code=HTTP_204_NO_CONTENT)
37
+ response.set_cookie(
38
+ key=PHOENIX_ACCESS_TOKEN_COOKIE_NAME,
39
+ value="token", # todo: compute access token
40
+ secure=True,
41
+ httponly=True,
42
+ samesite="strict",
43
+ max_age=PHOENIX_ACCESS_TOKEN_COOKIE_MAX_AGE_IN_SECONDS,
44
+ )
45
+ return response
46
+
47
+
48
+ @router.post("/logout")
49
+ async def logout() -> Response:
50
+ response = Response(status_code=HTTP_204_NO_CONTENT)
51
+ response.delete_cookie(key=PHOENIX_ACCESS_TOKEN_COOKIE_NAME)
52
+ return response
@@ -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