arize-phoenix 4.7.2__tar.gz → 4.8.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 (266) hide show
  1. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/PKG-INFO +1 -1
  2. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/db/helpers.py +37 -2
  3. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/dataloaders/project_by_name.py +1 -1
  4. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/mutations/dataset_mutations.py +23 -13
  5. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/mutations/experiment_mutations.py +12 -4
  6. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/routers/v1/__init__.py +1 -0
  7. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/routers/v1/datasets.py +59 -1
  8. arize_phoenix-4.8.0/src/phoenix/server/api/utils.py +36 -0
  9. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/static/index.js +2 -2
  10. arize_phoenix-4.8.0/src/phoenix/version.py +1 -0
  11. arize_phoenix-4.7.2/src/phoenix/version.py +0 -1
  12. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/.gitignore +0 -0
  13. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/IP_NOTICE +0 -0
  14. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/LICENSE +0 -0
  15. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/README.md +0 -0
  16. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/examples/manually-instrumented-chatbot/chat-service/chat/__init__.py +0 -0
  17. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/examples/manually-instrumented-chatbot/chat-service/chat/app.py +0 -0
  18. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/examples/manually-instrumented-chatbot/chat-service/chat/types.py +0 -0
  19. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/examples/manually-instrumented-chatbot/frontend/Dockerfile +0 -0
  20. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/examples/manually-instrumented-chatbot/frontend/Makefile +0 -0
  21. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/examples/manually-instrumented-chatbot/frontend/__init__.py +0 -0
  22. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/examples/manually-instrumented-chatbot/frontend/pyproject.toml +0 -0
  23. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/examples/manually-instrumented-chatbot/frontend/requirements.txt +0 -0
  24. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/examples/manually-instrumented-chatbot/frontend/schema.json +0 -0
  25. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/pyproject.toml +0 -0
  26. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/__init__.py +0 -0
  27. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/config.py +0 -0
  28. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/core/__init__.py +0 -0
  29. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/core/embedding_dimension.py +0 -0
  30. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/core/model.py +0 -0
  31. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/core/model_schema.py +0 -0
  32. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/core/model_schema_adapter.py +0 -0
  33. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/datetime_utils.py +0 -0
  34. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/db/README.md +0 -0
  35. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/db/__init__.py +0 -0
  36. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/db/alembic.ini +0 -0
  37. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/db/bulk_inserter.py +0 -0
  38. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/db/engines.py +0 -0
  39. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/db/insertion/__init__.py +0 -0
  40. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/db/insertion/dataset.py +0 -0
  41. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/db/insertion/evaluation.py +0 -0
  42. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/db/insertion/helpers.py +0 -0
  43. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/db/insertion/span.py +0 -0
  44. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/db/migrate.py +0 -0
  45. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/db/migrations/__init__.py +0 -0
  46. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/db/migrations/env.py +0 -0
  47. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/db/migrations/script.py.mako +0 -0
  48. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/db/migrations/types.py +0 -0
  49. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/db/migrations/versions/10460e46d750_datasets.py +0 -0
  50. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/db/migrations/versions/cf03bd6bae1d_init.py +0 -0
  51. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/db/models.py +0 -0
  52. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/exceptions.py +0 -0
  53. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/experiments/__init__.py +0 -0
  54. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/experiments/evaluators/__init__.py +0 -0
  55. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/experiments/evaluators/base.py +0 -0
  56. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/experiments/evaluators/code_evaluators.py +0 -0
  57. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/experiments/evaluators/llm_evaluators.py +0 -0
  58. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/experiments/evaluators/utils.py +0 -0
  59. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/experiments/functions.py +0 -0
  60. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/experiments/tracing.py +0 -0
  61. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/experiments/types.py +0 -0
  62. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/experiments/utils.py +0 -0
  63. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/inferences/__init__.py +0 -0
  64. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/inferences/errors.py +0 -0
  65. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/inferences/fixtures.py +0 -0
  66. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/inferences/inferences.py +0 -0
  67. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/inferences/schema.py +0 -0
  68. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/inferences/validation.py +0 -0
  69. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/metrics/README.md +0 -0
  70. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/metrics/__init__.py +0 -0
  71. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/metrics/binning.py +0 -0
  72. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/metrics/metrics.py +0 -0
  73. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/metrics/mixins.py +0 -0
  74. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/metrics/retrieval_metrics.py +0 -0
  75. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/metrics/timeseries.py +0 -0
  76. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/metrics/wrappers.py +0 -0
  77. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/pointcloud/__init__.py +0 -0
  78. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/pointcloud/clustering.py +0 -0
  79. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/pointcloud/pointcloud.py +0 -0
  80. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/pointcloud/projectors.py +0 -0
  81. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/pointcloud/umap_parameters.py +0 -0
  82. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/py.typed +0 -0
  83. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/__init__.py +0 -0
  84. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/__init__.py +0 -0
  85. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/context.py +0 -0
  86. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/dataloaders/__init__.py +0 -0
  87. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/dataloaders/average_experiment_run_latency.py +0 -0
  88. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/dataloaders/cache/__init__.py +0 -0
  89. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/dataloaders/cache/two_tier_cache.py +0 -0
  90. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/dataloaders/dataset_example_revisions.py +0 -0
  91. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/dataloaders/dataset_example_spans.py +0 -0
  92. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/dataloaders/document_evaluation_summaries.py +0 -0
  93. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/dataloaders/document_evaluations.py +0 -0
  94. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/dataloaders/document_retrieval_metrics.py +0 -0
  95. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/dataloaders/evaluation_summaries.py +0 -0
  96. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/dataloaders/experiment_annotation_summaries.py +0 -0
  97. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/dataloaders/experiment_error_rates.py +0 -0
  98. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/dataloaders/experiment_run_counts.py +0 -0
  99. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/dataloaders/experiment_sequence_number.py +0 -0
  100. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/dataloaders/latency_ms_quantile.py +0 -0
  101. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/dataloaders/min_start_or_max_end_times.py +0 -0
  102. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/dataloaders/record_counts.py +0 -0
  103. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/dataloaders/span_descendants.py +0 -0
  104. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/dataloaders/span_evaluations.py +0 -0
  105. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/dataloaders/span_projects.py +0 -0
  106. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/dataloaders/token_counts.py +0 -0
  107. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/dataloaders/trace_evaluations.py +0 -0
  108. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/dataloaders/trace_row_ids.py +0 -0
  109. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/helpers/__init__.py +0 -0
  110. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/helpers/dataset_helpers.py +0 -0
  111. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/input_types/AddExamplesToDatasetInput.py +0 -0
  112. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/input_types/AddSpansToDatasetInput.py +0 -0
  113. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/input_types/ClearProjectInput.py +0 -0
  114. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/input_types/ClusterInput.py +0 -0
  115. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/input_types/Coordinates.py +0 -0
  116. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/input_types/CreateDatasetInput.py +0 -0
  117. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/input_types/DataQualityMetricInput.py +0 -0
  118. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/input_types/DatasetExampleInput.py +0 -0
  119. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/input_types/DatasetSort.py +0 -0
  120. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/input_types/DatasetVersionSort.py +0 -0
  121. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/input_types/DeleteDatasetExamplesInput.py +0 -0
  122. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/input_types/DeleteDatasetInput.py +0 -0
  123. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/input_types/DeleteExperimentsInput.py +0 -0
  124. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/input_types/DimensionFilter.py +0 -0
  125. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/input_types/DimensionInput.py +0 -0
  126. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/input_types/Granularity.py +0 -0
  127. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/input_types/PatchDatasetExamplesInput.py +0 -0
  128. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/input_types/PatchDatasetInput.py +0 -0
  129. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/input_types/PerformanceMetricInput.py +0 -0
  130. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/input_types/SpanSort.py +0 -0
  131. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/input_types/TimeRange.py +0 -0
  132. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/input_types/__init__.py +0 -0
  133. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/interceptor.py +0 -0
  134. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/mutations/__init__.py +0 -0
  135. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/mutations/auth.py +0 -0
  136. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/mutations/export_events_mutations.py +0 -0
  137. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/mutations/project_mutations.py +0 -0
  138. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/openapi/__init__.py +0 -0
  139. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/openapi/main.py +0 -0
  140. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/openapi/schema.py +0 -0
  141. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/queries.py +0 -0
  142. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/routers/__init__.py +0 -0
  143. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/routers/utils.py +0 -0
  144. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/routers/v1/dataset_examples.py +0 -0
  145. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/routers/v1/evaluations.py +0 -0
  146. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/routers/v1/experiment_evaluations.py +0 -0
  147. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/routers/v1/experiment_runs.py +0 -0
  148. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/routers/v1/experiments.py +0 -0
  149. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/routers/v1/spans.py +0 -0
  150. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/routers/v1/traces.py +0 -0
  151. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/schema.py +0 -0
  152. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/types/AnnotatorKind.py +0 -0
  153. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/types/Cluster.py +0 -0
  154. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/types/CreateDatasetPayload.py +0 -0
  155. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/types/DataQualityMetric.py +0 -0
  156. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/types/Dataset.py +0 -0
  157. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/types/DatasetExample.py +0 -0
  158. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/types/DatasetExampleRevision.py +0 -0
  159. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/types/DatasetValues.py +0 -0
  160. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/types/DatasetVersion.py +0 -0
  161. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/types/Dimension.py +0 -0
  162. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/types/DimensionDataType.py +0 -0
  163. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/types/DimensionShape.py +0 -0
  164. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/types/DimensionType.py +0 -0
  165. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/types/DimensionWithValue.py +0 -0
  166. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/types/DocumentEvaluationSummary.py +0 -0
  167. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/types/DocumentRetrievalMetrics.py +0 -0
  168. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/types/EmbeddingDimension.py +0 -0
  169. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/types/EmbeddingMetadata.py +0 -0
  170. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/types/Evaluation.py +0 -0
  171. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/types/EvaluationSummary.py +0 -0
  172. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/types/Event.py +0 -0
  173. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/types/EventMetadata.py +0 -0
  174. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/types/ExampleRevisionInterface.py +0 -0
  175. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/types/Experiment.py +0 -0
  176. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/types/ExperimentAnnotationSummary.py +0 -0
  177. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/types/ExperimentComparison.py +0 -0
  178. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/types/ExperimentRun.py +0 -0
  179. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/types/ExperimentRunAnnotation.py +0 -0
  180. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/types/ExportedFile.py +0 -0
  181. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/types/Functionality.py +0 -0
  182. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/types/Inferences.py +0 -0
  183. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/types/InferencesRole.py +0 -0
  184. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/types/MimeType.py +0 -0
  185. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/types/Model.py +0 -0
  186. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/types/NumericRange.py +0 -0
  187. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/types/PerformanceMetric.py +0 -0
  188. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/types/Project.py +0 -0
  189. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/types/PromptResponse.py +0 -0
  190. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/types/Retrieval.py +0 -0
  191. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/types/ScalarDriftMetricEnum.py +0 -0
  192. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/types/Segments.py +0 -0
  193. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/types/SortDir.py +0 -0
  194. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/types/Span.py +0 -0
  195. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/types/TimeSeries.py +0 -0
  196. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/types/Trace.py +0 -0
  197. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/types/UMAPPoints.py +0 -0
  198. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/types/ValidationResult.py +0 -0
  199. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/types/VectorDriftMetricEnum.py +0 -0
  200. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/types/__init__.py +0 -0
  201. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/types/node.py +0 -0
  202. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/api/types/pagination.py +0 -0
  203. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/app.py +0 -0
  204. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/grpc_server.py +0 -0
  205. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/main.py +0 -0
  206. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/openapi/__init__.py +0 -0
  207. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/openapi/docs.py +0 -0
  208. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/prometheus.py +0 -0
  209. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/static/apple-touch-icon-114x114.png +0 -0
  210. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/static/apple-touch-icon-120x120.png +0 -0
  211. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/static/apple-touch-icon-144x144.png +0 -0
  212. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/static/apple-touch-icon-152x152.png +0 -0
  213. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/static/apple-touch-icon-180x180.png +0 -0
  214. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/static/apple-touch-icon-72x72.png +0 -0
  215. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/static/apple-touch-icon-76x76.png +0 -0
  216. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/static/apple-touch-icon.png +0 -0
  217. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/static/favicon.ico +0 -0
  218. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/static/index.css +0 -0
  219. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/static/modernizr.js +0 -0
  220. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/telemetry.py +0 -0
  221. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/templates/__init__.py +0 -0
  222. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/templates/index.html +0 -0
  223. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/server/thread_server.py +0 -0
  224. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/services.py +0 -0
  225. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/session/__init__.py +0 -0
  226. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/session/client.py +0 -0
  227. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/session/data_extractor.py +0 -0
  228. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/session/evaluation.py +0 -0
  229. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/session/session.py +0 -0
  230. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/settings.py +0 -0
  231. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/trace/__init__.py +0 -0
  232. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/trace/attributes.py +0 -0
  233. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/trace/dsl/README.md +0 -0
  234. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/trace/dsl/__init__.py +0 -0
  235. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/trace/dsl/filter.py +0 -0
  236. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/trace/dsl/helpers.py +0 -0
  237. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/trace/dsl/query.py +0 -0
  238. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/trace/errors.py +0 -0
  239. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/trace/evaluation_conventions.py +0 -0
  240. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/trace/exporter.py +0 -0
  241. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/trace/fixtures.py +0 -0
  242. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/trace/langchain/__init__.py +0 -0
  243. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/trace/langchain/instrumentor.py +0 -0
  244. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/trace/llama_index/__init__.py +0 -0
  245. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/trace/llama_index/callback.py +0 -0
  246. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/trace/openai/__init__.py +0 -0
  247. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/trace/openai/instrumentor.py +0 -0
  248. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/trace/otel.py +0 -0
  249. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/trace/projects.py +0 -0
  250. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/trace/schemas.py +0 -0
  251. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/trace/span_evaluations.py +0 -0
  252. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/trace/span_json_decoder.py +0 -0
  253. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/trace/span_json_encoder.py +0 -0
  254. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/trace/trace_dataset.py +0 -0
  255. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/trace/utils.py +0 -0
  256. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/trace/v1/__init__.py +0 -0
  257. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/trace/v1/evaluation_pb2.py +0 -0
  258. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/trace/v1/evaluation_pb2.pyi +0 -0
  259. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/utilities/__init__.py +0 -0
  260. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/utilities/deprecation.py +0 -0
  261. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/utilities/error_handling.py +0 -0
  262. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/utilities/json.py +0 -0
  263. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/utilities/logging.py +0 -0
  264. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/utilities/project.py +0 -0
  265. {arize_phoenix-4.7.2 → arize_phoenix-4.8.0}/src/phoenix/utilities/re.py +0 -0
  266. {arize_phoenix-4.7.2 → arize_phoenix-4.8.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.7.2
3
+ Version: 4.8.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
@@ -1,12 +1,12 @@
1
1
  from enum import Enum
2
- from typing import Any
2
+ from typing import Any, Optional, Tuple
3
3
 
4
4
  from openinference.semconv.trace import (
5
5
  OpenInferenceSpanKindValues,
6
6
  RerankerAttributes,
7
7
  SpanAttributes,
8
8
  )
9
- from sqlalchemy import Integer, SQLColumnExpression, case, func
9
+ from sqlalchemy import Integer, Select, SQLColumnExpression, case, distinct, func, select
10
10
  from typing_extensions import assert_never
11
11
 
12
12
  from phoenix.db import models
@@ -45,3 +45,38 @@ def num_docs_col(dialect: SupportedSQLDialect) -> SQLColumnExpression[Integer]:
45
45
 
46
46
  _RETRIEVAL_DOCUMENTS = SpanAttributes.RETRIEVAL_DOCUMENTS.split(".")
47
47
  _RERANKER_OUTPUT_DOCUMENTS = RerankerAttributes.RERANKER_OUTPUT_DOCUMENTS.split(".")
48
+
49
+
50
+ def get_eval_trace_ids_for_datasets(*dataset_ids: int) -> Select[Tuple[Optional[str]]]:
51
+ return (
52
+ select(distinct(models.ExperimentRunAnnotation.trace_id))
53
+ .join(models.ExperimentRun)
54
+ .join_from(models.ExperimentRun, models.Experiment)
55
+ .where(models.Experiment.dataset_id.in_(set(dataset_ids)))
56
+ .where(models.ExperimentRunAnnotation.trace_id.isnot(None))
57
+ )
58
+
59
+
60
+ def get_project_names_for_datasets(*dataset_ids: int) -> Select[Tuple[Optional[str]]]:
61
+ return (
62
+ select(distinct(models.Experiment.project_name))
63
+ .where(models.Experiment.dataset_id.in_(set(dataset_ids)))
64
+ .where(models.Experiment.project_name.isnot(None))
65
+ )
66
+
67
+
68
+ def get_eval_trace_ids_for_experiments(*experiment_ids: int) -> Select[Tuple[Optional[str]]]:
69
+ return (
70
+ select(distinct(models.ExperimentRunAnnotation.trace_id))
71
+ .join(models.ExperimentRun)
72
+ .where(models.ExperimentRun.experiment_id.in_(set(experiment_ids)))
73
+ .where(models.ExperimentRunAnnotation.trace_id.isnot(None))
74
+ )
75
+
76
+
77
+ def get_project_names_for_experiments(*experiment_ids: int) -> Select[Tuple[Optional[str]]]:
78
+ return (
79
+ select(distinct(models.Experiment.project_name))
80
+ .where(models.Experiment.id.in_(set(experiment_ids)))
81
+ .where(models.Experiment.project_name.isnot(None))
82
+ )
@@ -28,4 +28,4 @@ class ProjectByNameDataLoader(DataLoader[Key, Result]):
28
28
  async for project in data:
29
29
  projects_by_name[project.name] = project
30
30
 
31
- return [projects_by_name[project_name] for project_name in project_names]
31
+ return [projects_by_name.get(project_name) for project_name in keys]
@@ -1,3 +1,4 @@
1
+ import asyncio
1
2
  from datetime import datetime
2
3
  from typing import Any, Dict
3
4
 
@@ -10,6 +11,7 @@ from strawberry import UNSET
10
11
  from strawberry.types import Info
11
12
 
12
13
  from phoenix.db import models
14
+ from phoenix.db.helpers import get_eval_trace_ids_for_datasets, get_project_names_for_datasets
13
15
  from phoenix.server.api.context import Context
14
16
  from phoenix.server.api.helpers.dataset_helpers import (
15
17
  get_dataset_example_input,
@@ -30,6 +32,7 @@ from phoenix.server.api.types.Dataset import Dataset, to_gql_dataset
30
32
  from phoenix.server.api.types.DatasetExample import DatasetExample
31
33
  from phoenix.server.api.types.node import from_global_id_with_expected_type
32
34
  from phoenix.server.api.types.Span import Span
35
+ from phoenix.server.api.utils import delete_projects, delete_traces
33
36
 
34
37
 
35
38
  @strawberry.type
@@ -274,21 +277,28 @@ class DatasetMutationMixin:
274
277
  info: Info[Context, None],
275
278
  input: DeleteDatasetInput,
276
279
  ) -> DatasetMutationPayload:
277
- dataset_id = input.dataset_id
278
- dataset_rowid = from_global_id_with_expected_type(
279
- global_id=dataset_id, expected_type_name=Dataset.__name__
280
+ try:
281
+ dataset_id = from_global_id_with_expected_type(
282
+ global_id=input.dataset_id,
283
+ expected_type_name=Dataset.__name__,
284
+ )
285
+ except ValueError:
286
+ raise ValueError(f"Unknown dataset: {input.dataset_id}")
287
+ project_names_stmt = get_project_names_for_datasets(dataset_id)
288
+ eval_trace_ids_stmt = get_eval_trace_ids_for_datasets(dataset_id)
289
+ stmt = (
290
+ delete(models.Dataset).where(models.Dataset.id == dataset_id).returning(models.Dataset)
280
291
  )
281
-
282
292
  async with info.context.db() as session:
283
- delete_result = await session.execute(
284
- delete(models.Dataset)
285
- .where(models.Dataset.id == dataset_rowid)
286
- .returning(models.Dataset)
287
- )
288
- if not (datasets := delete_result.first()):
289
- raise ValueError(f"Unknown dataset: {dataset_id}")
290
-
291
- dataset = datasets[0]
293
+ project_names = await session.scalars(project_names_stmt)
294
+ eval_trace_ids = await session.scalars(eval_trace_ids_stmt)
295
+ if not (dataset := await session.scalar(stmt)):
296
+ raise ValueError(f"Unknown dataset: {input.dataset_id}")
297
+ await asyncio.gather(
298
+ delete_projects(info.context.db, *project_names),
299
+ delete_traces(info.context.db, *eval_trace_ids),
300
+ return_exceptions=True,
301
+ )
292
302
  return DatasetMutationPayload(dataset=to_gql_dataset(dataset))
293
303
 
294
304
  @strawberry.mutation(permission_classes=[IsAuthenticated]) # type: ignore
@@ -1,3 +1,4 @@
1
+ import asyncio
1
2
  from typing import List
2
3
 
3
4
  import strawberry
@@ -6,11 +7,13 @@ from strawberry.relay import GlobalID
6
7
  from strawberry.types import Info
7
8
 
8
9
  from phoenix.db import models
10
+ from phoenix.db.helpers import get_eval_trace_ids_for_experiments, get_project_names_for_experiments
9
11
  from phoenix.server.api.context import Context
10
12
  from phoenix.server.api.input_types.DeleteExperimentsInput import DeleteExperimentsInput
11
13
  from phoenix.server.api.mutations.auth import IsAuthenticated
12
14
  from phoenix.server.api.types.Experiment import Experiment, to_gql_experiment
13
15
  from phoenix.server.api.types.node import from_global_id_with_expected_type
16
+ from phoenix.server.api.utils import delete_projects, delete_traces
14
17
 
15
18
 
16
19
  @strawberry.type
@@ -30,7 +33,11 @@ class ExperimentMutationMixin:
30
33
  from_global_id_with_expected_type(experiment_id, Experiment.__name__)
31
34
  for experiment_id in input.experiment_ids
32
35
  ]
36
+ project_names_stmt = get_project_names_for_experiments(*experiment_ids)
37
+ eval_trace_ids_stmt = get_eval_trace_ids_for_experiments(*experiment_ids)
33
38
  async with info.context.db() as session:
39
+ project_names = await session.scalars(project_names_stmt)
40
+ eval_trace_ids = await session.scalars(eval_trace_ids_stmt)
34
41
  savepoint = await session.begin_nested()
35
42
  experiments = {
36
43
  experiment.id: experiment
@@ -54,10 +61,11 @@ class ExperimentMutationMixin:
54
61
  ]
55
62
  )
56
63
  )
57
- if project_names := set(filter(bool, (e.project_name for e in experiments.values()))):
58
- await session.execute(
59
- delete(models.Project).where(models.Project.name.in_(project_names))
60
- )
64
+ await asyncio.gather(
65
+ delete_projects(info.context.db, *project_names),
66
+ delete_traces(info.context.db, *eval_trace_ids),
67
+ return_exceptions=True,
68
+ )
61
69
  return ExperimentMutationPayload(
62
70
  experiments=[
63
71
  to_gql_experiment(experiments[experiment_id]) for experiment_id in experiment_ids
@@ -44,6 +44,7 @@ V1_ROUTES = [
44
44
  Route("/v1/spans", spans.get_spans_handler, methods=["GET"]),
45
45
  Route("/v1/datasets/upload", datasets.post_datasets_upload, methods=["POST"]),
46
46
  Route("/v1/datasets", datasets.list_datasets, methods=["GET"]),
47
+ Route("/v1/datasets/{id:str}", datasets.delete_dataset_by_id, methods=["DELETE"]),
47
48
  Route("/v1/datasets/{id:str}", datasets.get_dataset_by_id, methods=["GET"]),
48
49
  Route("/v1/datasets/{id:str}/csv", datasets.get_dataset_csv, methods=["GET"]),
49
50
  Route(
@@ -26,13 +26,15 @@ from typing import (
26
26
 
27
27
  import pandas as pd
28
28
  import pyarrow as pa
29
- from sqlalchemy import and_, func, select
29
+ from sqlalchemy import and_, delete, func, select
30
30
  from sqlalchemy.ext.asyncio import AsyncSession
31
+ from starlette.background import BackgroundTasks
31
32
  from starlette.concurrency import run_in_threadpool
32
33
  from starlette.datastructures import FormData, UploadFile
33
34
  from starlette.requests import Request
34
35
  from starlette.responses import JSONResponse, Response
35
36
  from starlette.status import (
37
+ HTTP_204_NO_CONTENT,
36
38
  HTTP_404_NOT_FOUND,
37
39
  HTTP_409_CONFLICT,
38
40
  HTTP_422_UNPROCESSABLE_ENTITY,
@@ -42,6 +44,7 @@ from strawberry.relay import GlobalID
42
44
  from typing_extensions import TypeAlias, assert_never
43
45
 
44
46
  from phoenix.db import models
47
+ from phoenix.db.helpers import get_eval_trace_ids_for_datasets, get_project_names_for_datasets
45
48
  from phoenix.db.insertion.dataset import (
46
49
  DatasetAction,
47
50
  DatasetExampleAdditionEvent,
@@ -52,6 +55,7 @@ from phoenix.server.api.types.Dataset import Dataset
52
55
  from phoenix.server.api.types.DatasetExample import DatasetExample
53
56
  from phoenix.server.api.types.DatasetVersion import DatasetVersion
54
57
  from phoenix.server.api.types.node import from_global_id_with_expected_type
58
+ from phoenix.server.api.utils import delete_projects, delete_traces
55
59
 
56
60
  logger = logging.getLogger(__name__)
57
61
 
@@ -163,6 +167,60 @@ async def list_datasets(request: Request) -> Response:
163
167
  return JSONResponse(content={"next_cursor": next_cursor, "data": data})
164
168
 
165
169
 
170
+ async def delete_dataset_by_id(request: Request) -> Response:
171
+ """
172
+ summary: Delete dataset by ID
173
+ operationId: deleteDatasetById
174
+ tags:
175
+ - datasets
176
+ parameters:
177
+ - in: path
178
+ name: id
179
+ required: true
180
+ schema:
181
+ type: string
182
+ responses:
183
+ 204:
184
+ description: Success
185
+ 403:
186
+ description: Forbidden
187
+ 404:
188
+ description: Dataset not found
189
+ 422:
190
+ description: Dataset ID is invalid
191
+ """
192
+ if id_ := request.path_params.get("id"):
193
+ try:
194
+ dataset_id = from_global_id_with_expected_type(
195
+ GlobalID.from_id(id_),
196
+ Dataset.__name__,
197
+ )
198
+ except ValueError:
199
+ return Response(
200
+ content=f"Invalid Dataset ID: {id_}",
201
+ status_code=HTTP_422_UNPROCESSABLE_ENTITY,
202
+ )
203
+ else:
204
+ return Response(
205
+ content="Missing Dataset ID",
206
+ status_code=HTTP_422_UNPROCESSABLE_ENTITY,
207
+ )
208
+ project_names_stmt = get_project_names_for_datasets(dataset_id)
209
+ eval_trace_ids_stmt = get_eval_trace_ids_for_datasets(dataset_id)
210
+ stmt = (
211
+ delete(models.Dataset).where(models.Dataset.id == dataset_id).returning(models.Dataset.id)
212
+ )
213
+ async with request.app.state.db() as session:
214
+ project_names = await session.scalars(project_names_stmt)
215
+ eval_trace_ids = await session.scalars(eval_trace_ids_stmt)
216
+ if (await session.scalar(stmt)) is None:
217
+ return Response(content="Dataset does not exist", status_code=HTTP_404_NOT_FOUND)
218
+ tasks = BackgroundTasks()
219
+ tasks.add_task(delete_projects, request.app.state.db, *project_names)
220
+ tasks.add_task(delete_traces, request.app.state.db, *eval_trace_ids)
221
+ return Response(status_code=HTTP_204_NO_CONTENT, background=tasks)
222
+
223
+
166
224
  async def get_dataset_by_id(request: Request) -> Response:
167
225
  """
168
226
  summary: Get dataset by ID
@@ -0,0 +1,36 @@
1
+ from typing import AsyncContextManager, Callable, List
2
+
3
+ from sqlalchemy import delete
4
+ from sqlalchemy.ext.asyncio import AsyncSession
5
+
6
+ from phoenix.db import models
7
+
8
+
9
+ async def delete_projects(
10
+ db: Callable[[], AsyncContextManager[AsyncSession]],
11
+ *project_names: str,
12
+ ) -> List[int]:
13
+ if not project_names:
14
+ return []
15
+ stmt = (
16
+ delete(models.Project)
17
+ .where(models.Project.name.in_(set(project_names)))
18
+ .returning(models.Project.id)
19
+ )
20
+ async with db() as session:
21
+ return list(await session.scalars(stmt))
22
+
23
+
24
+ async def delete_traces(
25
+ db: Callable[[], AsyncContextManager[AsyncSession]],
26
+ *trace_ids: str,
27
+ ) -> List[int]:
28
+ if not trace_ids:
29
+ return []
30
+ stmt = (
31
+ delete(models.Trace)
32
+ .where(models.Trace.trace_id.in_(set(trace_ids)))
33
+ .returning(models.Trace.id)
34
+ )
35
+ async with db() as session:
36
+ return list(await session.scalars(stmt))
@@ -7750,7 +7750,7 @@ fragment DatasetsTable_datasets on Query {
7750
7750
  __typename
7751
7751
  }
7752
7752
  }
7753
- `}}}();bat.hash="d98c682a2c908030c2f772209a4a25b8";var mat=bat;var Q0=P(ie()),Iat=P(wt());function pat(t){let{datasetId:e,datasetName:n,onDatasetDelete:i,onDatasetDeleteError:r}=t,[a,o]=(0,Q0.useState)(null),[l,s]=(0,Iat.useMutation)(mat),c=(0,Q0.useCallback)(()=>{(0,Q0.startTransition)(()=>{l({variables:{datasetId:e},onCompleted:()=>{i()},onError:g=>{r(g)}})})},[l,e,i,r]),u=(0,Q0.useCallback)(()=>{o(B(Mn,{size:"S",title:"Delete Dataset",children:[h(De,{padding:"size-200",children:h(me,{color:"danger",children:`Are you sure you want to delete dataset ${n}? This cannot be undone.`})}),h(De,{paddingEnd:"size-200",paddingTop:"size-100",paddingBottom:"size-100",borderTopColor:"light",borderTopWidth:"thin",children:h(ge,{direction:"row",justifyContent:"end",children:h(At,{variant:"danger",onClick:()=>{c(),o(null)},children:"Delete Dataset"})})})]}))},[c,n]);return B("div",{onClick:g=>{g.preventDefault(),g.stopPropagation()},children:[h(Gc,{align:"end",buttonSize:"compact",isDisabled:s,onAction:g=>{switch(g){case"deleteDataset":u();break}},children:h(Ht,{children:B(ge,{direction:"row",gap:"size-75",justifyContent:"start",alignItems:"center",children:[h(ke,{svg:h(Pe.TrashOutline,{})}),h(me,{children:"Delete"})]})},"deleteDataset")}),h(Fn,{type:"modal",isDismissable:!0,onDismiss:()=>o(null),children:a})]})}var hat=100;function cGn(t){let e=t.id;if(e!=="createdAt"&&e!=="name")throw new Error("Invalid sort column");return{col:e,dir:t.desc?"desc":"asc"}}function Cat(t){let[e,n]=(0,cd.useState)([]),i=(0,cd.useRef)(null),r=Zn(),a=Zo(),o=dm(),{data:l,loadNext:s,hasNext:c,isLoadingNext:u,refetch:g}=(0,fat.usePaginationFragment)(dat,t.query),d=(0,cd.useMemo)(()=>l.datasets.edges.map(f=>f.node),[l]),b=cd.default.useCallback(f=>{if(f){let{scrollHeight:C,scrollTop:v,clientHeight:x}=f;C-v-x<300&&!u&&c&&s(hat)}},[c,u,s]),m=Gr({columns:[{header:"name",accessorKey:"name",cell:({row:f})=>{let v=f.original.experimentCount>0?`${f.original.id}/experiments`:`${f.original.id}/examples`;return h(_l,{to:v,children:f.original.name})}},{header:"description",accessorKey:"description",enableSorting:!1},{header:"created at",accessorKey:"createdAt",cell:sd},{header:"example count",accessorKey:"exampleCount",enableSorting:!1,meta:{textAlign:"right"}},{header:"experiment count",accessorKey:"experimentCount",enableSorting:!1,meta:{textAlign:"right"}},{header:"",id:"actions",enableSorting:!1,size:10,cell:({row:f})=>h(pat,{datasetId:f.original.id,datasetName:f.original.name,onDatasetDelete:()=>{a({title:"Dataset deleted",message:`${f.original.name} has been successfully deleted.`}),g({},{fetchPolicy:"store-and-network"})},onDatasetDeleteError:C=>{o({title:"Dataset deletion failed",message:C.message})}})}],data:d,state:{sorting:e},getCoreRowModel:Wr(),getSortedRowModel:Zg(),onSortingChange:n,manualSorting:!0});(0,cd.useEffect)(()=>{let f=e[0];(0,cd.startTransition)(()=>{g({sort:f?cGn(f):{col:"createdAt",dir:"desc"},after:null,first:hat},{fetchPolicy:"store-and-network"})})},[e,g]);let I=m.getRowModel().rows,p=I.length===0;return h("div",{css:$`
7753
+ `}}}();bat.hash="d98c682a2c908030c2f772209a4a25b8";var mat=bat;var Q0=P(ie()),Iat=P(wt());function pat(t){let{datasetId:e,datasetName:n,onDatasetDelete:i,onDatasetDeleteError:r}=t,[a,o]=(0,Q0.useState)(null),[l,s]=(0,Iat.useMutation)(mat),c=(0,Q0.useCallback)(()=>{(0,Q0.startTransition)(()=>{l({variables:{datasetId:e},onCompleted:()=>{i()},onError:g=>{r(g)}})})},[l,e,i,r]),u=(0,Q0.useCallback)(()=>{o(B(Mn,{size:"S",title:"Delete Dataset",children:[h(De,{padding:"size-200",children:h(me,{color:"danger",children:`Are you sure you want to delete dataset ${n}? This will also delete all associated experiments and traces, and it cannot be undone.`})}),h(De,{paddingEnd:"size-200",paddingTop:"size-100",paddingBottom:"size-100",borderTopColor:"light",borderTopWidth:"thin",children:h(ge,{direction:"row",justifyContent:"end",children:h(At,{variant:"danger",onClick:()=>{c(),o(null)},children:"Delete Dataset"})})})]}))},[c,n]);return B("div",{onClick:g=>{g.preventDefault(),g.stopPropagation()},children:[h(Gc,{align:"end",buttonSize:"compact",isDisabled:s,onAction:g=>{switch(g){case"deleteDataset":u();break}},children:h(Ht,{children:B(ge,{direction:"row",gap:"size-75",justifyContent:"start",alignItems:"center",children:[h(ke,{svg:h(Pe.TrashOutline,{})}),h(me,{children:"Delete"})]})},"deleteDataset")}),h(Fn,{type:"modal",isDismissable:!0,onDismiss:()=>o(null),children:a})]})}var hat=100;function cGn(t){let e=t.id;if(e!=="createdAt"&&e!=="name")throw new Error("Invalid sort column");return{col:e,dir:t.desc?"desc":"asc"}}function Cat(t){let[e,n]=(0,cd.useState)([]),i=(0,cd.useRef)(null),r=Zn(),a=Zo(),o=dm(),{data:l,loadNext:s,hasNext:c,isLoadingNext:u,refetch:g}=(0,fat.usePaginationFragment)(dat,t.query),d=(0,cd.useMemo)(()=>l.datasets.edges.map(f=>f.node),[l]),b=cd.default.useCallback(f=>{if(f){let{scrollHeight:C,scrollTop:v,clientHeight:x}=f;C-v-x<300&&!u&&c&&s(hat)}},[c,u,s]),m=Gr({columns:[{header:"name",accessorKey:"name",cell:({row:f})=>{let v=f.original.experimentCount>0?`${f.original.id}/experiments`:`${f.original.id}/examples`;return h(_l,{to:v,children:f.original.name})}},{header:"description",accessorKey:"description",enableSorting:!1},{header:"created at",accessorKey:"createdAt",cell:sd},{header:"example count",accessorKey:"exampleCount",enableSorting:!1,meta:{textAlign:"right"}},{header:"experiment count",accessorKey:"experimentCount",enableSorting:!1,meta:{textAlign:"right"}},{header:"",id:"actions",enableSorting:!1,size:10,cell:({row:f})=>h(pat,{datasetId:f.original.id,datasetName:f.original.name,onDatasetDelete:()=>{a({title:"Dataset deleted",message:`${f.original.name} has been successfully deleted.`}),g({},{fetchPolicy:"store-and-network"})},onDatasetDeleteError:C=>{o({title:"Dataset deletion failed",message:C.message})}})}],data:d,state:{sorting:e},getCoreRowModel:Wr(),getSortedRowModel:Zg(),onSortingChange:n,manualSorting:!0});(0,cd.useEffect)(()=>{let f=e[0];(0,cd.startTransition)(()=>{g({sort:f?cGn(f):{col:"createdAt",dir:"desc"},after:null,first:hat},{fetchPolicy:"store-and-network"})})},[e,g]);let I=m.getRowModel().rows,p=I.length===0;return h("div",{css:$`
7754
7754
  flex: 1 1 auto;
7755
7755
  overflow: auto;
7756
7756
  `,onScroll:f=>b(f.target),ref:i,children:B("table",{css:wg,children:[h("thead",{children:m.getHeaderGroups().map(f=>h("tr",{children:f.headers.map(C=>h("th",{colSpan:C.colSpan,children:C.isPlaceholder?null:B("div",{className:C.column.getCanSort()?"cursor-pointer":"",onClick:C.column.getToggleSortingHandler(),style:{textAlign:C.column.columnDef.meta?.textAlign},children:[Hn(C.column.columnDef.header,C.getContext()),C.column.getIsSorted()?h(ke,{className:"sort-icon",svg:C.column.getIsSorted()==="asc"?h(Pe.ArrowUpFilled,{}):h(Pe.ArrowDownFilled,{})}):null]})},C.id))},f.id))}),p?h(Ul,{}):h("tbody",{children:I.map(f=>h("tr",{onClick:()=>{let v=f.original.experimentCount>0?`${f.original.id}/experiments`:`${f.original.id}/examples`;r(v)},children:f.getVisibleCells().map(C=>h("td",{align:C.column.columnDef.meta?.textAlign,children:Hn(C.column.columnDef.cell,C.getContext())},C.id))},f.id))})]})})}function yat(){return h(K0.Suspense,{fallback:h(Qr,{}),children:h(uGn,{})})}function uGn(){let[t,e]=(0,K0.useState)(0),n=(0,Aat.useLazyLoadQuery)(oat,{},{fetchKey:t}),i=(0,K0.useCallback)(()=>{e(r=>r+1)},[e]);return B(ge,{direction:"column",height:"100%",children:[h(De,{padding:"size-200",borderBottomWidth:"thin",borderBottomColor:"dark",flex:"none",children:B(ge,{direction:"row",justifyContent:"space-between",children:[h(dn,{level:1,children:"Datasets"}),h(gGn,{onDatasetCreated:i})]})}),h(Cat,{query:n})]})}function gGn({onDatasetCreated:t}){let e=Zn(),n=Zo(),i=dm(),[r,a]=(0,K0.useState)(null),o=()=>{a(h(Mn,{size:"S",title:"New Dataset",children:h(rY,{onDatasetCreated:s=>{n({title:"Dataset created",message:`${s.name} has been successfully created.`,action:{text:"Go to Dataset",onClick:()=>{e(`/datasets/${s.id}`)}}}),a(null),t()},onDatasetCreateError:s=>{i({title:"Dataset creation failed",message:s.message})}})}))},l=()=>{a(h(Mn,{size:"M",title:"New Dataset from CSV",children:h(lat,{onDatasetCreated:s=>{n({title:"Dataset created",message:`${s.name} has been successfully created.`,action:{text:"Go to Dataset",onClick:()=>{e(`/datasets/${s.id}`)}}}),a(null),t()},onDatasetCreateError:s=>{i({title:"Dataset creation failed",message:s.message})}})}))};return B($t,{children:[B(Gc,{buttonText:"Create Dataset",align:"end",icon:h(ke,{svg:h(Pe.DatabaseOutline,{})}),onAction:s=>{switch(s){case"newDataset":o();break;case"datasetFromCSV":l();break}},children:[h(Ht,{children:"New Dataset"},"newDataset"),h(Ht,{children:"Dataset from CSV"},"datasetFromCSV")]}),h(Fn,{type:"modal",isDismissable:!0,onDismiss:()=>a(null),children:r})]})}var tA=P(ie());var uY=P(ie());var vat=function(){var t=[{defaultValue:null,kind:"LocalArgument",name:"datasetId"}],e=[{kind:"Variable",name:"id",variableName:"datasetId"}],n={alias:null,args:null,kind:"ScalarField",name:"id",storageKey:null},i={kind:"InlineFragment",selections:[{alias:"latestVersions",args:[{kind:"Literal",name:"first",value:1},{kind:"Literal",name:"sort",value:{col:"createdAt",dir:"desc"}}],concreteType:"DatasetVersionConnection",kind:"LinkedField",name:"versions",plural:!1,selections:[{alias:null,args:null,concreteType:"DatasetVersionEdge",kind:"LinkedField",name:"edges",plural:!0,selections:[{alias:"version",args:null,concreteType:"DatasetVersion",kind:"LinkedField",name:"node",plural:!1,selections:[n,{alias:null,args:null,kind:"ScalarField",name:"description",storageKey:null},{alias:null,args:null,kind:"ScalarField",name:"createdAt",storageKey:null}],storageKey:null}],storageKey:null}],storageKey:'versions(first:1,sort:{"col":"createdAt","dir":"desc"})'}],type:"Dataset",abstractKey:null};return{fragment:{argumentDefinitions:t,kind:"Fragment",metadata:null,name:"datasetStore_latestVersionQuery",selections:[{alias:"dataset",args:e,concreteType:null,kind:"LinkedField",name:"node",plural:!1,selections:[n,i],storageKey:null}],type:"Query",abstractKey:null},kind:"Request",operation:{argumentDefinitions:t,kind:"Operation",name:"datasetStore_latestVersionQuery",selections:[{alias:"dataset",args:e,concreteType:null,kind:"LinkedField",name:"node",plural:!1,selections:[{alias:null,args:null,kind:"ScalarField",name:"__typename",storageKey:null},n,i],storageKey:null}]},params:{cacheID:"d7075240e4dae8871997e57616c05302",id:null,metadata:{},name:"datasetStore_latestVersionQuery",operationKind:"query",text:`query datasetStore_latestVersionQuery(
@@ -8152,7 +8152,7 @@ fragment ExperimentsTableFragment on Dataset {
8152
8152
  __typename
8153
8153
  }
8154
8154
  }
8155
- `}}}();Vot.hash="4ab310746eb51c6a3fcb799d2c972762";var Eot=Vot;var a3=P(ie()),Jot=P(wt());function Hot(t){let e=Zn(),[n,i]=(0,a3.useState)(null),[r,a]=(0,Jot.useMutation)(Eot),{datasetId:o,selectedExperiments:l,onClearSelection:s,onExperimentsDeleted:c}=t,u=l.length!==1,g=Zo(),d=dm(),b=(0,a3.useCallback)(()=>{r({variables:{input:{experimentIds:l.map(I=>I.id)}},onCompleted:()=>{g({title:"Examples Deleted",message:`${l.length} experiment${u?"s":""} have been deleted.`}),c(),s()},onError:I=>{d({title:"An error occurred",message:`Failed to delete examples: ${I.message}`})}})},[r,u,d,g,s,c,l]),m=(0,a3.useCallback)(()=>{i(B(Mn,{size:"S",title:"Delete Experiments",children:[h(De,{padding:"size-200",children:h(me,{color:"danger",children:"Are you sure you want to delete these experiments? This cannot be undone."})}),h(De,{paddingEnd:"size-200",paddingTop:"size-100",paddingBottom:"size-100",borderTopColor:"light",borderTopWidth:"thin",children:h(ge,{direction:"row",justifyContent:"end",children:h(At,{variant:"danger",onClick:()=>{b(),i(null)},children:"Delete Experiments"})})})]}))},[b]);return B("div",{css:$`
8155
+ `}}}();Vot.hash="4ab310746eb51c6a3fcb799d2c972762";var Eot=Vot;var a3=P(ie()),Jot=P(wt());function Hot(t){let e=Zn(),[n,i]=(0,a3.useState)(null),[r,a]=(0,Jot.useMutation)(Eot),{datasetId:o,selectedExperiments:l,onClearSelection:s,onExperimentsDeleted:c}=t,u=l.length!==1,g=Zo(),d=dm(),b=(0,a3.useCallback)(()=>{r({variables:{input:{experimentIds:l.map(I=>I.id)}},onCompleted:()=>{g({title:"Examples Deleted",message:`${l.length} experiment${u?"s":""} have been deleted.`}),c(),s()},onError:I=>{d({title:"An error occurred",message:`Failed to delete examples: ${I.message}`})}})},[r,u,d,g,s,c,l]),m=(0,a3.useCallback)(()=>{i(B(Mn,{size:"S",title:"Delete Experiments",children:[h(De,{padding:"size-200",children:h(me,{color:"danger",children:"Are you sure you want to delete these experiments? This will also delete all associated annotations and traces, and it cannot be undone."})}),h(De,{paddingEnd:"size-200",paddingTop:"size-100",paddingBottom:"size-100",borderTopColor:"light",borderTopWidth:"thin",children:h(ge,{direction:"row",justifyContent:"end",children:h(At,{variant:"danger",onClick:()=>{b(),i(null)},children:"Delete Experiments"})})})]}))},[b]);return B("div",{css:$`
8156
8156
  position: absolute;
8157
8157
  bottom: var(--ac-global-dimension-size-400);
8158
8158
  left: 50%;
@@ -0,0 +1 @@
1
+ __version__ = "4.8.0"
@@ -1 +0,0 @@
1
- __version__ = "4.7.2"
File without changes
File without changes
File without changes
File without changes