arize-phoenix 4.27.0__tar.gz → 4.29.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 (311) hide show
  1. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/PKG-INFO +2 -1
  2. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/pyproject.toml +1 -0
  3. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/auth.py +3 -0
  4. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/context.py +10 -1
  5. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/dataloaders/dataset_example_revisions.py +3 -2
  6. arize_phoenix-4.29.0/src/phoenix/server/api/exceptions.py +41 -0
  7. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/mutations/__init__.py +4 -2
  8. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/mutations/api_key_mutations.py +29 -0
  9. arize_phoenix-4.29.0/src/phoenix/server/api/mutations/auth_mutations.py +65 -0
  10. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/mutations/dataset_mutations.py +9 -8
  11. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/mutations/experiment_mutations.py +2 -1
  12. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/queries.py +9 -8
  13. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/routers/v1/experiments.py +4 -4
  14. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/schema.py +2 -0
  15. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/app.py +0 -3
  16. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/static/.vite/manifest.json +9 -9
  17. arize_phoenix-4.27.0/src/phoenix/server/static/assets/components-1MfQimGx.js → arize_phoenix-4.29.0/src/phoenix/server/static/assets/components-BYH03rjA.js +108 -100
  18. arize_phoenix-4.27.0/src/phoenix/server/static/assets/index-B263sE2x.js → arize_phoenix-4.29.0/src/phoenix/server/static/assets/index-fqdjNpYm.js +1 -1
  19. arize_phoenix-4.27.0/src/phoenix/server/static/assets/pages-CqZDVx20.js → arize_phoenix-4.29.0/src/phoenix/server/static/assets/pages-DnbxgoTK.js +266 -219
  20. arize_phoenix-4.29.0/src/phoenix/version.py +1 -0
  21. arize_phoenix-4.27.0/src/phoenix/server/api/routers/auth.py +0 -52
  22. arize_phoenix-4.27.0/src/phoenix/version.py +0 -1
  23. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/.gitignore +0 -0
  24. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/IP_NOTICE +0 -0
  25. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/LICENSE +0 -0
  26. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/README.md +0 -0
  27. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/examples/manually-instrumented-chatbot/chat-service/chat/__init__.py +0 -0
  28. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/examples/manually-instrumented-chatbot/chat-service/chat/app.py +0 -0
  29. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/examples/manually-instrumented-chatbot/chat-service/chat/types.py +0 -0
  30. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/examples/manually-instrumented-chatbot/frontend/Dockerfile +0 -0
  31. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/examples/manually-instrumented-chatbot/frontend/Makefile +0 -0
  32. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/examples/manually-instrumented-chatbot/frontend/__init__.py +0 -0
  33. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/examples/manually-instrumented-chatbot/frontend/pyproject.toml +0 -0
  34. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/examples/manually-instrumented-chatbot/frontend/requirements.txt +0 -0
  35. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/examples/manually-instrumented-chatbot/frontend/schema.json +0 -0
  36. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/__init__.py +0 -0
  37. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/config.py +0 -0
  38. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/core/__init__.py +0 -0
  39. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/core/embedding_dimension.py +0 -0
  40. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/core/model.py +0 -0
  41. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/core/model_schema.py +0 -0
  42. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/core/model_schema_adapter.py +0 -0
  43. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/datetime_utils.py +0 -0
  44. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/db/README.md +0 -0
  45. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/db/__init__.py +0 -0
  46. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/db/alembic.ini +0 -0
  47. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/db/bulk_inserter.py +0 -0
  48. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/db/engines.py +0 -0
  49. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/db/helpers.py +0 -0
  50. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/db/insertion/__init__.py +0 -0
  51. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/db/insertion/constants.py +0 -0
  52. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/db/insertion/dataset.py +0 -0
  53. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/db/insertion/document_annotation.py +0 -0
  54. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/db/insertion/evaluation.py +0 -0
  55. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/db/insertion/helpers.py +0 -0
  56. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/db/insertion/span.py +0 -0
  57. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/db/insertion/span_annotation.py +0 -0
  58. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/db/insertion/trace_annotation.py +0 -0
  59. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/db/insertion/types.py +0 -0
  60. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/db/migrate.py +0 -0
  61. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/db/migrations/__init__.py +0 -0
  62. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/db/migrations/env.py +0 -0
  63. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/db/migrations/future_versions/README.md +0 -0
  64. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/db/migrations/future_versions/cd164e83824f_users_and_tokens.py +0 -0
  65. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/db/migrations/script.py.mako +0 -0
  66. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/db/migrations/versions/.gitignore +0 -0
  67. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/db/migrations/versions/10460e46d750_datasets.py +0 -0
  68. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/db/migrations/versions/3be8647b87d8_add_token_columns_to_spans_table.py +0 -0
  69. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/db/migrations/versions/cf03bd6bae1d_init.py +0 -0
  70. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/db/models.py +0 -0
  71. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/exceptions.py +0 -0
  72. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/experiments/__init__.py +0 -0
  73. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/experiments/evaluators/__init__.py +0 -0
  74. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/experiments/evaluators/base.py +0 -0
  75. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/experiments/evaluators/code_evaluators.py +0 -0
  76. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/experiments/evaluators/llm_evaluators.py +0 -0
  77. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/experiments/evaluators/utils.py +0 -0
  78. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/experiments/functions.py +0 -0
  79. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/experiments/tracing.py +0 -0
  80. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/experiments/types.py +0 -0
  81. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/experiments/utils.py +0 -0
  82. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/inferences/__init__.py +0 -0
  83. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/inferences/errors.py +0 -0
  84. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/inferences/fixtures.py +0 -0
  85. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/inferences/inferences.py +0 -0
  86. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/inferences/schema.py +0 -0
  87. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/inferences/validation.py +0 -0
  88. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/metrics/README.md +0 -0
  89. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/metrics/__init__.py +0 -0
  90. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/metrics/binning.py +0 -0
  91. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/metrics/metrics.py +0 -0
  92. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/metrics/mixins.py +0 -0
  93. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/metrics/retrieval_metrics.py +0 -0
  94. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/metrics/timeseries.py +0 -0
  95. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/metrics/wrappers.py +0 -0
  96. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/pointcloud/__init__.py +0 -0
  97. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/pointcloud/clustering.py +0 -0
  98. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/pointcloud/pointcloud.py +0 -0
  99. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/pointcloud/projectors.py +0 -0
  100. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/pointcloud/umap_parameters.py +0 -0
  101. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/py.typed +0 -0
  102. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/__init__.py +0 -0
  103. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/__init__.py +0 -0
  104. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/dataloaders/__init__.py +0 -0
  105. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/dataloaders/annotation_summaries.py +0 -0
  106. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/dataloaders/average_experiment_run_latency.py +0 -0
  107. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/dataloaders/cache/__init__.py +0 -0
  108. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/dataloaders/cache/two_tier_cache.py +0 -0
  109. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/dataloaders/dataset_example_spans.py +0 -0
  110. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/dataloaders/document_evaluation_summaries.py +0 -0
  111. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/dataloaders/document_evaluations.py +0 -0
  112. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/dataloaders/document_retrieval_metrics.py +0 -0
  113. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/dataloaders/experiment_annotation_summaries.py +0 -0
  114. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/dataloaders/experiment_error_rates.py +0 -0
  115. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/dataloaders/experiment_run_counts.py +0 -0
  116. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/dataloaders/experiment_sequence_number.py +0 -0
  117. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/dataloaders/latency_ms_quantile.py +0 -0
  118. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/dataloaders/min_start_or_max_end_times.py +0 -0
  119. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/dataloaders/project_by_name.py +0 -0
  120. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/dataloaders/record_counts.py +0 -0
  121. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/dataloaders/span_annotations.py +0 -0
  122. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/dataloaders/span_dataset_examples.py +0 -0
  123. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/dataloaders/span_descendants.py +0 -0
  124. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/dataloaders/span_projects.py +0 -0
  125. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/dataloaders/token_counts.py +0 -0
  126. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/dataloaders/trace_row_ids.py +0 -0
  127. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/helpers/__init__.py +0 -0
  128. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/helpers/dataset_helpers.py +0 -0
  129. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/input_types/AddExamplesToDatasetInput.py +0 -0
  130. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/input_types/AddSpansToDatasetInput.py +0 -0
  131. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/input_types/ClearProjectInput.py +0 -0
  132. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/input_types/ClusterInput.py +0 -0
  133. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/input_types/Coordinates.py +0 -0
  134. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/input_types/CreateDatasetInput.py +0 -0
  135. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/input_types/CreateSpanAnnotationInput.py +0 -0
  136. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/input_types/CreateTraceAnnotationInput.py +0 -0
  137. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/input_types/DataQualityMetricInput.py +0 -0
  138. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/input_types/DatasetExampleInput.py +0 -0
  139. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/input_types/DatasetSort.py +0 -0
  140. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/input_types/DatasetVersionSort.py +0 -0
  141. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/input_types/DeleteAnnotationsInput.py +0 -0
  142. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/input_types/DeleteDatasetExamplesInput.py +0 -0
  143. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/input_types/DeleteDatasetInput.py +0 -0
  144. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/input_types/DeleteExperimentsInput.py +0 -0
  145. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/input_types/DimensionFilter.py +0 -0
  146. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/input_types/DimensionInput.py +0 -0
  147. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/input_types/Granularity.py +0 -0
  148. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/input_types/PatchAnnotationInput.py +0 -0
  149. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/input_types/PatchDatasetExamplesInput.py +0 -0
  150. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/input_types/PatchDatasetInput.py +0 -0
  151. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/input_types/PerformanceMetricInput.py +0 -0
  152. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/input_types/SpanAnnotationSort.py +0 -0
  153. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/input_types/SpanSort.py +0 -0
  154. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/input_types/TimeRange.py +0 -0
  155. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/input_types/TraceAnnotationSort.py +0 -0
  156. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/input_types/UserRoleInput.py +0 -0
  157. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/input_types/__init__.py +0 -0
  158. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/interceptor.py +0 -0
  159. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/mutations/auth.py +0 -0
  160. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/mutations/export_events_mutations.py +0 -0
  161. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/mutations/project_mutations.py +0 -0
  162. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/mutations/span_annotations_mutations.py +0 -0
  163. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/mutations/trace_annotations_mutations.py +0 -0
  164. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/mutations/user_mutations.py +0 -0
  165. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/openapi/__init__.py +0 -0
  166. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/openapi/main.py +0 -0
  167. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/openapi/schema.py +0 -0
  168. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/routers/__init__.py +0 -0
  169. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/routers/utils.py +0 -0
  170. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/routers/v1/__init__.py +0 -0
  171. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/routers/v1/datasets.py +0 -0
  172. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/routers/v1/evaluations.py +0 -0
  173. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/routers/v1/experiment_evaluations.py +0 -0
  174. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/routers/v1/experiment_runs.py +0 -0
  175. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/routers/v1/pydantic_compat.py +0 -0
  176. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/routers/v1/spans.py +0 -0
  177. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/routers/v1/traces.py +0 -0
  178. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/routers/v1/utils.py +0 -0
  179. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/Annotation.py +0 -0
  180. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/AnnotationSummary.py +0 -0
  181. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/AnnotatorKind.py +0 -0
  182. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/ApiKey.py +0 -0
  183. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/Cluster.py +0 -0
  184. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/CreateDatasetPayload.py +0 -0
  185. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/DataQualityMetric.py +0 -0
  186. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/Dataset.py +0 -0
  187. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/DatasetExample.py +0 -0
  188. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/DatasetExampleRevision.py +0 -0
  189. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/DatasetValues.py +0 -0
  190. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/DatasetVersion.py +0 -0
  191. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/Dimension.py +0 -0
  192. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/DimensionDataType.py +0 -0
  193. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/DimensionShape.py +0 -0
  194. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/DimensionType.py +0 -0
  195. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/DimensionWithValue.py +0 -0
  196. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/DocumentEvaluationSummary.py +0 -0
  197. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/DocumentRetrievalMetrics.py +0 -0
  198. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/EmbeddingDimension.py +0 -0
  199. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/EmbeddingMetadata.py +0 -0
  200. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/Evaluation.py +0 -0
  201. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/EvaluationSummary.py +0 -0
  202. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/Event.py +0 -0
  203. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/EventMetadata.py +0 -0
  204. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/ExampleRevisionInterface.py +0 -0
  205. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/Experiment.py +0 -0
  206. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/ExperimentAnnotationSummary.py +0 -0
  207. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/ExperimentComparison.py +0 -0
  208. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/ExperimentRun.py +0 -0
  209. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/ExperimentRunAnnotation.py +0 -0
  210. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/ExportedFile.py +0 -0
  211. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/Functionality.py +0 -0
  212. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/Inferences.py +0 -0
  213. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/InferencesRole.py +0 -0
  214. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/LabelFraction.py +0 -0
  215. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/MimeType.py +0 -0
  216. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/Model.py +0 -0
  217. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/NumericRange.py +0 -0
  218. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/PerformanceMetric.py +0 -0
  219. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/Project.py +0 -0
  220. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/PromptResponse.py +0 -0
  221. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/Retrieval.py +0 -0
  222. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/ScalarDriftMetricEnum.py +0 -0
  223. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/Segments.py +0 -0
  224. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/SortDir.py +0 -0
  225. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/Span.py +0 -0
  226. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/SpanAnnotation.py +0 -0
  227. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/SystemApiKey.py +0 -0
  228. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/TimeSeries.py +0 -0
  229. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/Trace.py +0 -0
  230. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/TraceAnnotation.py +0 -0
  231. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/UMAPPoints.py +0 -0
  232. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/User.py +0 -0
  233. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/UserApiKey.py +0 -0
  234. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/UserRole.py +0 -0
  235. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/ValidationResult.py +0 -0
  236. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/VectorDriftMetricEnum.py +0 -0
  237. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/__init__.py +0 -0
  238. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/node.py +0 -0
  239. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/types/pagination.py +0 -0
  240. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/api/utils.py +0 -0
  241. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/dml_event.py +0 -0
  242. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/dml_event_handler.py +0 -0
  243. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/grpc_server.py +0 -0
  244. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/main.py +0 -0
  245. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/openapi/__init__.py +0 -0
  246. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/prometheus.py +0 -0
  247. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/static/apple-touch-icon-114x114.png +0 -0
  248. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/static/apple-touch-icon-120x120.png +0 -0
  249. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/static/apple-touch-icon-144x144.png +0 -0
  250. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/static/apple-touch-icon-152x152.png +0 -0
  251. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/static/apple-touch-icon-180x180.png +0 -0
  252. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/static/apple-touch-icon-72x72.png +0 -0
  253. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/static/apple-touch-icon-76x76.png +0 -0
  254. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/static/apple-touch-icon.png +0 -0
  255. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/static/assets/vendor-DxkFTwjz.css +0 -0
  256. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/static/assets/vendor-aSQri0vz.js +0 -0
  257. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/static/assets/vendor-arizeai-CsdcB1NH.js +0 -0
  258. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/static/assets/vendor-codemirror-CYHkhs7D.js +0 -0
  259. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/static/assets/vendor-recharts-B0sannek.js +0 -0
  260. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/static/assets/vendor-three-DwGkEfCM.js +0 -0
  261. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/static/favicon.ico +0 -0
  262. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/static/modernizr.js +0 -0
  263. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/telemetry.py +0 -0
  264. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/templates/__init__.py +0 -0
  265. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/templates/index.html +0 -0
  266. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/thread_server.py +0 -0
  267. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/server/types.py +0 -0
  268. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/services.py +0 -0
  269. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/session/__init__.py +0 -0
  270. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/session/client.py +0 -0
  271. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/session/data_extractor.py +0 -0
  272. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/session/evaluation.py +0 -0
  273. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/session/session.py +0 -0
  274. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/settings.py +0 -0
  275. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/trace/__init__.py +0 -0
  276. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/trace/attributes.py +0 -0
  277. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/trace/dsl/README.md +0 -0
  278. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/trace/dsl/__init__.py +0 -0
  279. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/trace/dsl/filter.py +0 -0
  280. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/trace/dsl/helpers.py +0 -0
  281. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/trace/dsl/query.py +0 -0
  282. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/trace/errors.py +0 -0
  283. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/trace/evaluation_conventions.py +0 -0
  284. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/trace/exporter.py +0 -0
  285. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/trace/fixtures.py +0 -0
  286. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/trace/langchain/__init__.py +0 -0
  287. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/trace/langchain/instrumentor.py +0 -0
  288. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/trace/llama_index/__init__.py +0 -0
  289. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/trace/llama_index/callback.py +0 -0
  290. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/trace/openai/__init__.py +0 -0
  291. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/trace/openai/instrumentor.py +0 -0
  292. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/trace/otel.py +0 -0
  293. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/trace/projects.py +0 -0
  294. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/trace/schemas.py +0 -0
  295. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/trace/span_evaluations.py +0 -0
  296. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/trace/span_json_decoder.py +0 -0
  297. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/trace/span_json_encoder.py +0 -0
  298. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/trace/trace_dataset.py +0 -0
  299. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/trace/utils.py +0 -0
  300. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/trace/v1/__init__.py +0 -0
  301. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/trace/v1/evaluation_pb2.py +0 -0
  302. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/trace/v1/evaluation_pb2.pyi +0 -0
  303. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/utilities/__init__.py +0 -0
  304. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/utilities/client.py +0 -0
  305. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/utilities/deprecation.py +0 -0
  306. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/utilities/error_handling.py +0 -0
  307. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/utilities/json.py +0 -0
  308. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/utilities/logging.py +0 -0
  309. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/utilities/project.py +0 -0
  310. {arize_phoenix-4.27.0 → arize_phoenix-4.29.0}/src/phoenix/utilities/re.py +0 -0
  311. {arize_phoenix-4.27.0 → arize_phoenix-4.29.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.27.0
3
+ Version: 4.29.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
@@ -21,6 +21,7 @@ Requires-Dist: aioitertools
21
21
  Requires-Dist: aiosqlite
22
22
  Requires-Dist: alembic<2,>=1.3.0
23
23
  Requires-Dist: arize-phoenix-evals>=0.13.1
24
+ Requires-Dist: arize-phoenix-otel>=0.4.1
24
25
  Requires-Dist: cachetools
25
26
  Requires-Dist: fastapi
26
27
  Requires-Dist: grpcio
@@ -59,6 +59,7 @@ dependencies = [
59
59
  "cachetools",
60
60
  "python-multipart", # see https://www.starlette.io/#dependencies
61
61
  "arize-phoenix-evals>=0.13.1",
62
+ "arize-phoenix-otel>=0.4.1",
62
63
  "fastapi",
63
64
  "pydantic>=1.0,!=2.0.*,<3", # exclude 2.0.* since it does not support the `json_encoders` configuration setting
64
65
  "pyjwt",
@@ -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
@@ -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
@@ -10,6 +10,7 @@ from strawberry.dataloader import DataLoader
10
10
  from typing_extensions import TypeAlias
11
11
 
12
12
  from phoenix.db import models
13
+ from phoenix.server.api.exceptions import NotFound
13
14
  from phoenix.server.api.types.DatasetExampleRevision import DatasetExampleRevision
14
15
  from phoenix.server.types import DbSessionFactory
15
16
 
@@ -24,7 +25,7 @@ class DatasetExampleRevisionsDataLoader(DataLoader[Key, Result]):
24
25
  super().__init__(load_fn=self._load_fn)
25
26
  self._db = db
26
27
 
27
- async def _load_fn(self, keys: List[Key]) -> List[Union[Result, ValueError]]:
28
+ async def _load_fn(self, keys: List[Key]) -> List[Union[Result, NotFound]]:
28
29
  # sqlalchemy has limited SQLite support for VALUES, so use UNION ALL instead.
29
30
  # For details, see https://github.com/sqlalchemy/sqlalchemy/issues/7228
30
31
  keys_subquery = union(
@@ -95,4 +96,4 @@ class DatasetExampleRevisionsDataLoader(DataLoader[Key, Result]):
95
96
  ) in await session.stream(query)
96
97
  if is_valid_version
97
98
  }
98
- return [results.get(key, ValueError("Could not find revision.")) for key in keys]
99
+ return [results.get(key, NotFound("Could not find revision.")) for key in keys]
@@ -0,0 +1,41 @@
1
+ from graphql.error import GraphQLError
2
+ from strawberry.extensions import MaskErrors
3
+
4
+
5
+ class CustomGraphQLError(Exception):
6
+ """
7
+ An error that represents an expected error scenario in a GraphQL resolver.
8
+ """
9
+
10
+
11
+ class BadRequest(CustomGraphQLError):
12
+ """
13
+ An error raised due to a malformed or invalid request.
14
+ """
15
+
16
+
17
+ class NotFound(CustomGraphQLError):
18
+ """
19
+ An error raised when the requested resource is not found.
20
+ """
21
+
22
+
23
+ class Unauthorized(CustomGraphQLError):
24
+ """
25
+ An error raised when login fails or a user or other entity is not authorized
26
+ to access a resource.
27
+ """
28
+
29
+
30
+ def get_mask_errors_extension() -> MaskErrors:
31
+ return MaskErrors(
32
+ should_mask_error=_should_mask_error,
33
+ error_message="an unexpected error occurred",
34
+ )
35
+
36
+
37
+ def _should_mask_error(error: GraphQLError) -> bool:
38
+ """
39
+ Masks unexpected errors raised from GraphQL resolvers.
40
+ """
41
+ return not isinstance(error.original_error, CustomGraphQLError)
@@ -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
@@ -5,12 +5,15 @@ import jwt
5
5
  import strawberry
6
6
  from sqlalchemy import insert, select
7
7
  from strawberry import UNSET
8
+ from strawberry.relay import GlobalID
8
9
  from strawberry.types import Info
9
10
 
10
11
  from phoenix.db import models
11
12
  from phoenix.server.api.context import Context
13
+ from phoenix.server.api.exceptions import NotFound
12
14
  from phoenix.server.api.mutations.auth import HasSecret, IsAuthenticated
13
15
  from phoenix.server.api.queries import Query
16
+ from phoenix.server.api.types.node import from_global_id_with_expected_type
14
17
  from phoenix.server.api.types.SystemApiKey import SystemApiKey
15
18
 
16
19
 
@@ -28,6 +31,16 @@ class CreateApiKeyInput:
28
31
  expires_at: Optional[datetime] = UNSET
29
32
 
30
33
 
34
+ @strawberry.input
35
+ class DeleteApiKeyInput:
36
+ id: GlobalID
37
+
38
+
39
+ @strawberry.type
40
+ class DeleteSystemApiKeyMutationPayload:
41
+ id: GlobalID
42
+
43
+
31
44
  @strawberry.type
32
45
  class ApiKeyMutationMixin:
33
46
  @strawberry.mutation(permission_classes=[HasSecret, IsAuthenticated]) # type: ignore
@@ -79,6 +92,22 @@ class ApiKeyMutationMixin:
79
92
  query=Query(),
80
93
  )
81
94
 
95
+ @strawberry.mutation(permission_classes=[HasSecret, IsAuthenticated]) # type: ignore
96
+ async def delete_system_api_key(
97
+ self, info: Info[Context, None], input: DeleteApiKeyInput
98
+ ) -> DeleteSystemApiKeyMutationPayload:
99
+ api_key_id = from_global_id_with_expected_type(
100
+ input.id, expected_type_name=SystemApiKey.__name__
101
+ )
102
+ async with info.context.db() as session:
103
+ api_key = await session.get(models.APIKey, api_key_id)
104
+ if api_key is None:
105
+ raise NotFound(f"Unknown System API Key: {input.id}")
106
+
107
+ await session.delete(api_key)
108
+
109
+ return DeleteSystemApiKeyMutationPayload(id=input.id)
110
+
82
111
 
83
112
  def create_jwt(
84
113
  *,
@@ -0,0 +1,65 @@
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.exceptions import Unauthorized
12
+ from phoenix.server.api.mutations.auth import HasSecret
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
+ FAILED_LOGIN_MESSAGE = "login failed"
17
+
18
+
19
+ @strawberry.input
20
+ class LoginMutationInput:
21
+ email: str
22
+ password: str
23
+
24
+
25
+ @strawberry.type
26
+ class AuthMutationMixin:
27
+ @strawberry.mutation(permission_classes=[HasSecret]) # type: ignore
28
+ async def login(
29
+ self,
30
+ info: Info[Context, None],
31
+ input: LoginMutationInput,
32
+ ) -> None:
33
+ async with info.context.db() as session:
34
+ if (
35
+ user := await session.scalar(
36
+ select(models.User).where(models.User.email == input.email)
37
+ )
38
+ ) is None or (password_hash := user.password_hash) is None:
39
+ raise Unauthorized(FAILED_LOGIN_MESSAGE)
40
+ secret = info.context.get_secret()
41
+ loop = asyncio.get_running_loop()
42
+ if not await loop.run_in_executor(
43
+ executor=None,
44
+ func=lambda: is_valid_password(
45
+ password=input.password, salt=secret, password_hash=password_hash
46
+ ),
47
+ ):
48
+ raise Unauthorized(FAILED_LOGIN_MESSAGE)
49
+ response = info.context.get_response()
50
+ response.set_cookie(
51
+ key=PHOENIX_ACCESS_TOKEN_COOKIE_NAME,
52
+ value="token", # todo: compute access token
53
+ secure=True,
54
+ httponly=True,
55
+ samesite="strict",
56
+ max_age=PHOENIX_ACCESS_TOKEN_COOKIE_MAX_AGE_IN_SECONDS,
57
+ )
58
+
59
+ @strawberry.mutation(permission_classes=[HasSecret]) # type: ignore
60
+ async def logout(
61
+ self,
62
+ info: Info[Context, None],
63
+ ) -> None:
64
+ response = info.context.get_response()
65
+ response.delete_cookie(key=PHOENIX_ACCESS_TOKEN_COOKIE_NAME)
@@ -13,6 +13,7 @@ from strawberry.types import Info
13
13
  from phoenix.db import models
14
14
  from phoenix.db.helpers import get_eval_trace_ids_for_datasets, get_project_names_for_datasets
15
15
  from phoenix.server.api.context import Context
16
+ from phoenix.server.api.exceptions import BadRequest, NotFound
16
17
  from phoenix.server.api.helpers.dataset_helpers import (
17
18
  get_dataset_example_input,
18
19
  get_dataset_example_output,
@@ -362,7 +363,7 @@ class DatasetMutationMixin:
362
363
  expected_type_name=Dataset.__name__,
363
364
  )
364
365
  except ValueError:
365
- raise ValueError(f"Unknown dataset: {input.dataset_id}")
366
+ raise NotFound(f"Unknown dataset: {input.dataset_id}")
366
367
  project_names_stmt = get_project_names_for_datasets(dataset_id)
367
368
  eval_trace_ids_stmt = get_eval_trace_ids_for_datasets(dataset_id)
368
369
  stmt = (
@@ -372,7 +373,7 @@ class DatasetMutationMixin:
372
373
  project_names = await session.scalars(project_names_stmt)
373
374
  eval_trace_ids = await session.scalars(eval_trace_ids_stmt)
374
375
  if not (dataset := await session.scalar(stmt)):
375
- raise ValueError(f"Unknown dataset: {input.dataset_id}")
376
+ raise NotFound(f"Unknown dataset: {input.dataset_id}")
376
377
  await asyncio.gather(
377
378
  delete_projects(info.context.db, *project_names),
378
379
  delete_traces(info.context.db, *eval_trace_ids),
@@ -388,7 +389,7 @@ class DatasetMutationMixin:
388
389
  input: PatchDatasetExamplesInput,
389
390
  ) -> DatasetMutationPayload:
390
391
  if not (patches := input.patches):
391
- raise ValueError("Must provide examples to patch.")
392
+ raise BadRequest("Must provide examples to patch.")
392
393
  by_numeric_id = [
393
394
  (
394
395
  from_global_id_with_expected_type(patch.example_id, DatasetExample.__name__),
@@ -399,9 +400,9 @@ class DatasetMutationMixin:
399
400
  ]
400
401
  example_ids, _, patches = map(list, zip(*sorted(by_numeric_id)))
401
402
  if len(set(example_ids)) < len(example_ids):
402
- raise ValueError("Cannot patch the same example more than once per mutation.")
403
+ raise BadRequest("Cannot patch the same example more than once per mutation.")
403
404
  if any(patch.is_empty() for patch in patches):
404
- raise ValueError("Received one or more empty patches that contain no fields to update.")
405
+ raise BadRequest("Received one or more empty patches that contain no fields to update.")
405
406
  version_description = input.version_description or None
406
407
  version_metadata = input.version_metadata
407
408
  async with info.context.db() as session:
@@ -419,9 +420,9 @@ class DatasetMutationMixin:
419
420
  )
420
421
  ).all()
421
422
  if not datasets:
422
- raise ValueError("No examples found.")
423
+ raise NotFound("No examples found.")
423
424
  if len(set(ds.id for ds in datasets)) > 1:
424
- raise ValueError("Examples must come from the same dataset.")
425
+ raise BadRequest("Examples must come from the same dataset.")
425
426
  dataset = datasets[0]
426
427
 
427
428
  revision_ids = (
@@ -445,7 +446,7 @@ class DatasetMutationMixin:
445
446
  )
446
447
  ).all()
447
448
  if (num_missing_examples := len(example_ids) - len(revisions)) > 0:
448
- raise ValueError(f"{num_missing_examples} example(s) could not be found.")
449
+ raise NotFound(f"{num_missing_examples} example(s) could not be found.")
449
450
 
450
451
  version_id = await session.scalar(
451
452
  insert(models.DatasetVersion)
@@ -9,6 +9,7 @@ from strawberry.types import Info
9
9
  from phoenix.db import models
10
10
  from phoenix.db.helpers import get_eval_trace_ids_for_experiments, get_project_names_for_experiments
11
11
  from phoenix.server.api.context import Context
12
+ from phoenix.server.api.exceptions import CustomGraphQLError
12
13
  from phoenix.server.api.input_types.DeleteExperimentsInput import DeleteExperimentsInput
13
14
  from phoenix.server.api.mutations.auth import IsAuthenticated
14
15
  from phoenix.server.api.types.Experiment import Experiment, to_gql_experiment
@@ -52,7 +53,7 @@ class ExperimentMutationMixin:
52
53
  }
53
54
  if unknown_experiment_ids := set(experiment_ids) - set(experiments.keys()):
54
55
  await savepoint.rollback()
55
- raise ValueError(
56
+ raise CustomGraphQLError(
56
57
  "Failed to delete experiment(s), "
57
58
  "probably due to invalid input experiment ID(s): "
58
59
  + str(
@@ -33,6 +33,7 @@ from phoenix.db.models import (
33
33
  )
34
34
  from phoenix.pointcloud.clustering import Hdbscan
35
35
  from phoenix.server.api.context import Context
36
+ from phoenix.server.api.exceptions import NotFound
36
37
  from phoenix.server.api.helpers import ensure_list
37
38
  from phoenix.server.api.input_types.ClusterInput import ClusterInput
38
39
  from phoenix.server.api.input_types.Coordinates import (
@@ -391,7 +392,7 @@ class Query:
391
392
  async with info.context.db() as session:
392
393
  project = (await session.execute(project_stmt)).first()
393
394
  if project is None:
394
- raise ValueError(f"Unknown project: {id}")
395
+ raise NotFound(f"Unknown project: {id}")
395
396
  return Project(
396
397
  id_attr=project.id,
397
398
  name=project.name,
@@ -406,7 +407,7 @@ class Query:
406
407
  async with info.context.db() as session:
407
408
  trace = (await session.execute(trace_stmt)).first()
408
409
  if trace is None:
409
- raise ValueError(f"Unknown trace: {id}")
410
+ raise NotFound(f"Unknown trace: {id}")
410
411
  return Trace(
411
412
  id_attr=trace.id, trace_id=trace.trace_id, project_rowid=trace.project_rowid
412
413
  )
@@ -421,13 +422,13 @@ class Query:
421
422
  async with info.context.db() as session:
422
423
  span = await session.scalar(span_stmt)
423
424
  if span is None:
424
- raise ValueError(f"Unknown span: {id}")
425
+ raise NotFound(f"Unknown span: {id}")
425
426
  return to_gql_span(span)
426
427
  elif type_name == Dataset.__name__:
427
428
  dataset_stmt = select(models.Dataset).where(models.Dataset.id == node_id)
428
429
  async with info.context.db() as session:
429
430
  if (dataset := await session.scalar(dataset_stmt)) is None:
430
- raise ValueError(f"Unknown dataset: {id}")
431
+ raise NotFound(f"Unknown dataset: {id}")
431
432
  return to_gql_dataset(dataset)
432
433
  elif type_name == DatasetExample.__name__:
433
434
  example_id = node_id
@@ -453,7 +454,7 @@ class Query:
453
454
  )
454
455
  )
455
456
  if not example:
456
- raise ValueError(f"Unknown dataset example: {id}")
457
+ raise NotFound(f"Unknown dataset example: {id}")
457
458
  return DatasetExample(
458
459
  id_attr=example.id,
459
460
  created_at=example.created_at,
@@ -464,7 +465,7 @@ class Query:
464
465
  select(models.Experiment).where(models.Experiment.id == node_id)
465
466
  )
466
467
  if not experiment:
467
- raise ValueError(f"Unknown experiment: {id}")
468
+ raise NotFound(f"Unknown experiment: {id}")
468
469
  return Experiment(
469
470
  id_attr=experiment.id,
470
471
  name=experiment.name,
@@ -485,9 +486,9 @@ class Query:
485
486
  )
486
487
  )
487
488
  ):
488
- raise ValueError(f"Unknown experiment run: {id}")
489
+ raise NotFound(f"Unknown experiment run: {id}")
489
490
  return to_gql_experiment_run(run)
490
- raise Exception(f"Unknown node type: {type_name}")
491
+ raise NotFound(f"Unknown node type: {type_name}")
491
492
 
492
493
  @strawberry.field
493
494
  def clusters(
@@ -2,7 +2,7 @@ from datetime import datetime
2
2
  from random import getrandbits
3
3
  from typing import Any, Dict, List, Optional
4
4
 
5
- from fastapi import APIRouter, HTTPException
5
+ from fastapi import APIRouter, HTTPException, Path
6
6
  from pydantic import Field
7
7
  from sqlalchemy import select
8
8
  from starlette.requests import Request
@@ -18,7 +18,7 @@ from phoenix.server.dml_event import ExperimentInsertEvent
18
18
  from .pydantic_compat import V1RoutesBaseModel
19
19
  from .utils import ResponseBody, add_errors_to_responses
20
20
 
21
- router = APIRouter(tags=["experiments"], include_in_schema=False)
21
+ router = APIRouter(tags=["experiments"], include_in_schema=True)
22
22
 
23
23
 
24
24
  def _short_uuid() -> str:
@@ -90,8 +90,8 @@ class CreateExperimentResponseBody(ResponseBody[Experiment]):
90
90
  )
91
91
  async def create_experiment(
92
92
  request: Request,
93
- dataset_id: str,
94
93
  request_body: CreateExperimentRequestBody,
94
+ dataset_id: str = Path(..., title="Dataset ID"),
95
95
  ) -> CreateExperimentResponseBody:
96
96
  dataset_globalid = GlobalID.from_id(dataset_id)
97
97
  try:
@@ -266,7 +266,7 @@ class ListExperimentsResponseBody(ResponseBody[List[Experiment]]):
266
266
  )
267
267
  async def list_experiments(
268
268
  request: Request,
269
- dataset_id: str,
269
+ dataset_id: str = Path(..., title="Dataset ID"),
270
270
  ) -> ListExperimentsResponseBody:
271
271
  dataset_gid = GlobalID.from_id(dataset_id)
272
272
  try:
@@ -1,5 +1,6 @@
1
1
  import strawberry
2
2
 
3
+ from phoenix.server.api.exceptions import get_mask_errors_extension
3
4
  from phoenix.server.api.mutations import Mutation
4
5
  from phoenix.server.api.queries import Query
5
6
 
@@ -10,4 +11,5 @@ from phoenix.server.api.queries import Query
10
11
  schema = strawberry.Schema(
11
12
  query=Query,
12
13
  mutation=Mutation,
14
+ extensions=[get_mask_errors_extension()],
13
15
  )
@@ -79,7 +79,6 @@ from phoenix.server.api.dataloaders import (
79
79
  TokenCountDataLoader,
80
80
  TraceRowIdsDataLoader,
81
81
  )
82
- from phoenix.server.api.routers.auth import router as auth_router
83
82
  from phoenix.server.api.routers.v1 import REST_API_VERSION
84
83
  from phoenix.server.api.routers.v1 import router as v1_router
85
84
  from phoenix.server.api.schema import schema
@@ -662,8 +661,6 @@ def create_app(
662
661
  app.include_router(router)
663
662
  app.include_router(graphql_router)
664
663
  app.add_middleware(GZipMiddleware)
665
- if authentication_enabled:
666
- app.include_router(auth_router)
667
664
  if serve_ui:
668
665
  app.mount(
669
666
  "/",
@@ -1,21 +1,21 @@
1
1
  {
2
- "_components-1MfQimGx.js": {
3
- "file": "assets/components-1MfQimGx.js",
2
+ "_components-BYH03rjA.js": {
3
+ "file": "assets/components-BYH03rjA.js",
4
4
  "name": "components",
5
5
  "imports": [
6
6
  "_vendor-aSQri0vz.js",
7
7
  "_vendor-arizeai-CsdcB1NH.js",
8
- "_pages-CqZDVx20.js",
8
+ "_pages-DnbxgoTK.js",
9
9
  "_vendor-three-DwGkEfCM.js",
10
10
  "_vendor-codemirror-CYHkhs7D.js"
11
11
  ]
12
12
  },
13
- "_pages-CqZDVx20.js": {
14
- "file": "assets/pages-CqZDVx20.js",
13
+ "_pages-DnbxgoTK.js": {
14
+ "file": "assets/pages-DnbxgoTK.js",
15
15
  "name": "pages",
16
16
  "imports": [
17
17
  "_vendor-aSQri0vz.js",
18
- "_components-1MfQimGx.js",
18
+ "_components-BYH03rjA.js",
19
19
  "_vendor-arizeai-CsdcB1NH.js",
20
20
  "_vendor-recharts-B0sannek.js",
21
21
  "_vendor-codemirror-CYHkhs7D.js"
@@ -61,15 +61,15 @@
61
61
  "name": "vendor-three"
62
62
  },
63
63
  "index.tsx": {
64
- "file": "assets/index-B263sE2x.js",
64
+ "file": "assets/index-fqdjNpYm.js",
65
65
  "name": "index",
66
66
  "src": "index.tsx",
67
67
  "isEntry": true,
68
68
  "imports": [
69
69
  "_vendor-aSQri0vz.js",
70
70
  "_vendor-arizeai-CsdcB1NH.js",
71
- "_pages-CqZDVx20.js",
72
- "_components-1MfQimGx.js",
71
+ "_pages-DnbxgoTK.js",
72
+ "_components-BYH03rjA.js",
73
73
  "_vendor-three-DwGkEfCM.js",
74
74
  "_vendor-recharts-B0sannek.js",
75
75
  "_vendor-codemirror-CYHkhs7D.js"