arize-phoenix 8.0.1__tar.gz → 8.2.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 (375) hide show
  1. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/PKG-INFO +1 -2
  2. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/pyproject.toml +0 -1
  3. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/config.py +32 -6
  4. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/db/models.py +151 -11
  5. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/context.py +4 -0
  6. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/dataloaders/__init__.py +4 -0
  7. arize_phoenix-8.2.0/src/phoenix/server/api/dataloaders/span_by_id.py +29 -0
  8. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/dataloaders/span_descendants.py +24 -15
  9. arize_phoenix-8.2.0/src/phoenix/server/api/dataloaders/span_fields.py +76 -0
  10. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/dataloaders/trace_root_spans.py +9 -10
  11. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/mutations/chat_mutations.py +10 -7
  12. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/queries.py +2 -2
  13. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/subscriptions.py +3 -3
  14. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/Annotation.py +4 -1
  15. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/DatasetExample.py +2 -2
  16. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/Project.py +8 -10
  17. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/ProjectSession.py +2 -2
  18. arize_phoenix-8.2.0/src/phoenix/server/api/types/Span.py +666 -0
  19. arize_phoenix-8.2.0/src/phoenix/server/api/types/SpanIOValue.py +48 -0
  20. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/Trace.py +17 -15
  21. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/app.py +4 -0
  22. arize_phoenix-8.2.0/src/phoenix/server/prometheus.py +217 -0
  23. arize_phoenix-8.2.0/src/phoenix/server/static/.vite/manifest.json +87 -0
  24. arize_phoenix-8.0.1/src/phoenix/server/static/assets/components-B-qgPyHv.js → arize_phoenix-8.2.0/src/phoenix/server/static/assets/components-C48uRczp.js +1 -1
  25. arize_phoenix-8.0.1/src/phoenix/server/static/assets/index-D4KO1IcF.js → arize_phoenix-8.2.0/src/phoenix/server/static/assets/index-5klIR86Z.js +2 -2
  26. arize_phoenix-8.0.1/src/phoenix/server/static/assets/pages-DdcuL3Rh.js → arize_phoenix-8.2.0/src/phoenix/server/static/assets/pages-sERWyBWu.js +326 -326
  27. arize_phoenix-8.0.1/src/phoenix/server/static/assets/vendor-DQp7CrDA.js → arize_phoenix-8.2.0/src/phoenix/server/static/assets/vendor-Cqfydjep.js +117 -117
  28. arize_phoenix-8.0.1/src/phoenix/server/static/assets/vendor-arizeai-C1nEIEQq.js → arize_phoenix-8.2.0/src/phoenix/server/static/assets/vendor-arizeai-WnerlUPN.js +1 -1
  29. arize_phoenix-8.0.1/src/phoenix/server/static/assets/vendor-codemirror-BZXYUIkP.js → arize_phoenix-8.2.0/src/phoenix/server/static/assets/vendor-codemirror-D-ZZKLFq.js +1 -1
  30. arize_phoenix-8.0.1/src/phoenix/server/static/assets/vendor-recharts-BUFpwCVD.js → arize_phoenix-8.2.0/src/phoenix/server/static/assets/vendor-recharts-KY97ZPfK.js +1 -1
  31. arize_phoenix-8.0.1/src/phoenix/server/static/assets/vendor-shiki-C8L-c9jT.js → arize_phoenix-8.2.0/src/phoenix/server/static/assets/vendor-shiki-D5K9GnFn.js +1 -1
  32. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/trace/attributes.py +7 -2
  33. arize_phoenix-8.2.0/src/phoenix/version.py +1 -0
  34. arize_phoenix-8.0.1/src/phoenix/server/api/helpers/jsonschema.py +0 -135
  35. arize_phoenix-8.0.1/src/phoenix/server/api/types/Span.py +0 -409
  36. arize_phoenix-8.0.1/src/phoenix/server/api/types/SpanIOValue.py +0 -15
  37. arize_phoenix-8.0.1/src/phoenix/server/prometheus.py +0 -111
  38. arize_phoenix-8.0.1/src/phoenix/server/static/.vite/manifest.json +0 -87
  39. arize_phoenix-8.0.1/src/phoenix/version.py +0 -1
  40. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/.gitignore +0 -0
  41. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/IP_NOTICE +0 -0
  42. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/LICENSE +0 -0
  43. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/README.md +0 -0
  44. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/__init__.py +0 -0
  45. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/auth.py +0 -0
  46. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/core/__init__.py +0 -0
  47. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/core/embedding_dimension.py +0 -0
  48. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/core/model.py +0 -0
  49. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/core/model_schema.py +0 -0
  50. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/core/model_schema_adapter.py +0 -0
  51. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/datetime_utils.py +0 -0
  52. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/db/README.md +0 -0
  53. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/db/__init__.py +0 -0
  54. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/db/alembic.ini +0 -0
  55. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/db/bulk_inserter.py +0 -0
  56. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/db/engines.py +0 -0
  57. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/db/enums.py +0 -0
  58. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/db/facilitator.py +0 -0
  59. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/db/helpers.py +0 -0
  60. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/db/insertion/__init__.py +0 -0
  61. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/db/insertion/constants.py +0 -0
  62. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/db/insertion/dataset.py +0 -0
  63. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/db/insertion/document_annotation.py +0 -0
  64. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/db/insertion/evaluation.py +0 -0
  65. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/db/insertion/helpers.py +0 -0
  66. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/db/insertion/span.py +0 -0
  67. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/db/insertion/span_annotation.py +0 -0
  68. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/db/insertion/trace_annotation.py +0 -0
  69. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/db/insertion/types.py +0 -0
  70. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/db/migrate.py +0 -0
  71. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/db/migrations/__init__.py +0 -0
  72. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/db/migrations/data_migration_scripts/__init__.py +0 -0
  73. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/db/migrations/data_migration_scripts/populate_project_sessions.py +0 -0
  74. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/db/migrations/env.py +0 -0
  75. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/db/migrations/script.py.mako +0 -0
  76. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/db/migrations/versions/10460e46d750_datasets.py +0 -0
  77. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/db/migrations/versions/3be8647b87d8_add_token_columns_to_spans_table.py +0 -0
  78. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/db/migrations/versions/4ded9e43755f_create_project_sessions_table.py +0 -0
  79. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/db/migrations/versions/bc8fea3c2bc8_add_prompt_tables.py +0 -0
  80. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/db/migrations/versions/cd164e83824f_users_and_tokens.py +0 -0
  81. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/db/migrations/versions/cf03bd6bae1d_init.py +0 -0
  82. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/db/types/__init__.py +0 -0
  83. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/db/types/identifier.py +0 -0
  84. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/db/types/model_provider.py +0 -0
  85. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/exceptions.py +0 -0
  86. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/experiments/__init__.py +0 -0
  87. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/experiments/evaluators/__init__.py +0 -0
  88. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/experiments/evaluators/base.py +0 -0
  89. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/experiments/evaluators/code_evaluators.py +0 -0
  90. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/experiments/evaluators/llm_evaluators.py +0 -0
  91. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/experiments/evaluators/utils.py +0 -0
  92. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/experiments/functions.py +0 -0
  93. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/experiments/tracing.py +0 -0
  94. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/experiments/types.py +0 -0
  95. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/experiments/utils.py +0 -0
  96. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/inferences/__init__.py +0 -0
  97. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/inferences/errors.py +0 -0
  98. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/inferences/fixtures.py +0 -0
  99. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/inferences/inferences.py +0 -0
  100. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/inferences/schema.py +0 -0
  101. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/inferences/validation.py +0 -0
  102. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/logging/__init__.py +0 -0
  103. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/logging/_config.py +0 -0
  104. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/logging/_filter.py +0 -0
  105. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/logging/_formatter.py +0 -0
  106. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/metrics/README.md +0 -0
  107. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/metrics/__init__.py +0 -0
  108. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/metrics/binning.py +0 -0
  109. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/metrics/metrics.py +0 -0
  110. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/metrics/mixins.py +0 -0
  111. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/metrics/retrieval_metrics.py +0 -0
  112. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/metrics/timeseries.py +0 -0
  113. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/metrics/wrappers.py +0 -0
  114. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/pointcloud/__init__.py +0 -0
  115. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/pointcloud/clustering.py +0 -0
  116. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/pointcloud/pointcloud.py +0 -0
  117. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/pointcloud/projectors.py +0 -0
  118. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/pointcloud/umap_parameters.py +0 -0
  119. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/py.typed +0 -0
  120. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/__init__.py +0 -0
  121. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/README.md +0 -0
  122. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/__init__.py +0 -0
  123. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/auth.py +0 -0
  124. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/dataloaders/annotation_summaries.py +0 -0
  125. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/dataloaders/average_experiment_run_latency.py +0 -0
  126. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/dataloaders/cache/__init__.py +0 -0
  127. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/dataloaders/cache/two_tier_cache.py +0 -0
  128. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/dataloaders/dataset_example_revisions.py +0 -0
  129. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/dataloaders/dataset_example_spans.py +0 -0
  130. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/dataloaders/document_evaluation_summaries.py +0 -0
  131. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/dataloaders/document_evaluations.py +0 -0
  132. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/dataloaders/document_retrieval_metrics.py +0 -0
  133. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/dataloaders/experiment_annotation_summaries.py +0 -0
  134. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/dataloaders/experiment_error_rates.py +0 -0
  135. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/dataloaders/experiment_run_annotations.py +0 -0
  136. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/dataloaders/experiment_run_counts.py +0 -0
  137. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/dataloaders/experiment_sequence_number.py +0 -0
  138. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/dataloaders/latency_ms_quantile.py +0 -0
  139. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/dataloaders/min_start_or_max_end_times.py +0 -0
  140. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/dataloaders/project_by_name.py +0 -0
  141. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/dataloaders/prompt_version_sequence_number.py +0 -0
  142. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/dataloaders/record_counts.py +0 -0
  143. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/dataloaders/session_io.py +0 -0
  144. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/dataloaders/session_num_traces.py +0 -0
  145. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/dataloaders/session_num_traces_with_error.py +0 -0
  146. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/dataloaders/session_token_usages.py +0 -0
  147. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/dataloaders/session_trace_latency_ms_quantile.py +0 -0
  148. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/dataloaders/span_annotations.py +0 -0
  149. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/dataloaders/span_dataset_examples.py +0 -0
  150. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/dataloaders/span_projects.py +0 -0
  151. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/dataloaders/token_counts.py +0 -0
  152. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/dataloaders/trace_by_trace_ids.py +0 -0
  153. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/dataloaders/user_roles.py +0 -0
  154. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/dataloaders/users.py +0 -0
  155. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/exceptions.py +0 -0
  156. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/helpers/__init__.py +0 -0
  157. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/helpers/dataset_helpers.py +0 -0
  158. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/helpers/experiment_run_filters.py +0 -0
  159. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/helpers/playground_clients.py +0 -0
  160. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/helpers/playground_registry.py +0 -0
  161. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/helpers/playground_spans.py +0 -0
  162. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/helpers/prompts/__init__.py +0 -0
  163. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/helpers/prompts/conversions/__init__.py +0 -0
  164. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/helpers/prompts/conversions/anthropic.py +0 -0
  165. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/helpers/prompts/conversions/openai.py +0 -0
  166. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/helpers/prompts/models.py +0 -0
  167. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/input_types/AddExamplesToDatasetInput.py +0 -0
  168. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/input_types/AddSpansToDatasetInput.py +0 -0
  169. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/input_types/ChatCompletionInput.py +0 -0
  170. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/input_types/ChatCompletionMessageInput.py +0 -0
  171. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/input_types/ClearProjectInput.py +0 -0
  172. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/input_types/ClusterInput.py +0 -0
  173. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/input_types/Coordinates.py +0 -0
  174. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/input_types/CreateDatasetInput.py +0 -0
  175. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/input_types/CreateSpanAnnotationInput.py +0 -0
  176. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/input_types/CreateTraceAnnotationInput.py +0 -0
  177. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/input_types/DataQualityMetricInput.py +0 -0
  178. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/input_types/DatasetExampleInput.py +0 -0
  179. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/input_types/DatasetSort.py +0 -0
  180. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/input_types/DatasetVersionSort.py +0 -0
  181. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/input_types/DeleteAnnotationsInput.py +0 -0
  182. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/input_types/DeleteDatasetExamplesInput.py +0 -0
  183. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/input_types/DeleteDatasetInput.py +0 -0
  184. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/input_types/DeleteExperimentsInput.py +0 -0
  185. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/input_types/DimensionFilter.py +0 -0
  186. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/input_types/DimensionInput.py +0 -0
  187. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/input_types/GenerativeModelInput.py +0 -0
  188. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/input_types/Granularity.py +0 -0
  189. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/input_types/InvocationParameters.py +0 -0
  190. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/input_types/PatchAnnotationInput.py +0 -0
  191. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/input_types/PatchDatasetExamplesInput.py +0 -0
  192. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/input_types/PatchDatasetInput.py +0 -0
  193. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/input_types/PerformanceMetricInput.py +0 -0
  194. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/input_types/ProjectSessionSort.py +0 -0
  195. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/input_types/PromptTemplateOptions.py +0 -0
  196. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/input_types/PromptVersionInput.py +0 -0
  197. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/input_types/SpanAnnotationSort.py +0 -0
  198. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/input_types/SpanSort.py +0 -0
  199. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/input_types/TimeRange.py +0 -0
  200. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/input_types/TraceAnnotationSort.py +0 -0
  201. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/input_types/UserRoleInput.py +0 -0
  202. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/input_types/__init__.py +0 -0
  203. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/interceptor.py +0 -0
  204. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/mutations/__init__.py +0 -0
  205. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/mutations/api_key_mutations.py +0 -0
  206. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/mutations/dataset_mutations.py +0 -0
  207. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/mutations/experiment_mutations.py +0 -0
  208. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/mutations/export_events_mutations.py +0 -0
  209. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/mutations/project_mutations.py +0 -0
  210. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/mutations/prompt_label_mutations.py +0 -0
  211. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/mutations/prompt_mutations.py +0 -0
  212. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/mutations/prompt_version_tag_mutations.py +0 -0
  213. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/mutations/span_annotations_mutations.py +0 -0
  214. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/mutations/trace_annotations_mutations.py +0 -0
  215. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/mutations/user_mutations.py +0 -0
  216. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/openapi/__init__.py +0 -0
  217. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/openapi/main.py +0 -0
  218. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/openapi/schema.py +0 -0
  219. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/routers/__init__.py +0 -0
  220. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/routers/auth.py +0 -0
  221. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/routers/embeddings.py +0 -0
  222. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/routers/oauth2.py +0 -0
  223. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/routers/utils.py +0 -0
  224. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/routers/v1/__init__.py +0 -0
  225. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/routers/v1/datasets.py +0 -0
  226. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/routers/v1/evaluations.py +0 -0
  227. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/routers/v1/experiment_evaluations.py +0 -0
  228. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/routers/v1/experiment_runs.py +0 -0
  229. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/routers/v1/experiments.py +0 -0
  230. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/routers/v1/models.py +0 -0
  231. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/routers/v1/prompts.py +0 -0
  232. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/routers/v1/spans.py +0 -0
  233. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/routers/v1/traces.py +0 -0
  234. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/routers/v1/utils.py +0 -0
  235. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/schema.py +0 -0
  236. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/AnnotationSummary.py +0 -0
  237. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/AnnotatorKind.py +0 -0
  238. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/ApiKey.py +0 -0
  239. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/AuthMethod.py +0 -0
  240. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/ChatCompletionMessageRole.py +0 -0
  241. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/ChatCompletionSubscriptionPayload.py +0 -0
  242. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/Cluster.py +0 -0
  243. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/CreateDatasetPayload.py +0 -0
  244. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/DataQualityMetric.py +0 -0
  245. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/Dataset.py +0 -0
  246. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/DatasetExampleRevision.py +0 -0
  247. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/DatasetValues.py +0 -0
  248. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/DatasetVersion.py +0 -0
  249. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/Dimension.py +0 -0
  250. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/DimensionDataType.py +0 -0
  251. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/DimensionShape.py +0 -0
  252. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/DimensionType.py +0 -0
  253. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/DimensionWithValue.py +0 -0
  254. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/DocumentEvaluationSummary.py +0 -0
  255. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/DocumentRetrievalMetrics.py +0 -0
  256. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/EmbeddingDimension.py +0 -0
  257. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/EmbeddingMetadata.py +0 -0
  258. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/Evaluation.py +0 -0
  259. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/EvaluationSummary.py +0 -0
  260. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/Event.py +0 -0
  261. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/EventMetadata.py +0 -0
  262. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/ExampleRevisionInterface.py +0 -0
  263. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/Experiment.py +0 -0
  264. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/ExperimentAnnotationSummary.py +0 -0
  265. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/ExperimentComparison.py +0 -0
  266. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/ExperimentRun.py +0 -0
  267. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/ExperimentRunAnnotation.py +0 -0
  268. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/ExportedFile.py +0 -0
  269. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/Functionality.py +0 -0
  270. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/GenerativeModel.py +0 -0
  271. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/GenerativeProvider.py +0 -0
  272. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/Identifier.py +0 -0
  273. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/Inferences.py +0 -0
  274. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/InferencesRole.py +0 -0
  275. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/LabelFraction.py +0 -0
  276. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/MimeType.py +0 -0
  277. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/Model.py +0 -0
  278. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/NumericRange.py +0 -0
  279. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/PerformanceMetric.py +0 -0
  280. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/Prompt.py +0 -0
  281. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/PromptLabel.py +0 -0
  282. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/PromptResponse.py +0 -0
  283. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/PromptVersion.py +0 -0
  284. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/PromptVersionTag.py +0 -0
  285. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/PromptVersionTemplate.py +0 -0
  286. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/ResponseFormat.py +0 -0
  287. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/Retrieval.py +0 -0
  288. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/ScalarDriftMetricEnum.py +0 -0
  289. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/Segments.py +0 -0
  290. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/SortDir.py +0 -0
  291. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/SpanAnnotation.py +0 -0
  292. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/SystemApiKey.py +0 -0
  293. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/TimeSeries.py +0 -0
  294. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/TokenUsage.py +0 -0
  295. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/ToolDefinition.py +0 -0
  296. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/TraceAnnotation.py +0 -0
  297. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/UMAPPoints.py +0 -0
  298. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/User.py +0 -0
  299. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/UserApiKey.py +0 -0
  300. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/UserRole.py +0 -0
  301. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/ValidationResult.py +0 -0
  302. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/VectorDriftMetricEnum.py +0 -0
  303. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/__init__.py +0 -0
  304. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/node.py +0 -0
  305. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/types/pagination.py +0 -0
  306. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/api/utils.py +0 -0
  307. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/bearer_auth.py +0 -0
  308. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/dml_event.py +0 -0
  309. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/dml_event_handler.py +0 -0
  310. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/email/__init__.py +0 -0
  311. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/email/sender.py +0 -0
  312. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/email/templates/__init__.py +0 -0
  313. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/email/templates/password_reset.html +0 -0
  314. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/email/types.py +0 -0
  315. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/grpc_server.py +0 -0
  316. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/jwt_store.py +0 -0
  317. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/main.py +0 -0
  318. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/oauth2.py +0 -0
  319. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/openapi/__init__.py +0 -0
  320. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/rate_limiters.py +0 -0
  321. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/static/apple-touch-icon-114x114.png +0 -0
  322. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/static/apple-touch-icon-120x120.png +0 -0
  323. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/static/apple-touch-icon-144x144.png +0 -0
  324. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/static/apple-touch-icon-152x152.png +0 -0
  325. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/static/apple-touch-icon-180x180.png +0 -0
  326. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/static/apple-touch-icon-72x72.png +0 -0
  327. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/static/apple-touch-icon-76x76.png +0 -0
  328. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/static/apple-touch-icon.png +0 -0
  329. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/static/assets/vendor-Cg6lcjUC.css +0 -0
  330. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/static/assets/vendor-three-C-AGeJYv.js +0 -0
  331. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/static/favicon.ico +0 -0
  332. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/static/modernizr.js +0 -0
  333. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/telemetry.py +0 -0
  334. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/templates/__init__.py +0 -0
  335. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/templates/index.html +0 -0
  336. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/thread_server.py +0 -0
  337. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/server/types.py +0 -0
  338. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/services.py +0 -0
  339. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/session/__init__.py +0 -0
  340. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/session/client.py +0 -0
  341. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/session/data_extractor.py +0 -0
  342. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/session/evaluation.py +0 -0
  343. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/session/session.py +0 -0
  344. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/settings.py +0 -0
  345. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/trace/__init__.py +0 -0
  346. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/trace/dsl/README.md +0 -0
  347. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/trace/dsl/__init__.py +0 -0
  348. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/trace/dsl/filter.py +0 -0
  349. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/trace/dsl/helpers.py +0 -0
  350. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/trace/dsl/query.py +0 -0
  351. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/trace/errors.py +0 -0
  352. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/trace/evaluation_conventions.py +0 -0
  353. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/trace/exporter.py +0 -0
  354. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/trace/fixtures.py +0 -0
  355. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/trace/otel.py +0 -0
  356. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/trace/projects.py +0 -0
  357. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/trace/schemas.py +0 -0
  358. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/trace/span_evaluations.py +0 -0
  359. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/trace/span_json_decoder.py +0 -0
  360. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/trace/span_json_encoder.py +0 -0
  361. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/trace/trace_dataset.py +0 -0
  362. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/trace/utils.py +0 -0
  363. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/trace/v1/__init__.py +0 -0
  364. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/trace/v1/evaluation_pb2.py +0 -0
  365. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/trace/v1/evaluation_pb2.pyi +0 -0
  366. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/utilities/__init__.py +0 -0
  367. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/utilities/client.py +0 -0
  368. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/utilities/deprecation.py +0 -0
  369. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/utilities/error_handling.py +0 -0
  370. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/utilities/json.py +0 -0
  371. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/utilities/logging.py +0 -0
  372. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/utilities/project.py +0 -0
  373. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/utilities/re.py +0 -0
  374. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/utilities/span_store.py +0 -0
  375. {arize_phoenix-8.0.1 → arize_phoenix-8.2.0}/src/phoenix/utilities/template_formatters.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: arize-phoenix
3
- Version: 8.0.1
3
+ Version: 8.2.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
@@ -30,7 +30,6 @@ Requires-Dist: grpc-interceptor
30
30
  Requires-Dist: grpcio
31
31
  Requires-Dist: httpx
32
32
  Requires-Dist: jinja2
33
- Requires-Dist: jsonschema<=4.23.0,>=4.0.0
34
33
  Requires-Dist: numpy!=2.0.0
35
34
  Requires-Dist: openinference-instrumentation>=0.1.12
36
35
  Requires-Dist: openinference-semantic-conventions>=0.1.12
@@ -58,7 +58,6 @@ dependencies = [
58
58
  "pydantic>=2.1.0", # exclude 2.0.* since it does not support the `json_encoders` configuration setting
59
59
  "authlib",
60
60
  "websockets",
61
- "jsonschema>=4.0.0,<=4.23.0", # the upper bound is to keep us off the bleeding edge in case there's a regression since this controls what gets written to the database
62
61
  "arize-phoenix-client",
63
62
  ]
64
63
  dynamic = ["version"]
@@ -8,7 +8,7 @@ from enum import Enum
8
8
  from importlib.metadata import version
9
9
  from pathlib import Path
10
10
  from typing import Optional, cast, overload
11
- from urllib.parse import urlparse
11
+ from urllib.parse import quote_plus, urlparse
12
12
 
13
13
  from phoenix.utilities.logging import log_a_list
14
14
 
@@ -624,11 +624,37 @@ def get_env_project_name() -> str:
624
624
 
625
625
 
626
626
  def get_env_database_connection_str() -> str:
627
- env_url = getenv(ENV_PHOENIX_SQL_DATABASE_URL)
628
- if env_url is None:
629
- working_dir = get_working_dir()
630
- return f"sqlite:///{working_dir}/phoenix.db"
631
- return env_url
627
+ if phoenix_url := os.getenv(ENV_PHOENIX_SQL_DATABASE_URL):
628
+ return phoenix_url
629
+
630
+ if postgres_url := get_env_postgres_connection_str():
631
+ return postgres_url
632
+
633
+ working_dir = get_working_dir()
634
+ return f"sqlite:///{working_dir}/phoenix.db"
635
+
636
+
637
+ def get_env_postgres_connection_str() -> Optional[str]:
638
+ pg_user = os.getenv("PHOENIX_POSTGRES_USER")
639
+ pg_password = os.getenv("PHOENIX_POSTGRES_PASSWORD")
640
+ pg_host = os.getenv("PHOENIX_POSTGRES_HOST")
641
+ pg_port = os.getenv("PHOENIX_POSTGRES_PORT")
642
+ pg_db = os.getenv("PHOENIX_POSTGRES_DB")
643
+
644
+ if pg_host and ":" in pg_host:
645
+ pg_host, parsed_port = pg_host.split(":")
646
+ pg_port = pg_port or parsed_port # use the explicitly set port if provided
647
+
648
+ if pg_host and pg_user and pg_password:
649
+ encoded_password = quote_plus(pg_password)
650
+ connection_str = f"postgresql://{pg_user}:{encoded_password}@{pg_host}"
651
+ if pg_port:
652
+ connection_str = f"{connection_str}:{pg_port}"
653
+ if pg_db:
654
+ connection_str = f"{connection_str}/{pg_db}"
655
+
656
+ return connection_str
657
+ return None
632
658
 
633
659
 
634
660
  def get_env_database_schema() -> Optional[str]:
@@ -1,7 +1,9 @@
1
1
  from datetime import datetime, timezone
2
2
  from enum import Enum
3
- from typing import Any, Optional, TypedDict
3
+ from typing import Any, Optional, Sequence, TypedDict
4
4
 
5
+ import sqlalchemy.sql as sql
6
+ from openinference.semconv.trace import RerankerAttributes, SpanAttributes
5
7
  from sqlalchemy import (
6
8
  JSON,
7
9
  NUMERIC,
@@ -12,6 +14,7 @@ from sqlalchemy import (
12
14
  Float,
13
15
  ForeignKey,
14
16
  Index,
17
+ Integer,
15
18
  MetaData,
16
19
  Null,
17
20
  String,
@@ -25,6 +28,7 @@ from sqlalchemy import (
25
28
  text,
26
29
  )
27
30
  from sqlalchemy.dialects import postgresql
31
+ from sqlalchemy.dialects.sqlite.base import SQLiteCompiler
28
32
  from sqlalchemy.ext.asyncio import AsyncEngine, AsyncSession
29
33
  from sqlalchemy.ext.compiler import compiles
30
34
  from sqlalchemy.ext.hybrid import hybrid_property
@@ -36,6 +40,8 @@ from sqlalchemy.orm import (
36
40
  relationship,
37
41
  )
38
42
  from sqlalchemy.sql import expression
43
+ from sqlalchemy.sql.compiler import SQLCompiler
44
+ from sqlalchemy.sql.functions import coalesce
39
45
 
40
46
  from phoenix.config import get_env_database_schema
41
47
  from phoenix.datetime_utils import normalize_datetime
@@ -54,6 +60,18 @@ from phoenix.server.api.helpers.prompts.models import (
54
60
  is_prompt_invocation_parameters,
55
61
  is_prompt_template,
56
62
  )
63
+ from phoenix.trace.attributes import get_attribute_value
64
+
65
+ INPUT_MIME_TYPE = SpanAttributes.INPUT_MIME_TYPE.split(".")
66
+ INPUT_VALUE = SpanAttributes.INPUT_VALUE.split(".")
67
+ LLM_TOKEN_COUNT_TOTAL = SpanAttributes.LLM_TOKEN_COUNT_TOTAL.split(".")
68
+ LLM_TOKEN_COUNT_PROMPT = SpanAttributes.LLM_TOKEN_COUNT_PROMPT.split(".")
69
+ LLM_TOKEN_COUNT_COMPLETION = SpanAttributes.LLM_TOKEN_COUNT_COMPLETION.split(".")
70
+ METADATA = SpanAttributes.METADATA.split(".")
71
+ OUTPUT_MIME_TYPE = SpanAttributes.OUTPUT_MIME_TYPE.split(".")
72
+ OUTPUT_VALUE = SpanAttributes.OUTPUT_VALUE.split(".")
73
+ RERANKER_OUTPUT_DOCUMENTS = RerankerAttributes.RERANKER_OUTPUT_DOCUMENTS.split(".")
74
+ RETRIEVAL_DOCUMENTS = SpanAttributes.RETRIEVAL_DOCUMENTS.split(".")
57
75
 
58
76
 
59
77
  class AuthMethod(Enum):
@@ -341,13 +359,11 @@ class Trace(Base):
341
359
 
342
360
  @hybrid_property
343
361
  def latency_ms(self) -> float:
344
- # See https://docs.sqlalchemy.org/en/20/orm/extensions/hybrid.html
345
362
  return (self.end_time - self.start_time).total_seconds() * 1000
346
363
 
347
364
  @latency_ms.inplace.expression
348
365
  @classmethod
349
366
  def _latency_ms_expression(cls) -> ColumnElement[float]:
350
- # See https://docs.sqlalchemy.org/en/20/orm/extensions/hybrid.html
351
367
  return LatencyMs(cls.start_time, cls.end_time)
352
368
 
353
369
  project: Mapped["Project"] = relationship(
@@ -404,25 +420,124 @@ class Span(Base):
404
420
 
405
421
  @hybrid_property
406
422
  def latency_ms(self) -> float:
407
- # See https://docs.sqlalchemy.org/en/20/orm/extensions/hybrid.html
408
- return (self.end_time - self.start_time).total_seconds() * 1000
423
+ return round((self.end_time - self.start_time).total_seconds() * 1000, 1)
409
424
 
410
425
  @latency_ms.inplace.expression
411
426
  @classmethod
412
427
  def _latency_ms_expression(cls) -> ColumnElement[float]:
413
- # See https://docs.sqlalchemy.org/en/20/orm/extensions/hybrid.html
414
428
  return LatencyMs(cls.start_time, cls.end_time)
415
429
 
430
+ @hybrid_property
431
+ def input_value(self) -> Any:
432
+ return get_attribute_value(self.attributes, INPUT_VALUE)
433
+
434
+ @input_value.inplace.expression
435
+ @classmethod
436
+ def _input_value_expression(cls) -> ColumnElement[Any]:
437
+ return cls.attributes[INPUT_VALUE]
438
+
439
+ @hybrid_property
440
+ def input_value_first_101_chars(self) -> Any:
441
+ if (v := get_attribute_value(self.attributes, INPUT_VALUE)) is None:
442
+ return None
443
+ return str(v)[:101]
444
+
445
+ @input_value_first_101_chars.inplace.expression
446
+ @classmethod
447
+ def _input_value_first_101_chars_expression(cls) -> ColumnElement[Any]:
448
+ return case(
449
+ (
450
+ cls.attributes[INPUT_VALUE] != sql.null(),
451
+ func.substr(cls.attributes[INPUT_VALUE].as_string(), 1, 101),
452
+ ),
453
+ )
454
+
455
+ @hybrid_property
456
+ def input_mime_type(self) -> Any:
457
+ return get_attribute_value(self.attributes, INPUT_MIME_TYPE)
458
+
459
+ @input_mime_type.inplace.expression
460
+ @classmethod
461
+ def _input_mime_type_expression(cls) -> ColumnElement[Any]:
462
+ return cls.attributes[INPUT_MIME_TYPE]
463
+
464
+ @hybrid_property
465
+ def output_value(self) -> Any:
466
+ return get_attribute_value(self.attributes, OUTPUT_VALUE)
467
+
468
+ @output_value.inplace.expression
469
+ @classmethod
470
+ def _output_value_expression(cls) -> ColumnElement[Any]:
471
+ return cls.attributes[OUTPUT_VALUE]
472
+
473
+ @hybrid_property
474
+ def output_value_first_101_chars(self) -> Any:
475
+ if (v := get_attribute_value(self.attributes, OUTPUT_VALUE)) is None:
476
+ return None
477
+ return str(v)[:101]
478
+
479
+ @output_value_first_101_chars.inplace.expression
480
+ @classmethod
481
+ def _output_value_first_101_chars_expression(cls) -> ColumnElement[Any]:
482
+ return case(
483
+ (
484
+ cls.attributes[OUTPUT_VALUE] != sql.null(),
485
+ func.substr(cls.attributes[OUTPUT_VALUE].as_string(), 1, 101),
486
+ ),
487
+ )
488
+
489
+ @hybrid_property
490
+ def output_mime_type(self) -> Any:
491
+ return get_attribute_value(self.attributes, OUTPUT_MIME_TYPE)
492
+
493
+ @output_mime_type.inplace.expression
494
+ @classmethod
495
+ def _output_mime_type_expression(cls) -> ColumnElement[Any]:
496
+ return cls.attributes[OUTPUT_MIME_TYPE]
497
+
498
+ @hybrid_property
499
+ def metadata_(self) -> Any:
500
+ return get_attribute_value(self.attributes, METADATA)
501
+
502
+ @metadata_.inplace.expression
503
+ @classmethod
504
+ def _metadata_expression(cls) -> ColumnElement[Any]:
505
+ return cls.attributes[METADATA]
506
+
507
+ @hybrid_property
508
+ def num_documents(self) -> int:
509
+ if self.span_kind.upper() == "RERANKER":
510
+ reranker_documents = get_attribute_value(self.attributes, RERANKER_OUTPUT_DOCUMENTS)
511
+ return len(reranker_documents) if isinstance(reranker_documents, Sequence) else 0
512
+ retrieval_documents = get_attribute_value(self.attributes, RETRIEVAL_DOCUMENTS)
513
+ return len(retrieval_documents) if isinstance(retrieval_documents, Sequence) else 0
514
+
515
+ @num_documents.inplace.expression
516
+ @classmethod
517
+ def _num_documents_expression(cls) -> ColumnElement[int]:
518
+ return NumDocuments(cls.attributes, cls.span_kind)
519
+
416
520
  @hybrid_property
417
521
  def cumulative_llm_token_count_total(self) -> int:
418
522
  return self.cumulative_llm_token_count_prompt + self.cumulative_llm_token_count_completion
419
523
 
524
+ @cumulative_llm_token_count_total.inplace.expression
525
+ @classmethod
526
+ def _cumulative_llm_token_count_total_expression(cls) -> ColumnElement[int]:
527
+ return cls.cumulative_llm_token_count_prompt + cls.cumulative_llm_token_count_completion
528
+
420
529
  @hybrid_property
421
- def llm_token_count_total(self) -> Optional[int]:
422
- if self.llm_token_count_prompt is None and self.llm_token_count_completion is None:
423
- return None
530
+ def llm_token_count_total(self) -> int:
424
531
  return (self.llm_token_count_prompt or 0) + (self.llm_token_count_completion or 0)
425
532
 
533
+ @llm_token_count_total.inplace.expression
534
+ @classmethod
535
+ def _llm_token_count_total_expression(cls) -> ColumnElement[int]:
536
+ return coalesce(
537
+ coalesce(cls.llm_token_count_prompt, 0) + coalesce(cls.llm_token_count_completion, 0),
538
+ 0,
539
+ )
540
+
426
541
  trace: Mapped["Trace"] = relationship("Trace", back_populates="spans")
427
542
  document_annotations: Mapped[list["DocumentAnnotation"]] = relationship(back_populates="span")
428
543
  dataset_examples: Mapped[list["DatasetExample"]] = relationship(back_populates="span")
@@ -477,6 +592,33 @@ def _(element: Any, compiler: Any, **kw: Any) -> Any:
477
592
  )
478
593
 
479
594
 
595
+ class NumDocuments(expression.FunctionElement[int]):
596
+ # See https://docs.sqlalchemy.org/en/20/core/compiler.html
597
+ inherit_cache = True
598
+ type = Integer()
599
+ name = "num_documents"
600
+
601
+
602
+ @compiles(NumDocuments)
603
+ def _(element: Any, compiler: SQLCompiler, **kw: Any) -> Any:
604
+ # See https://docs.sqlalchemy.org/en/20/core/compiler.html
605
+ array_length = (
606
+ func.json_array_length if isinstance(compiler, SQLiteCompiler) else func.jsonb_array_length
607
+ )
608
+ attributes, span_kind = list(element.clauses)
609
+ retrieval_docs = attributes[RETRIEVAL_DOCUMENTS]
610
+ num_retrieval_docs = coalesce(array_length(retrieval_docs), 0)
611
+ reranker_docs = attributes[RERANKER_OUTPUT_DOCUMENTS]
612
+ num_reranker_docs = coalesce(array_length(reranker_docs), 0)
613
+ return compiler.process(
614
+ sql.case(
615
+ (func.upper(span_kind) == "RERANKER", num_reranker_docs),
616
+ else_=num_retrieval_docs,
617
+ ),
618
+ **kw,
619
+ )
620
+
621
+
480
622
  class TextContains(expression.FunctionElement[str]):
481
623
  # See https://docs.sqlalchemy.org/en/20/core/compiler.html
482
624
  inherit_cache = True
@@ -763,13 +905,11 @@ class ExperimentRun(Base):
763
905
 
764
906
  @hybrid_property
765
907
  def latency_ms(self) -> float:
766
- # See https://docs.sqlalchemy.org/en/20/orm/extensions/hybrid.html
767
908
  return (self.end_time - self.start_time).total_seconds() * 1000
768
909
 
769
910
  @latency_ms.inplace.expression
770
911
  @classmethod
771
912
  def _latency_expression(cls) -> ColumnElement[float]:
772
- # See https://docs.sqlalchemy.org/en/20/orm/extensions/hybrid.html
773
913
  return LatencyMs(cls.start_time, cls.end_time)
774
914
 
775
915
  trace: Mapped["Trace"] = relationship(
@@ -38,8 +38,10 @@ from phoenix.server.api.dataloaders import (
38
38
  SessionTokenUsagesDataLoader,
39
39
  SessionTraceLatencyMsQuantileDataLoader,
40
40
  SpanAnnotationsDataLoader,
41
+ SpanByIdDataLoader,
41
42
  SpanDatasetExamplesDataLoader,
42
43
  SpanDescendantsDataLoader,
44
+ SpanFieldsDataLoader,
43
45
  SpanProjectsDataLoader,
44
46
  TokenCountDataLoader,
45
47
  TraceByTraceIdsDataLoader,
@@ -83,8 +85,10 @@ class DataLoaders:
83
85
  session_token_usages: SessionTokenUsagesDataLoader
84
86
  session_trace_latency_ms_quantile: SessionTraceLatencyMsQuantileDataLoader
85
87
  span_annotations: SpanAnnotationsDataLoader
88
+ span_by_id: SpanByIdDataLoader
86
89
  span_dataset_examples: SpanDatasetExamplesDataLoader
87
90
  span_descendants: SpanDescendantsDataLoader
91
+ span_fields: SpanFieldsDataLoader
88
92
  span_projects: SpanProjectsDataLoader
89
93
  token_counts: TokenCountDataLoader
90
94
  trace_by_trace_ids: TraceByTraceIdsDataLoader
@@ -26,8 +26,10 @@ from .session_num_traces_with_error import SessionNumTracesWithErrorDataLoader
26
26
  from .session_token_usages import SessionTokenUsagesDataLoader
27
27
  from .session_trace_latency_ms_quantile import SessionTraceLatencyMsQuantileDataLoader
28
28
  from .span_annotations import SpanAnnotationsDataLoader
29
+ from .span_by_id import SpanByIdDataLoader
29
30
  from .span_dataset_examples import SpanDatasetExamplesDataLoader
30
31
  from .span_descendants import SpanDescendantsDataLoader
32
+ from .span_fields import SpanFieldsDataLoader
31
33
  from .span_projects import SpanProjectsDataLoader
32
34
  from .token_counts import TokenCountCache, TokenCountDataLoader
33
35
  from .trace_by_trace_ids import TraceByTraceIdsDataLoader
@@ -58,6 +60,8 @@ __all__ = [
58
60
  "SessionNumTracesWithErrorDataLoader",
59
61
  "SessionTokenUsagesDataLoader",
60
62
  "SessionTraceLatencyMsQuantileDataLoader",
63
+ "SpanFieldsDataLoader",
64
+ "SpanByIdDataLoader",
61
65
  "SpanDatasetExamplesDataLoader",
62
66
  "SpanDescendantsDataLoader",
63
67
  "SpanProjectsDataLoader",
@@ -0,0 +1,29 @@
1
+ from typing import Iterable, Union
2
+
3
+ from sqlalchemy import select
4
+ from strawberry.dataloader import DataLoader
5
+ from typing_extensions import TypeAlias
6
+
7
+ from phoenix.db import models
8
+ from phoenix.server.types import DbSessionFactory
9
+
10
+ SpanRowId: TypeAlias = int
11
+
12
+ Key: TypeAlias = SpanRowId
13
+ Result: TypeAlias = models.Span
14
+
15
+
16
+ class SpanByIdDataLoader(DataLoader[Key, Result]):
17
+ def __init__(self, db: DbSessionFactory) -> None:
18
+ super().__init__(load_fn=self._load_fn)
19
+ self._db = db
20
+
21
+ async def _load_fn(self, keys: Iterable[Key]) -> list[Union[Result, ValueError]]:
22
+ span_rowids = list(set(keys))
23
+ spans: dict[Key, Result] = {}
24
+ stmt = select(models.Span).where(models.Span.id.in_(span_rowids))
25
+ async with self._db() as session:
26
+ data = await session.stream_scalars(stmt)
27
+ async for span in data:
28
+ spans[span.id] = span
29
+ return [spans.get(span_rowid, ValueError("Invalid span row id")) for span_rowid in keys]
@@ -1,18 +1,18 @@
1
- from random import randint
1
+ from secrets import token_hex
2
+ from typing import Iterable
2
3
 
3
4
  from aioitertools.itertools import groupby
4
5
  from sqlalchemy import select
5
- from sqlalchemy.orm import joinedload
6
6
  from strawberry.dataloader import DataLoader
7
7
  from typing_extensions import TypeAlias
8
8
 
9
9
  from phoenix.db import models
10
10
  from phoenix.server.types import DbSessionFactory
11
11
 
12
- SpanId: TypeAlias = str
12
+ SpanRowId: TypeAlias = int
13
13
 
14
- Key: TypeAlias = SpanId
15
- Result: TypeAlias = list[models.Span]
14
+ Key: TypeAlias = SpanRowId
15
+ Result: TypeAlias = list[SpanRowId]
16
16
 
17
17
 
18
18
  class SpanDescendantsDataLoader(DataLoader[Key, Result]):
@@ -20,16 +20,25 @@ class SpanDescendantsDataLoader(DataLoader[Key, Result]):
20
20
  super().__init__(load_fn=self._load_fn)
21
21
  self._db = db
22
22
 
23
- async def _load_fn(self, keys: list[Key]) -> list[Result]:
24
- root_ids = set(keys)
25
- root_id_label = f"root_id_{randint(0, 10**6):06}"
23
+ async def _load_fn(self, keys: Iterable[Key]) -> list[Result]:
24
+ root_ids = (
25
+ select(
26
+ models.Span.span_id,
27
+ models.Span.id,
28
+ )
29
+ .where(models.Span.id.in_(set(keys)))
30
+ .subquery()
31
+ )
32
+ root_id_label = f"root_id_{token_hex(8)}"
33
+ root_rowid_label = f"root_rowid_{token_hex(8)}"
26
34
  descendant_ids = (
27
35
  select(
28
36
  models.Span.id,
29
37
  models.Span.span_id,
30
38
  models.Span.parent_id.label(root_id_label),
39
+ root_ids.c.id.label(root_rowid_label),
31
40
  )
32
- .where(models.Span.parent_id.in_(root_ids))
41
+ .join(root_ids, models.Span.parent_id == root_ids.c.span_id)
33
42
  .cte(recursive=True)
34
43
  )
35
44
  parent_ids = descendant_ids.alias()
@@ -38,20 +47,20 @@ class SpanDescendantsDataLoader(DataLoader[Key, Result]):
38
47
  models.Span.id,
39
48
  models.Span.span_id,
40
49
  parent_ids.c[root_id_label],
50
+ parent_ids.c[root_rowid_label],
41
51
  ).join(
42
52
  parent_ids,
43
53
  models.Span.parent_id == parent_ids.c.span_id,
44
54
  )
45
55
  )
46
56
  stmt = (
47
- select(descendant_ids.c[root_id_label], models.Span)
57
+ select(descendant_ids.c[root_rowid_label], models.Span.id)
48
58
  .join(descendant_ids, models.Span.id == descendant_ids.c.id)
49
- .options(joinedload(models.Span.trace, innerjoin=True).load_only(models.Trace.trace_id))
50
- .order_by(descendant_ids.c[root_id_label])
59
+ .order_by(descendant_ids.c[root_rowid_label])
51
60
  )
52
- results: dict[SpanId, Result] = {key: [] for key in keys}
61
+ results: dict[Key, Result] = {key: [] for key in keys}
53
62
  async with self._db() as session:
54
63
  data = await session.stream(stmt)
55
- async for root_id, group in groupby(data, key=lambda d: d[0]):
56
- results[root_id].extend(span for _, span in group)
64
+ async for key, group in groupby(data, key=lambda d: d[0]):
65
+ results[key].extend(span_rowid for _, span_rowid in group)
57
66
  return [results[key].copy() for key in keys]
@@ -0,0 +1,76 @@
1
+ from typing import Any, Iterable, Union
2
+
3
+ from sqlalchemy import Select, select
4
+ from sqlalchemy.orm import QueryableAttribute
5
+ from strawberry.dataloader import DataLoader
6
+ from typing_extensions import TypeAlias
7
+
8
+ from phoenix.db import models
9
+ from phoenix.server.types import DbSessionFactory
10
+
11
+ SpanRowId: TypeAlias = int
12
+
13
+ Key: TypeAlias = tuple[SpanRowId, QueryableAttribute[Any]]
14
+ Result: TypeAlias = Any
15
+
16
+
17
+ _ResultColumnPosition: TypeAlias = int
18
+ _AttrStrIdentifier: TypeAlias = str
19
+
20
+
21
+ class SpanFieldsDataLoader(DataLoader[Key, Result]):
22
+ def __init__(self, db: DbSessionFactory) -> None:
23
+ super().__init__(load_fn=self._load_fn)
24
+ self._db = db
25
+
26
+ async def _load_fn(self, keys: Iterable[Key]) -> list[Union[Result, ValueError]]:
27
+ result: dict[tuple[SpanRowId, _AttrStrIdentifier], Result] = {}
28
+ stmt, attr_strs = _get_stmt(keys)
29
+ async with self._db() as session:
30
+ data = await session.stream(stmt)
31
+ async for row in data:
32
+ span_rowid: SpanRowId = row[0] # models.Span's primary key
33
+ for i, value in enumerate(row[1:]):
34
+ result[span_rowid, attr_strs[i]] = value
35
+ return [result.get((span_rowid, str(attr))) for span_rowid, attr in keys]
36
+
37
+
38
+ def _get_stmt(
39
+ keys: Iterable[Key],
40
+ ) -> tuple[
41
+ Select[Any],
42
+ dict[_ResultColumnPosition, _AttrStrIdentifier],
43
+ ]:
44
+ """
45
+ Generate a SQLAlchemy Select statement and a mapping of attribute identifiers (from their
46
+ column positions in the query result starting at the second column).
47
+
48
+ This function constructs a SQLAlchemy Select statement to query the `Span` model
49
+ based on the provided keys. It also creates a mapping of attribute identifiers
50
+ to their positions in the query result (starting at the second column as the zero-th
51
+ position).
52
+
53
+ Args:
54
+ keys (list[Key]): A list of tuples, where each tuple contains an integer ID, i.e. the
55
+ primary key of models.Span, and a QueryableAttribute.
56
+
57
+ Returns:
58
+ tuple: A tuple containing:
59
+ - Select[Any]: A SQLAlchemy Select statement with `Span` ID and attributes.
60
+ - dict[int, str]: A dictionary mapping the column position--where 0-th position starts
61
+ at the second column (because the first column is the span's primary key)--in the
62
+ result to the attribute's string identifier.
63
+ """
64
+ span_rowids: set[SpanRowId] = set()
65
+ attrs: dict[_AttrStrIdentifier, QueryableAttribute[Any]] = {}
66
+ joins = set()
67
+ for span_rowid, attr in keys:
68
+ span_rowids.add(span_rowid)
69
+ attrs[str(attr)] = attr
70
+ if (entity := attr.parent.entity) is not models.Span:
71
+ joins.add(entity)
72
+ stmt = select(models.Span.id).where(models.Span.id.in_(span_rowids))
73
+ for table in joins:
74
+ stmt = stmt.join(table)
75
+ identifiers, columns = zip(*attrs.items())
76
+ return stmt.add_columns(*columns), dict(enumerate(identifiers))
@@ -1,15 +1,17 @@
1
- from typing import List, Optional
1
+ from typing import Iterable, Optional
2
2
 
3
3
  from sqlalchemy import select
4
- from sqlalchemy.orm import contains_eager
5
4
  from strawberry.dataloader import DataLoader
6
5
  from typing_extensions import TypeAlias
7
6
 
8
7
  from phoenix.db import models
9
8
  from phoenix.server.types import DbSessionFactory
10
9
 
11
- Key: TypeAlias = int
12
- Result: TypeAlias = Optional[models.Span]
10
+ TraceRowId: TypeAlias = int
11
+ SpanRowId: TypeAlias = int
12
+
13
+ Key: TypeAlias = TraceRowId
14
+ Result: TypeAlias = Optional[SpanRowId]
13
15
 
14
16
 
15
17
  class TraceRootSpansDataLoader(DataLoader[Key, Result]):
@@ -17,16 +19,13 @@ class TraceRootSpansDataLoader(DataLoader[Key, Result]):
17
19
  super().__init__(load_fn=self._load_fn)
18
20
  self._db = db
19
21
 
20
- async def _load_fn(self, keys: List[Key]) -> List[Result]:
22
+ async def _load_fn(self, keys: Iterable[Key]) -> list[Result]:
21
23
  stmt = (
22
- select(models.Span)
24
+ select(models.Trace.id, models.Span.id)
23
25
  .join(models.Trace)
24
26
  .where(models.Span.parent_id.is_(None))
25
27
  .where(models.Trace.id.in_(keys))
26
- .options(contains_eager(models.Span.trace).load_only(models.Trace.trace_id))
27
28
  )
28
29
  async with self._db() as session:
29
- result: dict[Key, models.Span] = {
30
- span.trace_rowid: span async for span in await session.stream_scalars(stmt)
31
- }
30
+ result: dict[Key, int] = {k: v async for k, v in await session.stream(stmt)}
32
31
  return [result.get(key) for key in keys]
@@ -60,7 +60,7 @@ from phoenix.server.api.types.ChatCompletionSubscriptionPayload import (
60
60
  from phoenix.server.api.types.Dataset import Dataset
61
61
  from phoenix.server.api.types.DatasetVersion import DatasetVersion
62
62
  from phoenix.server.api.types.node import from_global_id_with_expected_type
63
- from phoenix.server.api.types.Span import Span, to_gql_span
63
+ from phoenix.server.api.types.Span import Span
64
64
  from phoenix.server.dml_event import SpanInsertEvent
65
65
  from phoenix.trace.attributes import unflatten
66
66
  from phoenix.trace.schemas import SpanException
@@ -91,6 +91,7 @@ class ChatCompletionToolCall:
91
91
 
92
92
  @strawberry.type
93
93
  class ChatCompletionMutationPayload:
94
+ db_span: strawberry.Private[models.Span]
94
95
  content: Optional[str]
95
96
  tool_calls: List[ChatCompletionToolCall]
96
97
  span: Span
@@ -188,7 +189,7 @@ class ChatCompletionMutationMixin:
188
189
  session.add(experiment)
189
190
  await session.flush()
190
191
 
191
- results = []
192
+ results: list[Union[ChatCompletionMutationPayload, BaseException]] = []
192
193
  batch_size = 3
193
194
  start_time = datetime.now(timezone.utc)
194
195
  for batch in _get_batches(revisions, batch_size):
@@ -234,19 +235,19 @@ class ChatCompletionMutationMixin:
234
235
  error=str(result),
235
236
  )
236
237
  else:
237
- db_span = result.span.db_span
238
+ db_span: models.Span = result.db_span
238
239
  experiment_run = models.ExperimentRun(
239
240
  experiment_id=experiment.id,
240
241
  dataset_example_id=revision.dataset_example_id,
241
- trace_id=str(result.span.context.trace_id),
242
+ trace_id=db_span.trace.trace_id,
242
243
  output=models.ExperimentRunOutput(
243
244
  task_output=get_dataset_example_output(db_span),
244
245
  ),
245
246
  prompt_token_count=db_span.cumulative_llm_token_count_prompt,
246
247
  completion_token_count=db_span.cumulative_llm_token_count_completion,
247
248
  repetition_number=1,
248
- start_time=result.span.start_time,
249
- end_time=result.span.end_time,
249
+ start_time=db_span.start_time,
250
+ end_time=db_span.end_time,
250
251
  error=str(result.error_message) if result.error_message else None,
251
252
  )
252
253
  experiment_runs.append(experiment_run)
@@ -433,12 +434,13 @@ class ChatCompletionMutationMixin:
433
434
  session.add(span)
434
435
  await session.flush()
435
436
 
436
- gql_span = to_gql_span(span)
437
+ gql_span = Span(span_rowid=span.id, db_span=span)
437
438
 
438
439
  info.context.event_queue.put(SpanInsertEvent(ids=(project_id,)))
439
440
 
440
441
  if status_code is StatusCode.ERROR:
441
442
  return ChatCompletionMutationPayload(
443
+ db_span=span,
442
444
  content=None,
443
445
  tool_calls=[],
444
446
  span=gql_span,
@@ -446,6 +448,7 @@ class ChatCompletionMutationMixin:
446
448
  )
447
449
  else:
448
450
  return ChatCompletionMutationPayload(
451
+ db_span=span,
449
452
  content=text_content if text_content else None,
450
453
  tool_calls=list(tool_calls.values()),
451
454
  span=gql_span,