arize-phoenix 4.21.0__tar.gz → 4.22.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of arize-phoenix might be problematic. Click here for more details.

Files changed (302) hide show
  1. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/PKG-INFO +1 -1
  2. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/examples/manually-instrumented-chatbot/chat-service/chat/app.py +3 -3
  3. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/pyproject.toml +7 -0
  4. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/config.py +59 -1
  5. arize_phoenix-4.22.1/src/phoenix/db/migrations/future_versions/README.md +4 -0
  6. arize_phoenix-4.22.1/src/phoenix/db/migrations/future_versions/cd164e83824f_users_and_tokens.py +292 -0
  7. arize_phoenix-4.22.1/src/phoenix/db/migrations/versions/.gitignore +1 -0
  8. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/db/models.py +61 -0
  9. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/experiments/functions.py +4 -4
  10. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/experiments/types.py +3 -3
  11. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/context.py +0 -6
  12. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/dataloaders/__init__.py +0 -9
  13. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/routers/v1/experiment_runs.py +7 -2
  14. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/types/Evaluation.py +1 -26
  15. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/types/Project.py +1 -60
  16. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/types/Span.py +1 -9
  17. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/app.py +0 -11
  18. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/dml_event_handler.py +0 -3
  19. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/static/.vite/manifest.json +9 -9
  20. arize_phoenix-4.21.0/src/phoenix/server/static/assets/components-D2V-mOGq.js → arize_phoenix-4.22.1/src/phoenix/server/static/assets/components-BC3-LP_a.js +44 -44
  21. arize_phoenix-4.21.0/src/phoenix/server/static/assets/index-B52Z3aZG.js → arize_phoenix-4.22.1/src/phoenix/server/static/assets/index-BjJvafYL.js +1 -1
  22. arize_phoenix-4.21.0/src/phoenix/server/static/assets/pages-CChOjmat.js → arize_phoenix-4.22.1/src/phoenix/server/static/assets/pages--n2933VW.js +214 -195
  23. arize_phoenix-4.22.1/src/phoenix/version.py +1 -0
  24. arize_phoenix-4.21.0/src/phoenix/server/api/dataloaders/evaluation_summaries.py +0 -149
  25. arize_phoenix-4.21.0/src/phoenix/server/api/dataloaders/span_evaluations.py +0 -35
  26. arize_phoenix-4.21.0/src/phoenix/server/api/dataloaders/trace_evaluations.py +0 -35
  27. arize_phoenix-4.21.0/src/phoenix/version.py +0 -1
  28. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/.gitignore +0 -0
  29. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/IP_NOTICE +0 -0
  30. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/LICENSE +0 -0
  31. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/README.md +0 -0
  32. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/examples/manually-instrumented-chatbot/chat-service/chat/__init__.py +0 -0
  33. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/examples/manually-instrumented-chatbot/chat-service/chat/types.py +0 -0
  34. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/examples/manually-instrumented-chatbot/frontend/Dockerfile +0 -0
  35. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/examples/manually-instrumented-chatbot/frontend/Makefile +0 -0
  36. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/examples/manually-instrumented-chatbot/frontend/__init__.py +0 -0
  37. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/examples/manually-instrumented-chatbot/frontend/pyproject.toml +0 -0
  38. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/examples/manually-instrumented-chatbot/frontend/requirements.txt +0 -0
  39. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/examples/manually-instrumented-chatbot/frontend/schema.json +0 -0
  40. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/__init__.py +0 -0
  41. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/core/__init__.py +0 -0
  42. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/core/embedding_dimension.py +0 -0
  43. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/core/model.py +0 -0
  44. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/core/model_schema.py +0 -0
  45. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/core/model_schema_adapter.py +0 -0
  46. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/datetime_utils.py +0 -0
  47. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/db/README.md +0 -0
  48. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/db/__init__.py +0 -0
  49. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/db/alembic.ini +0 -0
  50. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/db/bulk_inserter.py +0 -0
  51. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/db/engines.py +0 -0
  52. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/db/helpers.py +0 -0
  53. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/db/insertion/__init__.py +0 -0
  54. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/db/insertion/constants.py +0 -0
  55. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/db/insertion/dataset.py +0 -0
  56. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/db/insertion/document_annotation.py +0 -0
  57. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/db/insertion/evaluation.py +0 -0
  58. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/db/insertion/helpers.py +0 -0
  59. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/db/insertion/span.py +0 -0
  60. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/db/insertion/span_annotation.py +0 -0
  61. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/db/insertion/trace_annotation.py +0 -0
  62. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/db/insertion/types.py +0 -0
  63. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/db/migrate.py +0 -0
  64. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/db/migrations/__init__.py +0 -0
  65. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/db/migrations/env.py +0 -0
  66. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/db/migrations/script.py.mako +0 -0
  67. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/db/migrations/versions/10460e46d750_datasets.py +0 -0
  68. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/db/migrations/versions/3be8647b87d8_add_token_columns_to_spans_table.py +0 -0
  69. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/db/migrations/versions/cf03bd6bae1d_init.py +0 -0
  70. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/exceptions.py +0 -0
  71. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/experiments/__init__.py +0 -0
  72. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/experiments/evaluators/__init__.py +0 -0
  73. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/experiments/evaluators/base.py +0 -0
  74. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/experiments/evaluators/code_evaluators.py +0 -0
  75. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/experiments/evaluators/llm_evaluators.py +0 -0
  76. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/experiments/evaluators/utils.py +0 -0
  77. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/experiments/tracing.py +0 -0
  78. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/experiments/utils.py +0 -0
  79. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/inferences/__init__.py +0 -0
  80. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/inferences/errors.py +0 -0
  81. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/inferences/fixtures.py +0 -0
  82. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/inferences/inferences.py +0 -0
  83. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/inferences/schema.py +0 -0
  84. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/inferences/validation.py +0 -0
  85. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/metrics/README.md +0 -0
  86. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/metrics/__init__.py +0 -0
  87. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/metrics/binning.py +0 -0
  88. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/metrics/metrics.py +0 -0
  89. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/metrics/mixins.py +0 -0
  90. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/metrics/retrieval_metrics.py +0 -0
  91. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/metrics/timeseries.py +0 -0
  92. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/metrics/wrappers.py +0 -0
  93. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/pointcloud/__init__.py +0 -0
  94. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/pointcloud/clustering.py +0 -0
  95. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/pointcloud/pointcloud.py +0 -0
  96. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/pointcloud/projectors.py +0 -0
  97. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/pointcloud/umap_parameters.py +0 -0
  98. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/py.typed +0 -0
  99. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/__init__.py +0 -0
  100. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/__init__.py +0 -0
  101. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/dataloaders/annotation_summaries.py +0 -0
  102. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/dataloaders/average_experiment_run_latency.py +0 -0
  103. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/dataloaders/cache/__init__.py +0 -0
  104. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/dataloaders/cache/two_tier_cache.py +0 -0
  105. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/dataloaders/dataset_example_revisions.py +0 -0
  106. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/dataloaders/dataset_example_spans.py +0 -0
  107. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/dataloaders/document_evaluation_summaries.py +0 -0
  108. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/dataloaders/document_evaluations.py +0 -0
  109. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/dataloaders/document_retrieval_metrics.py +0 -0
  110. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/dataloaders/experiment_annotation_summaries.py +0 -0
  111. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/dataloaders/experiment_error_rates.py +0 -0
  112. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/dataloaders/experiment_run_counts.py +0 -0
  113. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/dataloaders/experiment_sequence_number.py +0 -0
  114. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/dataloaders/latency_ms_quantile.py +0 -0
  115. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/dataloaders/min_start_or_max_end_times.py +0 -0
  116. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/dataloaders/project_by_name.py +0 -0
  117. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/dataloaders/record_counts.py +0 -0
  118. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/dataloaders/span_annotations.py +0 -0
  119. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/dataloaders/span_dataset_examples.py +0 -0
  120. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/dataloaders/span_descendants.py +0 -0
  121. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/dataloaders/span_projects.py +0 -0
  122. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/dataloaders/token_counts.py +0 -0
  123. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/dataloaders/trace_row_ids.py +0 -0
  124. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/helpers/__init__.py +0 -0
  125. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/helpers/dataset_helpers.py +0 -0
  126. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/input_types/AddExamplesToDatasetInput.py +0 -0
  127. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/input_types/AddSpansToDatasetInput.py +0 -0
  128. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/input_types/ClearProjectInput.py +0 -0
  129. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/input_types/ClusterInput.py +0 -0
  130. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/input_types/Coordinates.py +0 -0
  131. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/input_types/CreateDatasetInput.py +0 -0
  132. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/input_types/CreateSpanAnnotationInput.py +0 -0
  133. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/input_types/CreateTraceAnnotationInput.py +0 -0
  134. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/input_types/DataQualityMetricInput.py +0 -0
  135. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/input_types/DatasetExampleInput.py +0 -0
  136. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/input_types/DatasetSort.py +0 -0
  137. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/input_types/DatasetVersionSort.py +0 -0
  138. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/input_types/DeleteAnnotationsInput.py +0 -0
  139. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/input_types/DeleteDatasetExamplesInput.py +0 -0
  140. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/input_types/DeleteDatasetInput.py +0 -0
  141. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/input_types/DeleteExperimentsInput.py +0 -0
  142. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/input_types/DimensionFilter.py +0 -0
  143. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/input_types/DimensionInput.py +0 -0
  144. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/input_types/Granularity.py +0 -0
  145. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/input_types/PatchAnnotationInput.py +0 -0
  146. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/input_types/PatchDatasetExamplesInput.py +0 -0
  147. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/input_types/PatchDatasetInput.py +0 -0
  148. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/input_types/PerformanceMetricInput.py +0 -0
  149. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/input_types/SpanAnnotationSort.py +0 -0
  150. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/input_types/SpanSort.py +0 -0
  151. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/input_types/TimeRange.py +0 -0
  152. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/input_types/TraceAnnotationSort.py +0 -0
  153. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/input_types/__init__.py +0 -0
  154. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/interceptor.py +0 -0
  155. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/mutations/__init__.py +0 -0
  156. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/mutations/auth.py +0 -0
  157. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/mutations/dataset_mutations.py +0 -0
  158. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/mutations/experiment_mutations.py +0 -0
  159. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/mutations/export_events_mutations.py +0 -0
  160. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/mutations/project_mutations.py +0 -0
  161. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/mutations/span_annotations_mutations.py +0 -0
  162. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/mutations/trace_annotations_mutations.py +0 -0
  163. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/openapi/__init__.py +0 -0
  164. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/openapi/main.py +0 -0
  165. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/openapi/schema.py +0 -0
  166. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/queries.py +0 -0
  167. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/routers/__init__.py +0 -0
  168. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/routers/utils.py +0 -0
  169. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/routers/v1/__init__.py +0 -0
  170. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/routers/v1/datasets.py +0 -0
  171. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/routers/v1/evaluations.py +0 -0
  172. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/routers/v1/experiment_evaluations.py +0 -0
  173. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/routers/v1/experiments.py +0 -0
  174. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/routers/v1/pydantic_compat.py +0 -0
  175. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/routers/v1/spans.py +0 -0
  176. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/routers/v1/traces.py +0 -0
  177. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/routers/v1/utils.py +0 -0
  178. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/schema.py +0 -0
  179. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/types/Annotation.py +0 -0
  180. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/types/AnnotationSummary.py +0 -0
  181. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/types/AnnotatorKind.py +0 -0
  182. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/types/Cluster.py +0 -0
  183. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/types/CreateDatasetPayload.py +0 -0
  184. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/types/DataQualityMetric.py +0 -0
  185. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/types/Dataset.py +0 -0
  186. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/types/DatasetExample.py +0 -0
  187. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/types/DatasetExampleRevision.py +0 -0
  188. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/types/DatasetValues.py +0 -0
  189. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/types/DatasetVersion.py +0 -0
  190. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/types/Dimension.py +0 -0
  191. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/types/DimensionDataType.py +0 -0
  192. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/types/DimensionShape.py +0 -0
  193. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/types/DimensionType.py +0 -0
  194. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/types/DimensionWithValue.py +0 -0
  195. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/types/DocumentEvaluationSummary.py +0 -0
  196. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/types/DocumentRetrievalMetrics.py +0 -0
  197. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/types/EmbeddingDimension.py +0 -0
  198. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/types/EmbeddingMetadata.py +0 -0
  199. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/types/EvaluationSummary.py +0 -0
  200. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/types/Event.py +0 -0
  201. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/types/EventMetadata.py +0 -0
  202. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/types/ExampleRevisionInterface.py +0 -0
  203. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/types/Experiment.py +0 -0
  204. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/types/ExperimentAnnotationSummary.py +0 -0
  205. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/types/ExperimentComparison.py +0 -0
  206. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/types/ExperimentRun.py +0 -0
  207. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/types/ExperimentRunAnnotation.py +0 -0
  208. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/types/ExportedFile.py +0 -0
  209. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/types/Functionality.py +0 -0
  210. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/types/Inferences.py +0 -0
  211. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/types/InferencesRole.py +0 -0
  212. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/types/LabelFraction.py +0 -0
  213. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/types/MimeType.py +0 -0
  214. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/types/Model.py +0 -0
  215. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/types/NumericRange.py +0 -0
  216. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/types/PerformanceMetric.py +0 -0
  217. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/types/PromptResponse.py +0 -0
  218. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/types/Retrieval.py +0 -0
  219. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/types/ScalarDriftMetricEnum.py +0 -0
  220. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/types/Segments.py +0 -0
  221. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/types/SortDir.py +0 -0
  222. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/types/SpanAnnotation.py +0 -0
  223. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/types/TimeSeries.py +0 -0
  224. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/types/Trace.py +0 -0
  225. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/types/TraceAnnotation.py +0 -0
  226. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/types/UMAPPoints.py +0 -0
  227. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/types/ValidationResult.py +0 -0
  228. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/types/VectorDriftMetricEnum.py +0 -0
  229. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/types/__init__.py +0 -0
  230. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/types/node.py +0 -0
  231. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/types/pagination.py +0 -0
  232. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/api/utils.py +0 -0
  233. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/dml_event.py +0 -0
  234. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/grpc_server.py +0 -0
  235. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/main.py +0 -0
  236. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/openapi/__init__.py +0 -0
  237. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/prometheus.py +0 -0
  238. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/static/apple-touch-icon-114x114.png +0 -0
  239. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/static/apple-touch-icon-120x120.png +0 -0
  240. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/static/apple-touch-icon-144x144.png +0 -0
  241. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/static/apple-touch-icon-152x152.png +0 -0
  242. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/static/apple-touch-icon-180x180.png +0 -0
  243. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/static/apple-touch-icon-72x72.png +0 -0
  244. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/static/apple-touch-icon-76x76.png +0 -0
  245. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/static/apple-touch-icon.png +0 -0
  246. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/static/assets/vendor-BMWfu6zp.js +0 -0
  247. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/static/assets/vendor-DxkFTwjz.css +0 -0
  248. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/static/assets/vendor-arizeai-Sj74jm5V.js +0 -0
  249. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/static/assets/vendor-codemirror-DO3VqEcD.js +0 -0
  250. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/static/assets/vendor-recharts-BGN0SxgJ.js +0 -0
  251. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/static/assets/vendor-three-DwGkEfCM.js +0 -0
  252. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/static/favicon.ico +0 -0
  253. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/static/modernizr.js +0 -0
  254. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/telemetry.py +0 -0
  255. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/templates/__init__.py +0 -0
  256. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/templates/index.html +0 -0
  257. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/thread_server.py +0 -0
  258. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/server/types.py +0 -0
  259. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/services.py +0 -0
  260. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/session/__init__.py +0 -0
  261. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/session/client.py +0 -0
  262. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/session/data_extractor.py +0 -0
  263. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/session/evaluation.py +0 -0
  264. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/session/session.py +0 -0
  265. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/settings.py +0 -0
  266. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/trace/__init__.py +0 -0
  267. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/trace/attributes.py +0 -0
  268. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/trace/dsl/README.md +0 -0
  269. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/trace/dsl/__init__.py +0 -0
  270. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/trace/dsl/filter.py +0 -0
  271. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/trace/dsl/helpers.py +0 -0
  272. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/trace/dsl/query.py +0 -0
  273. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/trace/errors.py +0 -0
  274. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/trace/evaluation_conventions.py +0 -0
  275. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/trace/exporter.py +0 -0
  276. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/trace/fixtures.py +0 -0
  277. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/trace/langchain/__init__.py +0 -0
  278. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/trace/langchain/instrumentor.py +0 -0
  279. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/trace/llama_index/__init__.py +0 -0
  280. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/trace/llama_index/callback.py +0 -0
  281. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/trace/openai/__init__.py +0 -0
  282. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/trace/openai/instrumentor.py +0 -0
  283. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/trace/otel.py +0 -0
  284. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/trace/projects.py +0 -0
  285. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/trace/schemas.py +0 -0
  286. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/trace/span_evaluations.py +0 -0
  287. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/trace/span_json_decoder.py +0 -0
  288. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/trace/span_json_encoder.py +0 -0
  289. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/trace/trace_dataset.py +0 -0
  290. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/trace/utils.py +0 -0
  291. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/trace/v1/__init__.py +0 -0
  292. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/trace/v1/evaluation_pb2.py +0 -0
  293. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/trace/v1/evaluation_pb2.pyi +0 -0
  294. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/utilities/__init__.py +0 -0
  295. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/utilities/client.py +0 -0
  296. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/utilities/deprecation.py +0 -0
  297. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/utilities/error_handling.py +0 -0
  298. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/utilities/json.py +0 -0
  299. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/utilities/logging.py +0 -0
  300. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/utilities/project.py +0 -0
  301. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/utilities/re.py +0 -0
  302. {arize_phoenix-4.21.0 → arize_phoenix-4.22.1}/src/phoenix/utilities/span_store.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: arize-phoenix
3
- Version: 4.21.0
3
+ Version: 4.22.1
4
4
  Summary: AI Observability and Evaluation
5
5
  Project-URL: Documentation, https://docs.arize.com/phoenix/
6
6
  Project-URL: Issues, https://github.com/Arize-ai/phoenix/issues
@@ -106,15 +106,15 @@ async def messages(messages_payload: MessagesPayload) -> MessagesResponse:
106
106
  @app.post("/feedback/")
107
107
  async def post_feedback(feedback_request: FeedbackRequest) -> None:
108
108
  if feedback_request.feedback == 1:
109
- label = "thumbs_up"
109
+ label = "👍"
110
110
  elif feedback_request.feedback == 0:
111
- label = "thumbs_down"
111
+ label = "👎"
112
112
 
113
113
  request_body = {
114
114
  "data": [
115
115
  {
116
116
  "span_id": feedback_request.span_id,
117
- "name": "correctness",
117
+ "name": "user_feedback",
118
118
  "annotator_kind": "HUMAN",
119
119
  "result": {"label": label, "score": feedback_request.feedback},
120
120
  "metadata": {},
@@ -288,6 +288,12 @@ clean = [
288
288
  "jupyter nbconvert --ClearOutputPreprocessor.enabled=True --ClearMetadataPreprocessor.enabled=True --inplace **/*.ipynb **/internal/*.ipynb **/tracing/*.ipynb **/dolly-pythia-fine-tuned/*.ipynb",
289
289
  ]
290
290
 
291
+ [tool.hatch.envs.auth.scripts]
292
+ link = "cd src/phoenix/db/migrations/versions && ln -s ../future_versions/cd164e83824f_users_and_tokens.py cd164e83824f_users_and_tokens.py && echo 'created auth migration symlink'"
293
+ unlink = "rm src/phoenix/db/migrations/versions/cd164e83824f_users_and_tokens.py && echo 'removed auth migration symlink'"
294
+ up = "cd src/phoenix/db && alembic upgrade cd164e83824f && echo 'ran auth up-migration'"
295
+ down = "cd src/phoenix/db && alembic downgrade 3be8647b87d8 && echo 'ran auth down-migration'"
296
+
291
297
  [tool.hatch.envs.publish]
292
298
  dependencies = [
293
299
  "check-wheel-contents",
@@ -300,6 +306,7 @@ testpypi = [
300
306
  "twine upload --verbose --repository testpypi dist/*",
301
307
  ]
302
308
  pypi = [
309
+ "if [ -L src/phoenix/db/migrations/versions/cd164e83824f_users_and_tokens.py ]; then echo 'remove auth migration symlink before publishing with `hatch run auth:unlink`'; exit 1; fi",
303
310
  "check-wheel-contents dist/",
304
311
  "twine upload --verbose dist/*",
305
312
  ]
@@ -2,7 +2,7 @@ import os
2
2
  import tempfile
3
3
  from logging import getLogger
4
4
  from pathlib import Path
5
- from typing import Dict, List, Optional
5
+ from typing import Dict, List, Optional, Tuple
6
6
 
7
7
  from .utilities.re import parse_env_headers
8
8
 
@@ -60,6 +60,11 @@ ENV_PHOENIX_SERVER_INSTRUMENTATION_OTLP_TRACE_COLLECTOR_GRPC_ENDPOINT = (
60
60
  "PHOENIX_SERVER_INSTRUMENTATION_OTLP_TRACE_COLLECTOR_GRPC_ENDPOINT"
61
61
  )
62
62
 
63
+ # Auth is under active development. Phoenix users are strongly advised not to
64
+ # set these environment variables until the feature is officially released.
65
+ ENV_DANGEROUSLY_SET_PHOENIX_ENABLE_AUTH = "DANGEROUSLY_SET_PHOENIX_ENABLE_AUTH"
66
+ ENV_DANGEROUSLY_SET_PHOENIX_SECRET = "DANGEROUSLY_SET_PHOENIX_SECRET"
67
+
63
68
 
64
69
  def server_instrumentation_is_enabled() -> bool:
65
70
  return bool(
@@ -100,6 +105,57 @@ def get_working_dir() -> Path:
100
105
  return Path.home().resolve() / ".phoenix"
101
106
 
102
107
 
108
+ def get_boolean_env_var(env_var: str) -> Optional[bool]:
109
+ """
110
+ Parses a boolean environment variable, returning None if the variable is not set.
111
+ """
112
+ if (value := os.environ.get(env_var)) is None:
113
+ return None
114
+ assert (lower := value.lower()) in (
115
+ "true",
116
+ "false",
117
+ ), f"{env_var} must be set to TRUE or FALSE (case-insensitive)"
118
+ return lower == "true"
119
+
120
+
121
+ def get_env_enable_auth() -> bool:
122
+ """
123
+ Gets the value of the DANGEROUSLY_SET_PHOENIX_ENABLE_AUTH environment variable.
124
+ """
125
+ return get_boolean_env_var(ENV_DANGEROUSLY_SET_PHOENIX_ENABLE_AUTH) is True
126
+
127
+
128
+ def get_env_phoenix_secret() -> Optional[str]:
129
+ """
130
+ Gets the value of the DANGEROUSLY_SET_PHOENIX_SECRET environment variable
131
+ and performs validation.
132
+ """
133
+ phoenix_secret = os.environ.get(ENV_DANGEROUSLY_SET_PHOENIX_SECRET)
134
+ if phoenix_secret is None:
135
+ return None
136
+ # todo: add validation for the phoenix secret
137
+ return phoenix_secret
138
+
139
+
140
+ def get_auth_settings() -> Tuple[bool, Optional[str]]:
141
+ """
142
+ Gets auth settings and performs validation.
143
+ """
144
+ enable_auth = get_env_enable_auth()
145
+ phoenix_secret = get_env_phoenix_secret()
146
+ if enable_auth:
147
+ assert phoenix_secret, (
148
+ "DANGEROUSLY_SET_PHOENIX_SECRET must be set "
149
+ "when auth is enabled with DANGEROUSLY_SET_PHOENIX_ENABLE_AUTH"
150
+ )
151
+ else:
152
+ assert not phoenix_secret, (
153
+ "DANGEROUSLY_SET_PHOENIX_SECRET cannot be set "
154
+ "unless auth is enabled with DANGEROUSLY_SET_PHOENIX_ENABLE_AUTH"
155
+ )
156
+ return enable_auth, phoenix_secret
157
+
158
+
103
159
  PHOENIX_DIR = Path(__file__).resolve().parent
104
160
  # Server config
105
161
  SERVER_DIR = PHOENIX_DIR / "server"
@@ -123,6 +179,8 @@ EXPORT_DIR = ROOT_DIR / "exports"
123
179
  INFERENCES_DIR = ROOT_DIR / "inferences"
124
180
  TRACE_DATASETS_DIR = ROOT_DIR / "trace_datasets"
125
181
 
182
+ ENABLE_AUTH, PHOENIX_SECRET = get_auth_settings()
183
+
126
184
 
127
185
  def ensure_working_dir() -> None:
128
186
  """
@@ -0,0 +1,4 @@
1
+ # Future Migrations
2
+
3
+ This folder contains future migrations for unreleased features that are under active development. Do not run these migrations unless you are a Phoenix developer.
4
+
@@ -0,0 +1,292 @@
1
+ """users and tokens
2
+
3
+ Revision ID: cd164e83824f
4
+ Revises: 10460e46d750
5
+ Create Date: 2024-08-01 18:36:52.157604
6
+
7
+ """
8
+
9
+ from datetime import datetime, timezone
10
+ from typing import Any, Dict, List, Optional, Sequence, TypedDict, Union
11
+
12
+ import sqlalchemy as sa
13
+ from alembic import op
14
+ from phoenix.datetime_utils import normalize_datetime
15
+ from sqlalchemy import (
16
+ JSON,
17
+ TIMESTAMP,
18
+ CheckConstraint,
19
+ Dialect,
20
+ ForeignKey,
21
+ MetaData,
22
+ TypeDecorator,
23
+ func,
24
+ insert,
25
+ )
26
+ from sqlalchemy.dialects import postgresql
27
+ from sqlalchemy.ext.asyncio.engine import AsyncConnection
28
+ from sqlalchemy.ext.compiler import compiles
29
+ from sqlalchemy.orm import (
30
+ DeclarativeBase,
31
+ Mapped,
32
+ mapped_column,
33
+ )
34
+
35
+
36
+ class JSONB(JSON):
37
+ # See https://docs.sqlalchemy.org/en/20/core/custom_types.html
38
+ __visit_name__ = "JSONB"
39
+
40
+
41
+ @compiles(JSONB, "sqlite") # type: ignore
42
+ def _(*args: Any, **kwargs: Any) -> str:
43
+ # See https://docs.sqlalchemy.org/en/20/core/custom_types.html
44
+ return "JSONB"
45
+
46
+
47
+ JSON_ = (
48
+ JSON()
49
+ .with_variant(
50
+ postgresql.JSONB(), # type: ignore
51
+ "postgresql",
52
+ )
53
+ .with_variant(
54
+ JSONB(),
55
+ "sqlite",
56
+ )
57
+ )
58
+
59
+
60
+ class JsonDict(TypeDecorator[Dict[str, Any]]):
61
+ # See # See https://docs.sqlalchemy.org/en/20/core/custom_types.html
62
+ cache_ok = True
63
+ impl = JSON_
64
+
65
+ def process_bind_param(self, value: Optional[Dict[str, Any]], _: Dialect) -> Dict[str, Any]:
66
+ return value if isinstance(value, dict) else {}
67
+
68
+
69
+ class JsonList(TypeDecorator[List[Any]]):
70
+ # See # See https://docs.sqlalchemy.org/en/20/core/custom_types.html
71
+ cache_ok = True
72
+ impl = JSON_
73
+
74
+ def process_bind_param(self, value: Optional[List[Any]], _: Dialect) -> List[Any]:
75
+ return value if isinstance(value, list) else []
76
+
77
+
78
+ class UtcTimeStamp(TypeDecorator[datetime]):
79
+ # See # See https://docs.sqlalchemy.org/en/20/core/custom_types.html
80
+ cache_ok = True
81
+ impl = TIMESTAMP(timezone=True)
82
+
83
+ def process_bind_param(self, value: Optional[datetime], _: Dialect) -> Optional[datetime]:
84
+ return normalize_datetime(value)
85
+
86
+ def process_result_value(self, value: Optional[Any], _: Dialect) -> Optional[datetime]:
87
+ return normalize_datetime(value, timezone.utc)
88
+
89
+
90
+ class ExperimentRunOutput(TypedDict, total=False):
91
+ task_output: Any
92
+
93
+
94
+ class Base(DeclarativeBase):
95
+ # Enforce best practices for naming constraints
96
+ # https://alembic.sqlalchemy.org/en/latest/naming.html#integration-of-naming-conventions-into-operations-autogenerate
97
+ metadata = MetaData(
98
+ naming_convention={
99
+ "ix": "ix_%(table_name)s_%(column_0_N_name)s",
100
+ "uq": "uq_%(table_name)s_%(column_0_N_name)s",
101
+ "ck": "ck_%(table_name)s_`%(constraint_name)s`",
102
+ "fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s",
103
+ "pk": "pk_%(table_name)s",
104
+ }
105
+ )
106
+ type_annotation_map = {
107
+ Dict[str, Any]: JsonDict,
108
+ List[Dict[str, Any]]: JsonList,
109
+ ExperimentRunOutput: JsonDict,
110
+ }
111
+
112
+
113
+ class UserRole(Base):
114
+ __tablename__ = "user_roles"
115
+ id: Mapped[int] = mapped_column(primary_key=True)
116
+ role: Mapped[str] = mapped_column(unique=True)
117
+
118
+
119
+ class User(Base):
120
+ __tablename__ = "users"
121
+ id: Mapped[int] = mapped_column(primary_key=True)
122
+ user_role_id: Mapped[int] = mapped_column(
123
+ ForeignKey("user_roles.id"),
124
+ index=True,
125
+ )
126
+ username: Mapped[Optional[str]] = mapped_column(nullable=True, unique=True, index=True)
127
+ email: Mapped[str] = mapped_column(nullable=False, unique=True, index=True)
128
+ auth_method: Mapped[str] = mapped_column(
129
+ CheckConstraint("auth_method IN ('LOCAL')", name="valid_auth_method")
130
+ )
131
+ password_hash: Mapped[Optional[str]]
132
+ reset_password: Mapped[bool]
133
+ created_at: Mapped[datetime] = mapped_column(UtcTimeStamp, server_default=func.now())
134
+ updated_at: Mapped[datetime] = mapped_column(
135
+ UtcTimeStamp, server_default=func.now(), onupdate=func.now()
136
+ )
137
+ deleted_at: Mapped[Optional[datetime]] = mapped_column(UtcTimeStamp)
138
+
139
+
140
+ # revision identifiers, used by Alembic.
141
+ revision: str = "cd164e83824f"
142
+ down_revision: Union[str, None] = "3be8647b87d8"
143
+ branch_labels: Union[str, Sequence[str], None] = None
144
+ depends_on: Union[str, Sequence[str], None] = None
145
+
146
+
147
+ async def insert_roles_and_users(connection: AsyncConnection) -> None:
148
+ """
149
+ Populates the `user_roles` table and adds a system user and initial admin
150
+ user to the `users` table.
151
+ """
152
+ await connection.execute(
153
+ insert(UserRole).values([{"role": "SYSTEM"}, {"role": "ADMIN"}, {"role": "GENERAL"}])
154
+ )
155
+ system_user_role_id = sa.select(UserRole.id).where(UserRole.role == "SYSTEM").scalar_subquery()
156
+ admin_user_role_id = sa.select(UserRole.id).where(UserRole.role == "ADMIN").scalar_subquery()
157
+ await connection.execute(
158
+ insert(User).values(
159
+ [
160
+ {
161
+ "user_role_id": system_user_role_id,
162
+ "username": None,
163
+ "email": "system@localhost",
164
+ "auth_method": "LOCAL",
165
+ "password_hash": None,
166
+ "reset_password": False,
167
+ },
168
+ {
169
+ "user_role_id": admin_user_role_id,
170
+ "username": "admin",
171
+ "email": "admin@localhost",
172
+ "auth_method": "LOCAL",
173
+ "password_hash": None, # todo: replace this with the hashed PHOENIX_SECRET
174
+ "reset_password": True,
175
+ },
176
+ ]
177
+ )
178
+ )
179
+
180
+
181
+ def upgrade() -> None:
182
+ op.create_table(
183
+ "user_roles",
184
+ sa.Column("id", sa.Integer, primary_key=True),
185
+ sa.Column(
186
+ "role",
187
+ sa.String,
188
+ nullable=False,
189
+ unique=True,
190
+ ),
191
+ )
192
+ op.create_table(
193
+ "users",
194
+ sa.Column("id", sa.Integer, primary_key=True),
195
+ sa.Column(
196
+ "user_role_id",
197
+ sa.Integer,
198
+ sa.ForeignKey("user_roles.id"),
199
+ nullable=False,
200
+ index=True,
201
+ ),
202
+ sa.Column("username", sa.String, nullable=True, unique=True, index=True),
203
+ sa.Column("email", sa.String, nullable=False, unique=True, index=True),
204
+ sa.Column(
205
+ "auth_method",
206
+ sa.String,
207
+ sa.CheckConstraint("auth_method IN ('LOCAL')", "valid_auth_method"),
208
+ nullable=False,
209
+ ),
210
+ sa.Column("password_hash", sa.String, nullable=True),
211
+ sa.Column("reset_password", sa.Boolean, nullable=False),
212
+ sa.Column(
213
+ "created_at",
214
+ sa.TIMESTAMP(timezone=True),
215
+ nullable=False,
216
+ server_default=sa.func.now(),
217
+ ),
218
+ sa.Column(
219
+ "updated_at",
220
+ sa.TIMESTAMP(timezone=True),
221
+ nullable=False,
222
+ server_default=sa.func.now(),
223
+ onupdate=sa.func.now(),
224
+ ),
225
+ sa.Column(
226
+ "deleted_at",
227
+ sa.TIMESTAMP(timezone=True),
228
+ nullable=True,
229
+ ),
230
+ )
231
+ op.create_table(
232
+ "api_keys",
233
+ sa.Column("id", sa.Integer, primary_key=True),
234
+ sa.Column(
235
+ "user_id",
236
+ sa.Integer,
237
+ sa.ForeignKey("users.id"),
238
+ nullable=False,
239
+ index=True,
240
+ ),
241
+ sa.Column("name", sa.String, nullable=False),
242
+ sa.Column("description", sa.String, nullable=True),
243
+ sa.Column(
244
+ "created_at",
245
+ sa.TIMESTAMP(timezone=True),
246
+ nullable=False,
247
+ server_default=sa.func.now(),
248
+ ),
249
+ sa.Column(
250
+ "expires_at",
251
+ sa.TIMESTAMP(timezone=True),
252
+ nullable=True,
253
+ ),
254
+ )
255
+ op.create_table(
256
+ "audit_api_keys",
257
+ sa.Column("id", sa.Integer, primary_key=True),
258
+ sa.Column(
259
+ "api_key_id",
260
+ sa.Integer,
261
+ sa.ForeignKey("api_keys.id"),
262
+ nullable=False,
263
+ index=True,
264
+ ),
265
+ sa.Column(
266
+ "user_id",
267
+ sa.Integer,
268
+ sa.ForeignKey("users.id"),
269
+ nullable=False,
270
+ index=True,
271
+ ),
272
+ sa.Column(
273
+ "action",
274
+ sa.String,
275
+ sa.CheckConstraint("action IN ('CREATE', 'DELETE')", "valid_action"),
276
+ nullable=False,
277
+ ),
278
+ sa.Column(
279
+ "created_at",
280
+ sa.TIMESTAMP(timezone=True),
281
+ nullable=False,
282
+ server_default=sa.func.now(),
283
+ ),
284
+ )
285
+ op.run_async(insert_roles_and_users)
286
+
287
+
288
+ def downgrade() -> None:
289
+ op.drop_table("audit_api_keys")
290
+ op.drop_table("api_keys")
291
+ op.drop_table("users")
292
+ op.drop_table("user_roles")
@@ -0,0 +1 @@
1
+ cd164e83824f_users_and_tokens.py
@@ -34,6 +34,7 @@ from sqlalchemy.orm import (
34
34
  )
35
35
  from sqlalchemy.sql import expression
36
36
 
37
+ from phoenix.config import ENABLE_AUTH
37
38
  from phoenix.datetime_utils import normalize_datetime
38
39
 
39
40
 
@@ -616,3 +617,63 @@ class ExperimentRunAnnotation(Base):
616
617
  "name",
617
618
  ),
618
619
  )
620
+
621
+
622
+ # todo: unnest the following models when auth is released (https://github.com/Arize-ai/phoenix/issues/4183)
623
+ if ENABLE_AUTH:
624
+
625
+ class UserRole(Base):
626
+ __tablename__ = "user_roles"
627
+ id: Mapped[int] = mapped_column(primary_key=True)
628
+ role: Mapped[str] = mapped_column(unique=True)
629
+
630
+ class User(Base):
631
+ __tablename__ = "users"
632
+ id: Mapped[int] = mapped_column(primary_key=True)
633
+ user_role_id: Mapped[int] = mapped_column(
634
+ ForeignKey("user_roles.id"),
635
+ index=True,
636
+ )
637
+ username: Mapped[Optional[str]] = mapped_column(nullable=True, unique=True, index=True)
638
+ email: Mapped[str] = mapped_column(nullable=False, unique=True, index=True)
639
+ auth_method: Mapped[str] = mapped_column(
640
+ CheckConstraint("auth_method IN ('LOCAL')", name="valid_auth_method")
641
+ )
642
+ password_hash: Mapped[Optional[str]]
643
+ reset_password: Mapped[bool]
644
+ created_at: Mapped[datetime] = mapped_column(UtcTimeStamp, server_default=func.now())
645
+ updated_at: Mapped[datetime] = mapped_column(
646
+ UtcTimeStamp, server_default=func.now(), onupdate=func.now()
647
+ )
648
+ deleted_at: Mapped[Optional[datetime]] = mapped_column(UtcTimeStamp)
649
+
650
+ class APIKey(Base):
651
+ __tablename__ = "api_keys"
652
+ id: Mapped[int] = mapped_column(primary_key=True)
653
+ user_id: Mapped[int] = mapped_column(
654
+ ForeignKey("users.id"),
655
+ index=True,
656
+ )
657
+ name: Mapped[str]
658
+ description: Mapped[Optional[str]]
659
+ created_at: Mapped[datetime] = mapped_column(UtcTimeStamp, server_default=func.now())
660
+ expires_at: Mapped[Optional[datetime]] = mapped_column(UtcTimeStamp)
661
+
662
+ # todo: standardize audit table format (https://github.com/Arize-ai/phoenix/issues/4185)
663
+ class AuditAPIKey(Base):
664
+ __tablename__ = "audit_api_keys"
665
+ id: Mapped[int] = mapped_column(primary_key=True)
666
+ api_key_id: Mapped[int] = mapped_column(
667
+ ForeignKey("api_keys.id"),
668
+ nullable=False,
669
+ index=True,
670
+ )
671
+ user_id: Mapped[int] = mapped_column(
672
+ ForeignKey("users.id"),
673
+ nullable=False,
674
+ index=True,
675
+ )
676
+ action: Mapped[str] = mapped_column(
677
+ CheckConstraint("action IN ('CREATE', 'DELETE')", name="valid_action")
678
+ )
679
+ created_at: Mapped[datetime] = mapped_column(UtcTimeStamp, server_default=func.now())
@@ -447,14 +447,14 @@ def evaluate_experiment(
447
447
  )
448
448
  if not dataset.examples:
449
449
  raise ValueError(f"Dataset has no examples: {dataset_id=}, {dataset_version_id=}")
450
- experiment_runs = tuple(
451
- ExperimentRun.from_dict(exp_run)
450
+ experiment_runs = {
451
+ exp_run["id"]: ExperimentRun.from_dict(exp_run)
452
452
  for exp_run in sync_client.get(f"/v1/experiments/{experiment.id}/runs").json()["data"]
453
- )
453
+ }
454
454
  if not experiment_runs:
455
455
  raise ValueError("Experiment has not been run")
456
456
  params = ExperimentParameters(n_examples=len(dataset.examples))
457
- task_summary = TaskSummary.from_task_runs(params, experiment_runs)
457
+ task_summary = TaskSummary.from_task_runs(params, experiment_runs.values())
458
458
  ran_experiment = object.__new__(RanExperiment)
459
459
  ran_experiment.__init__( # type: ignore[misc]
460
460
  dataset=dataset,
@@ -167,7 +167,7 @@ class Dataset:
167
167
  def from_dict(cls, obj: Mapping[str, Any]) -> Dataset:
168
168
  examples = tuple(map(Example.from_dict, obj.get("examples") or ()))
169
169
  return cls(
170
- id=obj["id"],
170
+ id=obj["dataset_id"],
171
171
  version_id=obj["version_id"],
172
172
  examples={ex.id: ex for ex in examples},
173
173
  )
@@ -225,7 +225,7 @@ class ExperimentRun:
225
225
  )
226
226
 
227
227
  def __post_init__(self) -> None:
228
- if bool(self.output) == bool(self.error):
228
+ if self.output is None and self.error is None:
229
229
  raise ValueError("Must specify exactly one of experiment_run_output or error")
230
230
 
231
231
 
@@ -284,7 +284,7 @@ class ExperimentEvaluationRun:
284
284
  )
285
285
 
286
286
  def __post_init__(self) -> None:
287
- if bool(self.result) == bool(self.error):
287
+ if self.result is None and self.error is None:
288
288
  raise ValueError("Must specify either result or error")
289
289
 
290
290
 
@@ -14,7 +14,6 @@ from phoenix.server.api.dataloaders import (
14
14
  DocumentEvaluationsDataLoader,
15
15
  DocumentEvaluationSummaryDataLoader,
16
16
  DocumentRetrievalMetricsDataLoader,
17
- EvaluationSummaryDataLoader,
18
17
  ExperimentAnnotationSummaryDataLoader,
19
18
  ExperimentErrorRatesDataLoader,
20
19
  ExperimentRunCountsDataLoader,
@@ -26,10 +25,8 @@ from phoenix.server.api.dataloaders import (
26
25
  SpanAnnotationsDataLoader,
27
26
  SpanDatasetExamplesDataLoader,
28
27
  SpanDescendantsDataLoader,
29
- SpanEvaluationsDataLoader,
30
28
  SpanProjectsDataLoader,
31
29
  TokenCountDataLoader,
32
- TraceEvaluationsDataLoader,
33
30
  TraceRowIdsDataLoader,
34
31
  )
35
32
  from phoenix.server.dml_event import DmlEvent
@@ -45,7 +42,6 @@ class DataLoaders:
45
42
  document_evaluations: DocumentEvaluationsDataLoader
46
43
  document_retrieval_metrics: DocumentRetrievalMetricsDataLoader
47
44
  annotation_summaries: AnnotationSummaryDataLoader
48
- evaluation_summaries: EvaluationSummaryDataLoader
49
45
  experiment_annotation_summaries: ExperimentAnnotationSummaryDataLoader
50
46
  experiment_error_rates: ExperimentErrorRatesDataLoader
51
47
  experiment_run_counts: ExperimentRunCountsDataLoader
@@ -56,10 +52,8 @@ class DataLoaders:
56
52
  span_annotations: SpanAnnotationsDataLoader
57
53
  span_dataset_examples: SpanDatasetExamplesDataLoader
58
54
  span_descendants: SpanDescendantsDataLoader
59
- span_evaluations: SpanEvaluationsDataLoader
60
55
  span_projects: SpanProjectsDataLoader
61
56
  token_counts: TokenCountDataLoader
62
- trace_evaluations: TraceEvaluationsDataLoader
63
57
  trace_row_ids: TraceRowIdsDataLoader
64
58
  project_by_name: ProjectByNameDataLoader
65
59
 
@@ -10,7 +10,6 @@ from .document_evaluation_summaries import (
10
10
  )
11
11
  from .document_evaluations import DocumentEvaluationsDataLoader
12
12
  from .document_retrieval_metrics import DocumentRetrievalMetricsDataLoader
13
- from .evaluation_summaries import EvaluationSummaryCache, EvaluationSummaryDataLoader
14
13
  from .experiment_annotation_summaries import ExperimentAnnotationSummaryDataLoader
15
14
  from .experiment_error_rates import ExperimentErrorRatesDataLoader
16
15
  from .experiment_run_counts import ExperimentRunCountsDataLoader
@@ -22,10 +21,8 @@ from .record_counts import RecordCountCache, RecordCountDataLoader
22
21
  from .span_annotations import SpanAnnotationsDataLoader
23
22
  from .span_dataset_examples import SpanDatasetExamplesDataLoader
24
23
  from .span_descendants import SpanDescendantsDataLoader
25
- from .span_evaluations import SpanEvaluationsDataLoader
26
24
  from .span_projects import SpanProjectsDataLoader
27
25
  from .token_counts import TokenCountCache, TokenCountDataLoader
28
- from .trace_evaluations import TraceEvaluationsDataLoader
29
26
  from .trace_row_ids import TraceRowIdsDataLoader
30
27
 
31
28
  __all__ = [
@@ -37,7 +34,6 @@ __all__ = [
37
34
  "DocumentEvaluationsDataLoader",
38
35
  "DocumentRetrievalMetricsDataLoader",
39
36
  "AnnotationSummaryDataLoader",
40
- "EvaluationSummaryDataLoader",
41
37
  "ExperimentAnnotationSummaryDataLoader",
42
38
  "ExperimentErrorRatesDataLoader",
43
39
  "ExperimentRunCountsDataLoader",
@@ -47,10 +43,8 @@ __all__ = [
47
43
  "RecordCountDataLoader",
48
44
  "SpanDatasetExamplesDataLoader",
49
45
  "SpanDescendantsDataLoader",
50
- "SpanEvaluationsDataLoader",
51
46
  "SpanProjectsDataLoader",
52
47
  "TokenCountDataLoader",
53
- "TraceEvaluationsDataLoader",
54
48
  "TraceRowIdsDataLoader",
55
49
  "ProjectByNameDataLoader",
56
50
  "SpanAnnotationsDataLoader",
@@ -65,9 +59,6 @@ class CacheForDataLoaders:
65
59
  annotation_summary: AnnotationSummaryCache = field(
66
60
  default_factory=AnnotationSummaryCache,
67
61
  )
68
- evaluation_summary: EvaluationSummaryCache = field(
69
- default_factory=EvaluationSummaryCache,
70
- )
71
62
  latency_ms_quantile: LatencyMsQuantileCache = field(
72
63
  default_factory=LatencyMsQuantileCache,
73
64
  )
@@ -108,7 +108,12 @@ async def create_experiment_run(
108
108
  return CreateExperimentResponseBody(data=CreateExperimentRunResponseBodyData(id=str(run_gid)))
109
109
 
110
110
 
111
- class ListExperimentRunsResponseBody(ResponseBody[List[ExperimentRun]]):
111
+ class ExperimentRunResponse(ExperimentRun):
112
+ id: str = Field(description="The ID of the experiment run")
113
+ experiment_id: str = Field(description="The ID of the experiment")
114
+
115
+
116
+ class ListExperimentRunsResponseBody(ResponseBody[List[ExperimentRunResponse]]):
112
117
  pass
113
118
 
114
119
 
@@ -147,7 +152,7 @@ async def list_experiment_runs(
147
152
  experiment_gid = GlobalID("Experiment", str(exp_run.experiment_id))
148
153
  example_gid = GlobalID("DatasetExample", str(exp_run.dataset_example_id))
149
154
  runs.append(
150
- ExperimentRun(
155
+ ExperimentRunResponse(
151
156
  start_time=exp_run.start_time,
152
157
  end_time=exp_run.end_time,
153
158
  experiment_id=str(experiment_gid),