arize-phoenix 9.6.1__tar.gz → 10.0.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.
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/PKG-INFO +1 -1
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/auth.py +6 -4
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/config.py +150 -25
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/db/README.md +38 -1
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/db/enums.py +1 -2
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/db/facilitator.py +20 -11
- arize_phoenix-10.0.1/src/phoenix/db/migrations/versions/6a88424799fe_update_users_with_auth_method.py +179 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/db/models.py +66 -37
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/context.py +5 -4
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/mutations/user_mutations.py +58 -26
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/routers/auth.py +16 -4
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/routers/oauth2.py +196 -15
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/app.py +36 -10
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/bearer_auth.py +5 -7
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/jwt_store.py +5 -4
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/main.py +11 -4
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/oauth2.py +47 -3
- arize_phoenix-10.0.1/src/phoenix/server/static/.vite/manifest.json +87 -0
- arize_phoenix-9.6.1/src/phoenix/server/static/assets/components-CDvTuTqd.js → arize_phoenix-10.0.1/src/phoenix/server/static/assets/components-D6QBwbkV.js +274 -241
- arize_phoenix-9.6.1/src/phoenix/server/static/assets/index-DpcxdHu4.js → arize_phoenix-10.0.1/src/phoenix/server/static/assets/index-D4fytZZJ.js +11 -11
- arize_phoenix-9.6.1/src/phoenix/server/static/assets/pages-Bcs41-Zv.js → arize_phoenix-10.0.1/src/phoenix/server/static/assets/pages-Bg98duFI.js +350 -381
- arize_phoenix-9.6.1/src/phoenix/server/static/assets/vendor-arizeai-BhbMHqQs.js → arize_phoenix-10.0.1/src/phoenix/server/static/assets/vendor-arizeai-Dy-0mSNw.js +1 -1
- arize_phoenix-9.6.1/src/phoenix/server/static/assets/vendor-codemirror-CeLHFooz.js → arize_phoenix-10.0.1/src/phoenix/server/static/assets/vendor-codemirror-DBtifKNr.js +1 -1
- arize_phoenix-9.6.1/src/phoenix/server/static/assets/vendor-CToBXdDM.js → arize_phoenix-10.0.1/src/phoenix/server/static/assets/vendor-oB4u9zuV.js +11 -11
- arize_phoenix-9.6.1/src/phoenix/server/static/assets/vendor-recharts-PlWJHgM9.js → arize_phoenix-10.0.1/src/phoenix/server/static/assets/vendor-recharts-D-T4KPz2.js +1 -1
- arize_phoenix-9.6.1/src/phoenix/server/static/assets/vendor-shiki-CPwL2jwA.js → arize_phoenix-10.0.1/src/phoenix/server/static/assets/vendor-shiki-BMn4O_9F.js +1 -1
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/templates/index.html +1 -0
- arize_phoenix-10.0.1/src/phoenix/version.py +1 -0
- arize_phoenix-9.6.1/src/phoenix/server/static/.vite/manifest.json +0 -87
- arize_phoenix-9.6.1/src/phoenix/version.py +0 -1
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/.gitignore +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/IP_NOTICE +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/LICENSE +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/README.md +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/pyproject.toml +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/__init__.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/core/__init__.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/core/embedding_dimension.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/core/model.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/core/model_schema.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/core/model_schema_adapter.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/datetime_utils.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/db/__init__.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/db/alembic.ini +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/db/bulk_inserter.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/db/constants.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/db/engines.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/db/helpers.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/db/insertion/__init__.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/db/insertion/constants.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/db/insertion/dataset.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/db/insertion/document_annotation.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/db/insertion/evaluation.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/db/insertion/helpers.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/db/insertion/span.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/db/insertion/span_annotation.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/db/insertion/trace_annotation.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/db/insertion/types.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/db/migrate.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/db/migrations/__init__.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/db/migrations/data_migration_scripts/__init__.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/db/migrations/data_migration_scripts/populate_project_sessions.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/db/migrations/env.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/db/migrations/script.py.mako +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/db/migrations/versions/10460e46d750_datasets.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/db/migrations/versions/2f9d1a65945f_annotation_config_migration.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/db/migrations/versions/3be8647b87d8_add_token_columns_to_spans_table.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/db/migrations/versions/4ded9e43755f_create_project_sessions_table.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/db/migrations/versions/8a3764fe7f1a_change_jsonb_to_json_for_prompts.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/db/migrations/versions/bb8139330879_create_project_trace_retention_policies_table.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/db/migrations/versions/bc8fea3c2bc8_add_prompt_tables.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/db/migrations/versions/cd164e83824f_users_and_tokens.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/db/migrations/versions/cf03bd6bae1d_init.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/db/pg_config.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/db/types/__init__.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/db/types/annotation_configs.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/db/types/db_models.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/db/types/identifier.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/db/types/model_provider.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/db/types/trace_retention.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/exceptions.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/experiments/__init__.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/experiments/evaluators/__init__.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/experiments/evaluators/base.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/experiments/evaluators/code_evaluators.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/experiments/evaluators/llm_evaluators.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/experiments/evaluators/utils.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/experiments/functions.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/experiments/tracing.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/experiments/types.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/experiments/utils.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/inferences/__init__.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/inferences/errors.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/inferences/fixtures.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/inferences/inferences.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/inferences/schema.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/inferences/validation.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/logging/__init__.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/logging/_config.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/logging/_filter.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/logging/_formatter.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/metrics/README.md +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/metrics/__init__.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/metrics/binning.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/metrics/metrics.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/metrics/mixins.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/metrics/retrieval_metrics.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/metrics/timeseries.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/metrics/wrappers.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/pointcloud/__init__.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/pointcloud/clustering.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/pointcloud/pointcloud.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/pointcloud/projectors.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/pointcloud/umap_parameters.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/py.typed +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/__init__.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/README.md +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/__init__.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/auth.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/dataloaders/__init__.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/dataloaders/annotation_summaries.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/dataloaders/average_experiment_run_latency.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/dataloaders/cache/__init__.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/dataloaders/cache/two_tier_cache.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/dataloaders/dataset_example_revisions.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/dataloaders/dataset_example_spans.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/dataloaders/document_evaluation_summaries.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/dataloaders/document_evaluations.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/dataloaders/document_retrieval_metrics.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/dataloaders/experiment_annotation_summaries.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/dataloaders/experiment_error_rates.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/dataloaders/experiment_run_annotations.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/dataloaders/experiment_run_counts.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/dataloaders/experiment_sequence_number.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/dataloaders/latency_ms_quantile.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/dataloaders/min_start_or_max_end_times.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/dataloaders/num_child_spans.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/dataloaders/num_spans_per_trace.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/dataloaders/project_by_name.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/dataloaders/project_ids_by_trace_retention_policy_id.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/dataloaders/prompt_version_sequence_number.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/dataloaders/record_counts.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/dataloaders/session_io.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/dataloaders/session_num_traces.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/dataloaders/session_num_traces_with_error.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/dataloaders/session_token_usages.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/dataloaders/session_trace_latency_ms_quantile.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/dataloaders/span_annotations.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/dataloaders/span_by_id.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/dataloaders/span_dataset_examples.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/dataloaders/span_descendants.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/dataloaders/span_projects.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/dataloaders/table_fields.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/dataloaders/token_counts.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/dataloaders/trace_by_trace_ids.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/dataloaders/trace_retention_policy_id_by_project_id.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/dataloaders/trace_root_spans.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/dataloaders/user_roles.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/dataloaders/users.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/exceptions.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/helpers/__init__.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/helpers/annotations.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/helpers/dataset_helpers.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/helpers/experiment_run_filters.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/helpers/playground_clients.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/helpers/playground_registry.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/helpers/playground_spans.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/helpers/prompts/__init__.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/helpers/prompts/conversions/__init__.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/helpers/prompts/conversions/anthropic.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/helpers/prompts/conversions/openai.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/helpers/prompts/models.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/input_types/AddExamplesToDatasetInput.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/input_types/AddSpansToDatasetInput.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/input_types/ChatCompletionInput.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/input_types/ChatCompletionMessageInput.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/input_types/ClearProjectInput.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/input_types/ClusterInput.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/input_types/Coordinates.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/input_types/CreateDatasetInput.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/input_types/CreateSpanAnnotationInput.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/input_types/CreateTraceAnnotationInput.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/input_types/DataQualityMetricInput.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/input_types/DatasetExampleInput.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/input_types/DatasetSort.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/input_types/DatasetVersionSort.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/input_types/DeleteAnnotationsInput.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/input_types/DeleteDatasetExamplesInput.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/input_types/DeleteDatasetInput.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/input_types/DeleteExperimentsInput.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/input_types/DimensionFilter.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/input_types/DimensionInput.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/input_types/GenerativeModelInput.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/input_types/Granularity.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/input_types/InvocationParameters.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/input_types/PatchAnnotationInput.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/input_types/PatchDatasetExamplesInput.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/input_types/PatchDatasetInput.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/input_types/PerformanceMetricInput.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/input_types/ProjectFilter.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/input_types/ProjectSessionSort.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/input_types/ProjectSort.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/input_types/PromptTemplateOptions.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/input_types/PromptVersionInput.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/input_types/SpanAnnotationFilter.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/input_types/SpanAnnotationSort.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/input_types/SpanSort.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/input_types/TimeRange.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/input_types/TraceAnnotationSort.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/input_types/UserRoleInput.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/input_types/__init__.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/interceptor.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/mutations/__init__.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/mutations/annotation_config_mutations.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/mutations/api_key_mutations.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/mutations/chat_mutations.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/mutations/dataset_mutations.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/mutations/experiment_mutations.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/mutations/export_events_mutations.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/mutations/project_mutations.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/mutations/project_trace_retention_policy_mutations.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/mutations/prompt_label_mutations.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/mutations/prompt_mutations.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/mutations/prompt_version_tag_mutations.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/mutations/span_annotations_mutations.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/mutations/trace_annotations_mutations.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/mutations/trace_mutations.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/openapi/__init__.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/openapi/main.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/openapi/schema.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/queries.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/routers/__init__.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/routers/embeddings.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/routers/utils.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/routers/v1/__init__.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/routers/v1/annotation_configs.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/routers/v1/annotations.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/routers/v1/datasets.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/routers/v1/evaluations.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/routers/v1/experiment_evaluations.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/routers/v1/experiment_runs.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/routers/v1/experiments.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/routers/v1/models.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/routers/v1/projects.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/routers/v1/prompts.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/routers/v1/spans.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/routers/v1/traces.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/routers/v1/utils.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/schema.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/subscriptions.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/Annotation.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/AnnotationConfig.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/AnnotationSource.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/AnnotationSummary.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/AnnotatorKind.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/ApiKey.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/AuthMethod.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/ChatCompletionMessageRole.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/ChatCompletionSubscriptionPayload.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/Cluster.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/CreateDatasetPayload.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/CronExpression.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/DataQualityMetric.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/Dataset.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/DatasetExample.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/DatasetExampleRevision.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/DatasetValues.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/DatasetVersion.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/Dimension.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/DimensionDataType.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/DimensionShape.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/DimensionType.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/DimensionWithValue.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/DocumentEvaluationSummary.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/DocumentRetrievalMetrics.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/EmbeddingDimension.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/EmbeddingMetadata.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/Evaluation.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/EvaluationSummary.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/Event.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/EventMetadata.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/ExampleRevisionInterface.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/Experiment.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/ExperimentAnnotationSummary.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/ExperimentComparison.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/ExperimentRun.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/ExperimentRunAnnotation.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/ExportedFile.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/Functionality.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/GenerativeModel.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/GenerativeProvider.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/Identifier.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/Inferences.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/InferencesRole.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/LabelFraction.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/MimeType.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/Model.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/NumericRange.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/PerformanceMetric.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/Project.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/ProjectSession.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/ProjectTraceRetentionPolicy.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/Prompt.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/PromptLabel.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/PromptResponse.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/PromptVersion.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/PromptVersionTag.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/PromptVersionTemplate.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/ResponseFormat.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/Retrieval.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/ScalarDriftMetricEnum.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/Segments.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/SortDir.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/Span.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/SpanAnnotation.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/SpanIOValue.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/SystemApiKey.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/TimeSeries.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/TokenCountPromptDetails.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/TokenUsage.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/ToolDefinition.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/Trace.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/TraceAnnotation.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/UMAPPoints.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/User.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/UserApiKey.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/UserRole.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/ValidationResult.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/VectorDriftMetricEnum.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/__init__.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/node.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/types/pagination.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/api/utils.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/authorization.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/cost_tracking/__init__.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/cost_tracking/cost_lookup.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/cost_tracking/model_cost_manifest.json +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/dml_event.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/dml_event_handler.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/email/__init__.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/email/sender.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/email/templates/__init__.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/email/templates/password_reset.html +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/email/templates/welcome.html +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/email/types.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/grpc_server.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/middleware/__init__.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/middleware/gzip.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/openapi/__init__.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/prometheus.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/rate_limiters.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/retention.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/static/apple-touch-icon-114x114.png +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/static/apple-touch-icon-120x120.png +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/static/apple-touch-icon-144x144.png +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/static/apple-touch-icon-152x152.png +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/static/apple-touch-icon-180x180.png +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/static/apple-touch-icon-72x72.png +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/static/apple-touch-icon-76x76.png +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/static/apple-touch-icon.png +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/static/assets/vendor-WIZid84E.css +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/static/assets/vendor-three-C5WAXd5r.js +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/static/favicon.ico +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/static/modernizr.js +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/telemetry.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/templates/__init__.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/thread_server.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/server/types.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/services.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/session/__init__.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/session/client.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/session/data_extractor.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/session/evaluation.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/session/session.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/settings.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/trace/__init__.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/trace/attributes.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/trace/dsl/README.md +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/trace/dsl/__init__.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/trace/dsl/filter.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/trace/dsl/helpers.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/trace/dsl/query.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/trace/errors.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/trace/evaluation_conventions.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/trace/exporter.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/trace/fixtures.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/trace/otel.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/trace/projects.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/trace/schemas.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/trace/span_evaluations.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/trace/span_json_decoder.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/trace/span_json_encoder.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/trace/trace_dataset.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/trace/utils.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/trace/v1/__init__.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/trace/v1/evaluation_pb2.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/trace/v1/evaluation_pb2.pyi +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/utilities/__init__.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/utilities/client.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/utilities/deprecation.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/utilities/error_handling.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/utilities/json.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/utilities/logging.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/utilities/project.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/utilities/re.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/utilities/span_store.py +0 -0
- {arize_phoenix-9.6.1 → arize_phoenix-10.0.1}/src/phoenix/utilities/template_formatters.py +0 -0
|
@@ -7,15 +7,16 @@ from enum import Enum, auto
|
|
|
7
7
|
from hashlib import pbkdf2_hmac
|
|
8
8
|
from typing import Any, Literal, Optional, Protocol
|
|
9
9
|
|
|
10
|
+
from starlette.datastructures import Secret
|
|
10
11
|
from starlette.responses import Response
|
|
11
12
|
from typing_extensions import TypeVar
|
|
12
13
|
|
|
13
|
-
from phoenix.config import get_env_phoenix_use_secure_cookies
|
|
14
|
+
from phoenix.config import get_env_cookies_path, get_env_phoenix_use_secure_cookies
|
|
14
15
|
|
|
15
16
|
ResponseType = TypeVar("ResponseType", bound=Response)
|
|
16
17
|
|
|
17
18
|
|
|
18
|
-
def compute_password_hash(*, password:
|
|
19
|
+
def compute_password_hash(*, password: Secret, salt: bytes) -> bytes:
|
|
19
20
|
"""
|
|
20
21
|
Salts and hashes a password using PBKDF2, HMAC and SHA256.
|
|
21
22
|
|
|
@@ -26,11 +27,11 @@ def compute_password_hash(*, password: str, salt: bytes) -> bytes:
|
|
|
26
27
|
bytes: the hashed password
|
|
27
28
|
"""
|
|
28
29
|
assert salt
|
|
29
|
-
password_bytes = password.encode("utf-8")
|
|
30
|
+
password_bytes = str(password).encode("utf-8")
|
|
30
31
|
return pbkdf2_hmac("sha256", password_bytes, salt, NUM_ITERATIONS)
|
|
31
32
|
|
|
32
33
|
|
|
33
|
-
def is_valid_password(*, password:
|
|
34
|
+
def is_valid_password(*, password: Secret, salt: bytes, password_hash: bytes) -> bool:
|
|
34
35
|
"""
|
|
35
36
|
Determines whether the password is valid by salting and hashing the password
|
|
36
37
|
and comparing against the existing hash value.
|
|
@@ -131,6 +132,7 @@ def _set_cookie(
|
|
|
131
132
|
httponly=True,
|
|
132
133
|
samesite=samesite,
|
|
133
134
|
max_age=int(cookie_max_age.total_seconds()),
|
|
135
|
+
path=get_env_cookies_path(),
|
|
134
136
|
)
|
|
135
137
|
return response
|
|
136
138
|
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import logging
|
|
2
4
|
import os
|
|
3
5
|
import re
|
|
@@ -7,16 +9,18 @@ from datetime import timedelta
|
|
|
7
9
|
from enum import Enum
|
|
8
10
|
from importlib.metadata import version
|
|
9
11
|
from pathlib import Path
|
|
10
|
-
from typing import Any, Optional, Union, cast, overload
|
|
12
|
+
from typing import TYPE_CHECKING, Any, NamedTuple, Optional, Union, cast, overload
|
|
11
13
|
from urllib.parse import quote_plus, urljoin, urlparse
|
|
12
14
|
|
|
13
15
|
import wrapt
|
|
14
16
|
from email_validator import EmailNotValidError, validate_email
|
|
15
|
-
from starlette.datastructures import URL
|
|
17
|
+
from starlette.datastructures import URL, Secret
|
|
16
18
|
|
|
17
19
|
from phoenix.utilities.logging import log_a_list
|
|
20
|
+
from phoenix.utilities.re import parse_env_headers
|
|
18
21
|
|
|
19
|
-
|
|
22
|
+
if TYPE_CHECKING:
|
|
23
|
+
from phoenix.server.oauth2 import OAuth2Clients
|
|
20
24
|
|
|
21
25
|
logger = logging.getLogger(__name__)
|
|
22
26
|
|
|
@@ -138,6 +142,11 @@ ENV_PHOENIX_SERVER_INSTRUMENTATION_OTLP_TRACE_COLLECTOR_GRPC_ENDPOINT = (
|
|
|
138
142
|
|
|
139
143
|
# Authentication settings
|
|
140
144
|
ENV_PHOENIX_ENABLE_AUTH = "PHOENIX_ENABLE_AUTH"
|
|
145
|
+
ENV_PHOENIX_DISABLE_BASIC_AUTH = "PHOENIX_DISABLE_BASIC_AUTH"
|
|
146
|
+
"""
|
|
147
|
+
Forbid login via password and disable the creation of local users, which log in via passwords.
|
|
148
|
+
This can be helpful in setups where authentication is handled entirely through OAUTH2.
|
|
149
|
+
"""
|
|
141
150
|
ENV_PHOENIX_DISABLE_RATE_LIMIT = "PHOENIX_DISABLE_RATE_LIMIT"
|
|
142
151
|
ENV_PHOENIX_SECRET = "PHOENIX_SECRET"
|
|
143
152
|
"""
|
|
@@ -160,6 +169,7 @@ be updated manually in the application.
|
|
|
160
169
|
"""
|
|
161
170
|
ENV_PHOENIX_API_KEY = "PHOENIX_API_KEY"
|
|
162
171
|
ENV_PHOENIX_USE_SECURE_COOKIES = "PHOENIX_USE_SECURE_COOKIES"
|
|
172
|
+
ENV_PHOENIX_COOKIES_PATH = "PHOENIX_COOKIES_PATH"
|
|
163
173
|
ENV_PHOENIX_ACCESS_TOKEN_EXPIRY_MINUTES = "PHOENIX_ACCESS_TOKEN_EXPIRY_MINUTES"
|
|
164
174
|
"""
|
|
165
175
|
The duration, in minutes, before access tokens expire.
|
|
@@ -555,7 +565,7 @@ def _bool_val(env_var: str, default: Optional[bool] = None) -> Optional[bool]:
|
|
|
555
565
|
assert (lower := value.lower()) in (
|
|
556
566
|
"true",
|
|
557
567
|
"false",
|
|
558
|
-
), f"{env_var} must be set to TRUE or FALSE (case-insensitive)"
|
|
568
|
+
), f"{env_var} must be set to TRUE or FALSE (case-insensitive). Got: {value}"
|
|
559
569
|
return lower == "true"
|
|
560
570
|
|
|
561
571
|
|
|
@@ -573,8 +583,7 @@ def _float_val(env_var: str, default: Optional[float] = None) -> Optional[float]
|
|
|
573
583
|
return float(value)
|
|
574
584
|
except ValueError:
|
|
575
585
|
raise ValueError(
|
|
576
|
-
f"Invalid value for environment variable {env_var}: {value}. "
|
|
577
|
-
f"Value must be a number."
|
|
586
|
+
f"Invalid value for environment variable {env_var}: {value}. Value must be a number."
|
|
578
587
|
)
|
|
579
588
|
|
|
580
589
|
|
|
@@ -592,8 +601,7 @@ def _int_val(env_var: str, default: Optional[int] = None) -> Optional[int]:
|
|
|
592
601
|
return int(value)
|
|
593
602
|
except ValueError:
|
|
594
603
|
raise ValueError(
|
|
595
|
-
f"Invalid value for environment variable {env_var}: {value}. "
|
|
596
|
-
f"Value must be an integer."
|
|
604
|
+
f"Invalid value for environment variable {env_var}: {value}. Value must be an integer."
|
|
597
605
|
)
|
|
598
606
|
|
|
599
607
|
|
|
@@ -631,6 +639,13 @@ def get_env_enable_auth() -> bool:
|
|
|
631
639
|
return _bool_val(ENV_PHOENIX_ENABLE_AUTH, False)
|
|
632
640
|
|
|
633
641
|
|
|
642
|
+
def get_env_disable_basic_auth() -> bool:
|
|
643
|
+
"""
|
|
644
|
+
Gets the value of the ENV_PHOENIX_DISABLE_BASIC_AUTH environment variable.
|
|
645
|
+
"""
|
|
646
|
+
return _bool_val(ENV_PHOENIX_DISABLE_BASIC_AUTH, False)
|
|
647
|
+
|
|
648
|
+
|
|
634
649
|
def get_env_disable_rate_limit() -> bool:
|
|
635
650
|
"""
|
|
636
651
|
Gets the value of the PHOENIX_DISABLE_RATE_LIMIT environment variable.
|
|
@@ -638,29 +653,29 @@ def get_env_disable_rate_limit() -> bool:
|
|
|
638
653
|
return _bool_val(ENV_PHOENIX_DISABLE_RATE_LIMIT, False)
|
|
639
654
|
|
|
640
655
|
|
|
641
|
-
def get_env_phoenix_secret() ->
|
|
656
|
+
def get_env_phoenix_secret() -> Secret:
|
|
642
657
|
"""
|
|
643
658
|
Gets the value of the PHOENIX_SECRET environment variable
|
|
644
659
|
and performs validation.
|
|
645
660
|
"""
|
|
646
661
|
phoenix_secret = getenv(ENV_PHOENIX_SECRET)
|
|
647
662
|
if phoenix_secret is None:
|
|
648
|
-
return
|
|
663
|
+
return Secret("")
|
|
649
664
|
from phoenix.auth import REQUIREMENTS_FOR_PHOENIX_SECRET
|
|
650
665
|
|
|
651
666
|
REQUIREMENTS_FOR_PHOENIX_SECRET.validate(phoenix_secret, "Phoenix secret")
|
|
652
|
-
return phoenix_secret
|
|
667
|
+
return Secret(phoenix_secret)
|
|
653
668
|
|
|
654
669
|
|
|
655
|
-
def get_env_phoenix_admin_secret() ->
|
|
670
|
+
def get_env_phoenix_admin_secret() -> Secret:
|
|
656
671
|
"""
|
|
657
672
|
Gets the value of the PHOENIX_ADMIN_SECRET environment variable
|
|
658
673
|
and performs validation.
|
|
659
674
|
"""
|
|
660
675
|
phoenix_admin_secret = getenv(ENV_PHOENIX_ADMIN_SECRET)
|
|
661
676
|
if phoenix_admin_secret is None:
|
|
662
|
-
return
|
|
663
|
-
if (phoenix_secret := get_env_phoenix_secret())
|
|
677
|
+
return Secret("")
|
|
678
|
+
if not (phoenix_secret := get_env_phoenix_secret()):
|
|
664
679
|
raise ValueError(
|
|
665
680
|
f"`{ENV_PHOENIX_ADMIN_SECRET}` must be not be set without "
|
|
666
681
|
f"setting `{ENV_PHOENIX_SECRET}`."
|
|
@@ -668,17 +683,24 @@ def get_env_phoenix_admin_secret() -> Optional[str]:
|
|
|
668
683
|
from phoenix.auth import REQUIREMENTS_FOR_PHOENIX_SECRET
|
|
669
684
|
|
|
670
685
|
REQUIREMENTS_FOR_PHOENIX_SECRET.validate(phoenix_admin_secret, "Phoenix secret")
|
|
671
|
-
if phoenix_admin_secret == phoenix_secret:
|
|
686
|
+
if phoenix_admin_secret == str(phoenix_secret):
|
|
672
687
|
raise ValueError(
|
|
673
688
|
f"`{ENV_PHOENIX_ADMIN_SECRET}` must be different from `{ENV_PHOENIX_SECRET}`"
|
|
674
689
|
)
|
|
675
|
-
return phoenix_admin_secret
|
|
690
|
+
return Secret(phoenix_admin_secret)
|
|
676
691
|
|
|
677
692
|
|
|
678
|
-
def get_env_default_admin_initial_password() ->
|
|
693
|
+
def get_env_default_admin_initial_password() -> Secret:
|
|
679
694
|
from phoenix.auth import DEFAULT_ADMIN_PASSWORD
|
|
680
695
|
|
|
681
|
-
return getenv(ENV_PHOENIX_DEFAULT_ADMIN_INITIAL_PASSWORD) or DEFAULT_ADMIN_PASSWORD
|
|
696
|
+
return Secret(getenv(ENV_PHOENIX_DEFAULT_ADMIN_INITIAL_PASSWORD) or DEFAULT_ADMIN_PASSWORD)
|
|
697
|
+
|
|
698
|
+
|
|
699
|
+
def get_env_cookies_path() -> str:
|
|
700
|
+
"""
|
|
701
|
+
Gets the value of the PHOENIX_COOKIE_PATH environment variable.
|
|
702
|
+
"""
|
|
703
|
+
return getenv(ENV_PHOENIX_COOKIES_PATH, "/")
|
|
682
704
|
|
|
683
705
|
|
|
684
706
|
def get_env_phoenix_use_secure_cookies() -> bool:
|
|
@@ -689,7 +711,15 @@ def get_env_phoenix_api_key() -> Optional[str]:
|
|
|
689
711
|
return getenv(ENV_PHOENIX_API_KEY)
|
|
690
712
|
|
|
691
713
|
|
|
692
|
-
|
|
714
|
+
class AuthSettings(NamedTuple):
|
|
715
|
+
enable_auth: bool
|
|
716
|
+
disable_basic_auth: bool
|
|
717
|
+
phoenix_secret: Secret
|
|
718
|
+
phoenix_admin_secret: Secret
|
|
719
|
+
oauth2_clients: OAuth2Clients
|
|
720
|
+
|
|
721
|
+
|
|
722
|
+
def get_env_auth_settings() -> AuthSettings:
|
|
693
723
|
"""
|
|
694
724
|
Gets auth settings and performs validation.
|
|
695
725
|
"""
|
|
@@ -700,7 +730,22 @@ def get_env_auth_settings() -> tuple[bool, Optional[str]]:
|
|
|
700
730
|
f"`{ENV_PHOENIX_SECRET}` must be set when "
|
|
701
731
|
f"auth is enabled with `{ENV_PHOENIX_ENABLE_AUTH}`"
|
|
702
732
|
)
|
|
703
|
-
|
|
733
|
+
phoenix_admin_secret = get_env_phoenix_admin_secret()
|
|
734
|
+
disable_basic_auth = get_env_disable_basic_auth()
|
|
735
|
+
from phoenix.server.oauth2 import OAuth2Clients
|
|
736
|
+
|
|
737
|
+
oauth2_clients = OAuth2Clients.from_configs(get_env_oauth2_settings())
|
|
738
|
+
if enable_auth and disable_basic_auth and not oauth2_clients:
|
|
739
|
+
raise ValueError(
|
|
740
|
+
"OAuth2 is the only supported auth method but no OAuth2 client configs are provided."
|
|
741
|
+
)
|
|
742
|
+
return AuthSettings(
|
|
743
|
+
enable_auth=enable_auth,
|
|
744
|
+
disable_basic_auth=disable_basic_auth,
|
|
745
|
+
phoenix_secret=phoenix_secret,
|
|
746
|
+
phoenix_admin_secret=phoenix_admin_secret,
|
|
747
|
+
oauth2_clients=oauth2_clients,
|
|
748
|
+
)
|
|
704
749
|
|
|
705
750
|
|
|
706
751
|
def get_env_password_reset_token_expiry() -> timedelta:
|
|
@@ -839,6 +884,8 @@ class OAuth2ClientConfig:
|
|
|
839
884
|
client_id: str
|
|
840
885
|
client_secret: str
|
|
841
886
|
oidc_config_url: str
|
|
887
|
+
allow_sign_up: bool
|
|
888
|
+
auto_login: bool
|
|
842
889
|
|
|
843
890
|
@classmethod
|
|
844
891
|
def from_env(cls, idp_name: str) -> "OAuth2ClientConfig":
|
|
@@ -870,6 +917,8 @@ class OAuth2ClientConfig:
|
|
|
870
917
|
f"An OpenID Connect configuration URL must be set for the {idp_name} OAuth2 IDP "
|
|
871
918
|
f"via the {oidc_config_url_env_var} environment variable"
|
|
872
919
|
)
|
|
920
|
+
allow_sign_up = get_env_oauth2_allow_sign_up(idp_name)
|
|
921
|
+
auto_login = get_env_oauth2_auto_login(idp_name)
|
|
873
922
|
parsed_oidc_config_url = urlparse(oidc_config_url)
|
|
874
923
|
is_local_oidc_config_url = parsed_oidc_config_url.hostname in ("localhost", "127.0.0.1")
|
|
875
924
|
if parsed_oidc_config_url.scheme != "https" and not is_local_oidc_config_url:
|
|
@@ -886,17 +935,52 @@ class OAuth2ClientConfig:
|
|
|
886
935
|
client_id=client_id,
|
|
887
936
|
client_secret=client_secret,
|
|
888
937
|
oidc_config_url=oidc_config_url,
|
|
938
|
+
allow_sign_up=allow_sign_up,
|
|
939
|
+
auto_login=auto_login,
|
|
889
940
|
)
|
|
890
941
|
|
|
891
942
|
|
|
892
943
|
def get_env_oauth2_settings() -> list[OAuth2ClientConfig]:
|
|
893
944
|
"""
|
|
894
|
-
|
|
895
|
-
|
|
945
|
+
Retrieves and validates OAuth2/OpenID Connect (OIDC) identity provider configurations from environment variables.
|
|
946
|
+
|
|
947
|
+
This function scans the environment for OAuth2 configuration variables and returns a list of
|
|
948
|
+
configured identity providers. It supports multiple identity providers simultaneously.
|
|
949
|
+
|
|
950
|
+
Environment Variable Pattern:
|
|
951
|
+
PHOENIX_OAUTH2_{IDP_NAME}_{CONFIG_TYPE}
|
|
896
952
|
|
|
953
|
+
Required Environment Variables for each IDP:
|
|
954
|
+
- PHOENIX_OAUTH2_{IDP_NAME}_CLIENT_ID: The OAuth2 client ID issued by the identity provider
|
|
955
|
+
- PHOENIX_OAUTH2_{IDP_NAME}_CLIENT_SECRET: The OAuth2 client secret issued by the identity provider
|
|
956
|
+
- PHOENIX_OAUTH2_{IDP_NAME}_OIDC_CONFIG_URL: The OpenID Connect configuration URL (must be HTTPS)
|
|
957
|
+
|
|
958
|
+
Optional Environment Variables:
|
|
959
|
+
- PHOENIX_OAUTH2_{IDP_NAME}_DISPLAY_NAME: A user-friendly name for the identity provider
|
|
960
|
+
- PHOENIX_OAUTH2_{IDP_NAME}_ALLOW_SIGN_UP: Whether to allow new user registration (defaults to True)
|
|
961
|
+
When set to False, the system will check if the user exists in the database by their email address.
|
|
962
|
+
If the user does not exist or has a password set, they will be redirected to the login page with
|
|
963
|
+
an error message.
|
|
964
|
+
|
|
965
|
+
Returns:
|
|
966
|
+
list[OAuth2ClientConfig]: A list of configured OAuth2 identity providers, sorted alphabetically by IDP name.
|
|
967
|
+
Each OAuth2ClientConfig contains the validated configuration for one identity provider.
|
|
968
|
+
|
|
969
|
+
Raises:
|
|
970
|
+
ValueError: If required environment variables are missing or invalid.
|
|
971
|
+
Specifically, if the OIDC configuration URL is not HTTPS (except for localhost).
|
|
972
|
+
|
|
973
|
+
Example:
|
|
974
|
+
To configure Google as an identity provider, set these environment variables:
|
|
975
|
+
PHOENIX_OAUTH2_GOOGLE_CLIENT_ID=your_client_id
|
|
976
|
+
PHOENIX_OAUTH2_GOOGLE_CLIENT_SECRET=your_client_secret
|
|
977
|
+
PHOENIX_OAUTH2_GOOGLE_OIDC_CONFIG_URL=https://accounts.google.com/.well-known/openid-configuration
|
|
978
|
+
PHOENIX_OAUTH2_GOOGLE_DISPLAY_NAME=Google (optional)
|
|
979
|
+
PHOENIX_OAUTH2_GOOGLE_ALLOW_SIGN_UP=true (optional, defaults to true)
|
|
980
|
+
""" # noqa: E501
|
|
897
981
|
idp_names = set()
|
|
898
982
|
pattern = re.compile(
|
|
899
|
-
r"^PHOENIX_OAUTH2_(\w+)_(DISPLAY_NAME|CLIENT_ID|CLIENT_SECRET|OIDC_CONFIG_URL)$"
|
|
983
|
+
r"^PHOENIX_OAUTH2_(\w+)_(DISPLAY_NAME|CLIENT_ID|CLIENT_SECRET|OIDC_CONFIG_URL|ALLOW_SIGN_UP|AUTO_LOGIN)$" # noqa: E501
|
|
900
984
|
)
|
|
901
985
|
for env_var in os.environ:
|
|
902
986
|
if (match := pattern.match(env_var)) is not None and (idp_name := match.group(1).lower()):
|
|
@@ -904,6 +988,47 @@ def get_env_oauth2_settings() -> list[OAuth2ClientConfig]:
|
|
|
904
988
|
return [OAuth2ClientConfig.from_env(idp_name) for idp_name in sorted(idp_names)]
|
|
905
989
|
|
|
906
990
|
|
|
991
|
+
def get_env_oauth2_allow_sign_up(idp_name: str) -> bool:
|
|
992
|
+
"""Retrieves the allow_sign_up setting for a specific OAuth2 identity provider.
|
|
993
|
+
|
|
994
|
+
This function determines whether new user registration is allowed for the specified identity provider.
|
|
995
|
+
When set to False, the system will check if the user exists in the database by their email address.
|
|
996
|
+
If the user does not exist or has a password set, they will be redirected to the login page with
|
|
997
|
+
an error message.
|
|
998
|
+
|
|
999
|
+
Parameters:
|
|
1000
|
+
idp_name (str): The name of the identity provider (e.g., 'google', 'aws_cognito', 'microsoft_entra_id')
|
|
1001
|
+
|
|
1002
|
+
Returns:
|
|
1003
|
+
bool: True if new user registration is allowed (default), False otherwise
|
|
1004
|
+
|
|
1005
|
+
Environment Variable:
|
|
1006
|
+
PHOENIX_OAUTH2_{IDP_NAME}_ALLOW_SIGN_UP: Controls whether new user registration is allowed (defaults to True if not set)
|
|
1007
|
+
""" # noqa: E501
|
|
1008
|
+
env_var = f"PHOENIX_OAUTH2_{idp_name}_ALLOW_SIGN_UP".upper()
|
|
1009
|
+
return _bool_val(env_var, True)
|
|
1010
|
+
|
|
1011
|
+
|
|
1012
|
+
def get_env_oauth2_auto_login(idp_name: str) -> bool:
|
|
1013
|
+
"""Retrieves the auto_login setting for a specific OAuth2 identity provider.
|
|
1014
|
+
|
|
1015
|
+
This function determines whether users should be automatically logged in when accessing the OAuth2
|
|
1016
|
+
identity provider's login page. When set to True, users will be redirected to the identity provider's
|
|
1017
|
+
login page without first seeing the application's login page.
|
|
1018
|
+
|
|
1019
|
+
Parameters:
|
|
1020
|
+
idp_name (str): The name of the identity provider (e.g., 'google', 'aws_cognito', 'microsoft_entra_id')
|
|
1021
|
+
|
|
1022
|
+
Returns:
|
|
1023
|
+
bool: True if auto-login is enabled, False otherwise (defaults to False if not set)
|
|
1024
|
+
|
|
1025
|
+
Environment Variable:
|
|
1026
|
+
PHOENIX_OAUTH2_{IDP_NAME}_AUTO_LOGIN: Controls whether auto-login is enabled (defaults to False if not set)
|
|
1027
|
+
""" # noqa: E501
|
|
1028
|
+
env_var = f"PHOENIX_OAUTH2_{idp_name}_AUTO_LOGIN".upper()
|
|
1029
|
+
return _bool_val(env_var, False)
|
|
1030
|
+
|
|
1031
|
+
|
|
907
1032
|
PHOENIX_DIR = Path(__file__).resolve().parent
|
|
908
1033
|
# Server config
|
|
909
1034
|
SERVER_DIR = PHOENIX_DIR / "server"
|
|
@@ -1258,7 +1383,7 @@ def get_env_logging_mode() -> LoggingMode:
|
|
|
1258
1383
|
except ValueError:
|
|
1259
1384
|
raise ValueError(
|
|
1260
1385
|
f"Invalid value `{logging_mode}` for env var `{ENV_LOGGING_MODE}`. "
|
|
1261
|
-
f"Valid values are: {log_a_list([mode.value for mode in LoggingMode],'and')} "
|
|
1386
|
+
f"Valid values are: {log_a_list([mode.value for mode in LoggingMode], 'and')} "
|
|
1262
1387
|
"(case-insensitive)."
|
|
1263
1388
|
)
|
|
1264
1389
|
|
|
@@ -1337,7 +1462,7 @@ def _get_logging_level(env_var: str, default_level: int) -> int:
|
|
|
1337
1462
|
if logging_level.upper() not in valid_values:
|
|
1338
1463
|
raise ValueError(
|
|
1339
1464
|
f"Invalid value `{logging_level}` for env var `{env_var}`. "
|
|
1340
|
-
f"Valid values are: {log_a_list(valid_values,'and')} (case-insensitive)."
|
|
1465
|
+
f"Valid values are: {log_a_list(valid_values, 'and')} (case-insensitive)."
|
|
1341
1466
|
)
|
|
1342
1467
|
return levelNamesMapping[logging_level.upper()]
|
|
1343
1468
|
|
|
@@ -53,13 +53,23 @@ alembic revision -m "your_revision_name"
|
|
|
53
53
|
|
|
54
54
|
Then fill the migration file with the necessary changes.
|
|
55
55
|
|
|
56
|
-
## Entity Relationship Diagram
|
|
56
|
+
## Entity Relationship Diagram (ERD)
|
|
57
57
|
|
|
58
58
|
Below is a Mermaid diagram showing the current relationships between the main entities in the database:
|
|
59
59
|
|
|
60
60
|
```mermaid
|
|
61
61
|
erDiagram
|
|
62
|
+
ProjectTraceRetentionPolicy ||--o{ Project : applied_to
|
|
63
|
+
ProjectTraceRetentionPolicy {
|
|
64
|
+
int id PK
|
|
65
|
+
string name
|
|
66
|
+
string cron_expression
|
|
67
|
+
json rule
|
|
68
|
+
}
|
|
69
|
+
|
|
62
70
|
Project ||--o{ Trace : has
|
|
71
|
+
Project ||--o| ProjectTraceRetentionPolicy : has
|
|
72
|
+
Project ||--o{ ProjectAnnotationConfig : has
|
|
63
73
|
Project {
|
|
64
74
|
int id PK
|
|
65
75
|
string name
|
|
@@ -68,6 +78,7 @@ erDiagram
|
|
|
68
78
|
string gradient_end_color
|
|
69
79
|
datetime created_at
|
|
70
80
|
datetime updated_at
|
|
81
|
+
int trace_retention_policy_id FK
|
|
71
82
|
}
|
|
72
83
|
|
|
73
84
|
ProjectSession ||--o{ Trace : has
|
|
@@ -127,6 +138,9 @@ erDiagram
|
|
|
127
138
|
string annotator_kind
|
|
128
139
|
datetime created_at
|
|
129
140
|
datetime updated_at
|
|
141
|
+
string identifier
|
|
142
|
+
string source
|
|
143
|
+
int user_id FK
|
|
130
144
|
}
|
|
131
145
|
|
|
132
146
|
SpanAnnotation {
|
|
@@ -140,6 +154,9 @@ erDiagram
|
|
|
140
154
|
string annotator_kind
|
|
141
155
|
datetime created_at
|
|
142
156
|
datetime updated_at
|
|
157
|
+
string identifier
|
|
158
|
+
string source
|
|
159
|
+
int user_id FK
|
|
143
160
|
}
|
|
144
161
|
|
|
145
162
|
TraceAnnotation {
|
|
@@ -153,6 +170,9 @@ erDiagram
|
|
|
153
170
|
string annotator_kind
|
|
154
171
|
datetime created_at
|
|
155
172
|
datetime updated_at
|
|
173
|
+
string identifier
|
|
174
|
+
string source
|
|
175
|
+
int user_id FK
|
|
156
176
|
}
|
|
157
177
|
|
|
158
178
|
Dataset ||--o{ DatasetVersion : has
|
|
@@ -244,6 +264,9 @@ erDiagram
|
|
|
244
264
|
User ||--o{ PasswordResetToken : has
|
|
245
265
|
User ||--o{ PromptVersion : has
|
|
246
266
|
User ||--o{ PromptVersionTag : has
|
|
267
|
+
User ||--o{ SpanAnnotation : has
|
|
268
|
+
User ||--o{ DocumentAnnotation : has
|
|
269
|
+
User ||--o{ TraceAnnotation : has
|
|
247
270
|
User {
|
|
248
271
|
int id PK
|
|
249
272
|
int user_role_id FK
|
|
@@ -255,6 +278,7 @@ erDiagram
|
|
|
255
278
|
boolean reset_password
|
|
256
279
|
string oauth2_client_id
|
|
257
280
|
string oauth2_user_id
|
|
281
|
+
string auth_method
|
|
258
282
|
datetime created_at
|
|
259
283
|
datetime updated_at
|
|
260
284
|
}
|
|
@@ -350,4 +374,17 @@ erDiagram
|
|
|
350
374
|
int prompt_version_id FK
|
|
351
375
|
int user_id FK
|
|
352
376
|
}
|
|
377
|
+
|
|
378
|
+
AnnotationConfig ||--o{ ProjectAnnotationConfig : used_in
|
|
379
|
+
AnnotationConfig {
|
|
380
|
+
int id PK
|
|
381
|
+
string name
|
|
382
|
+
json config
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
ProjectAnnotationConfig {
|
|
386
|
+
int id PK
|
|
387
|
+
int project_id FK
|
|
388
|
+
int annotation_config_id FK
|
|
389
|
+
}
|
|
353
390
|
```
|
|
@@ -4,9 +4,8 @@ from enum import Enum
|
|
|
4
4
|
from sqlalchemy.orm import InstrumentedAttribute
|
|
5
5
|
|
|
6
6
|
from phoenix.db import models
|
|
7
|
-
from phoenix.db.models import AuthMethod
|
|
8
7
|
|
|
9
|
-
__all__ = ["
|
|
8
|
+
__all__ = ["UserRole", "COLUMN_ENUMS"]
|
|
10
9
|
|
|
11
10
|
|
|
12
11
|
class UserRole(Enum):
|
|
@@ -26,6 +26,7 @@ from phoenix.auth import (
|
|
|
26
26
|
from phoenix.config import (
|
|
27
27
|
get_env_admins,
|
|
28
28
|
get_env_default_admin_initial_password,
|
|
29
|
+
get_env_disable_basic_auth,
|
|
29
30
|
)
|
|
30
31
|
from phoenix.db import models
|
|
31
32
|
from phoenix.db.constants import DEFAULT_PROJECT_TRACE_RETENTION_POLICY_ID
|
|
@@ -111,7 +112,7 @@ async def _ensure_user_roles(db: DbSessionFactory) -> None:
|
|
|
111
112
|
if (system_role := UserRole.SYSTEM.value) not in existing_roles and (
|
|
112
113
|
system_role_id := role_ids.get(system_role)
|
|
113
114
|
) is not None:
|
|
114
|
-
system_user = models.
|
|
115
|
+
system_user = models.LocalUser(
|
|
115
116
|
user_role_id=system_role_id,
|
|
116
117
|
username=DEFAULT_SYSTEM_USERNAME,
|
|
117
118
|
email=DEFAULT_SYSTEM_EMAIL,
|
|
@@ -128,7 +129,7 @@ async def _ensure_user_roles(db: DbSessionFactory) -> None:
|
|
|
128
129
|
compute = partial(compute_password_hash, password=password, salt=salt)
|
|
129
130
|
loop = asyncio.get_running_loop()
|
|
130
131
|
hash_ = await loop.run_in_executor(None, compute)
|
|
131
|
-
admin_user = models.
|
|
132
|
+
admin_user = models.LocalUser(
|
|
132
133
|
user_role_id=admin_role_id,
|
|
133
134
|
username=DEFAULT_ADMIN_USERNAME,
|
|
134
135
|
email=DEFAULT_ADMIN_EMAIL,
|
|
@@ -168,6 +169,7 @@ async def _ensure_admins(
|
|
|
168
169
|
"""
|
|
169
170
|
if not (admins := get_env_admins()):
|
|
170
171
|
return
|
|
172
|
+
disable_basic_auth = get_env_disable_basic_auth()
|
|
171
173
|
async with db() as session:
|
|
172
174
|
existing_emails = set(
|
|
173
175
|
await session.scalars(
|
|
@@ -195,16 +197,23 @@ async def _ensure_admins(
|
|
|
195
197
|
select(models.UserRole.id).filter_by(name=UserRole.ADMIN.value)
|
|
196
198
|
)
|
|
197
199
|
assert admin_role_id is not None, "Admin role not found in database"
|
|
200
|
+
user: models.User
|
|
198
201
|
for email, username in admins.items():
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
202
|
+
if not disable_basic_auth:
|
|
203
|
+
user = models.LocalUser(
|
|
204
|
+
email=email,
|
|
205
|
+
username=username,
|
|
206
|
+
password_salt=secrets.token_bytes(DEFAULT_SECRET_LENGTH),
|
|
207
|
+
password_hash=secrets.token_bytes(DEFAULT_SECRET_LENGTH),
|
|
208
|
+
)
|
|
209
|
+
else:
|
|
210
|
+
user = models.OAuth2User(
|
|
211
|
+
email=email,
|
|
212
|
+
username=username,
|
|
213
|
+
)
|
|
214
|
+
user.user_role_id = admin_role_id
|
|
215
|
+
session.add(user)
|
|
216
|
+
await session.flush()
|
|
208
217
|
if email_sender is None:
|
|
209
218
|
return
|
|
210
219
|
for exc in await gather(
|