arize-phoenix 10.0.4__py3-none-any.whl → 12.28.1__py3-none-any.whl
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.
- {arize_phoenix-10.0.4.dist-info → arize_phoenix-12.28.1.dist-info}/METADATA +124 -72
- arize_phoenix-12.28.1.dist-info/RECORD +499 -0
- {arize_phoenix-10.0.4.dist-info → arize_phoenix-12.28.1.dist-info}/WHEEL +1 -1
- {arize_phoenix-10.0.4.dist-info → arize_phoenix-12.28.1.dist-info}/licenses/IP_NOTICE +1 -1
- phoenix/__generated__/__init__.py +0 -0
- phoenix/__generated__/classification_evaluator_configs/__init__.py +20 -0
- phoenix/__generated__/classification_evaluator_configs/_document_relevance_classification_evaluator_config.py +17 -0
- phoenix/__generated__/classification_evaluator_configs/_hallucination_classification_evaluator_config.py +17 -0
- phoenix/__generated__/classification_evaluator_configs/_models.py +18 -0
- phoenix/__generated__/classification_evaluator_configs/_tool_selection_classification_evaluator_config.py +17 -0
- phoenix/__init__.py +5 -4
- phoenix/auth.py +39 -2
- phoenix/config.py +1763 -91
- phoenix/datetime_utils.py +120 -2
- phoenix/db/README.md +595 -25
- phoenix/db/bulk_inserter.py +145 -103
- phoenix/db/engines.py +140 -33
- phoenix/db/enums.py +3 -12
- phoenix/db/facilitator.py +302 -35
- phoenix/db/helpers.py +1000 -65
- phoenix/db/iam_auth.py +64 -0
- phoenix/db/insertion/dataset.py +135 -2
- phoenix/db/insertion/document_annotation.py +9 -6
- phoenix/db/insertion/evaluation.py +2 -3
- phoenix/db/insertion/helpers.py +17 -2
- phoenix/db/insertion/session_annotation.py +176 -0
- phoenix/db/insertion/span.py +15 -11
- phoenix/db/insertion/span_annotation.py +3 -4
- phoenix/db/insertion/trace_annotation.py +3 -4
- phoenix/db/insertion/types.py +50 -20
- phoenix/db/migrations/versions/01a8342c9cdf_add_user_id_on_datasets.py +40 -0
- phoenix/db/migrations/versions/0df286449799_add_session_annotations_table.py +105 -0
- phoenix/db/migrations/versions/272b66ff50f8_drop_single_indices.py +119 -0
- phoenix/db/migrations/versions/58228d933c91_dataset_labels.py +67 -0
- phoenix/db/migrations/versions/699f655af132_experiment_tags.py +57 -0
- phoenix/db/migrations/versions/735d3d93c33e_add_composite_indices.py +41 -0
- phoenix/db/migrations/versions/a20694b15f82_cost.py +196 -0
- phoenix/db/migrations/versions/ab513d89518b_add_user_id_on_dataset_versions.py +40 -0
- phoenix/db/migrations/versions/d0690a79ea51_users_on_experiments.py +40 -0
- phoenix/db/migrations/versions/deb2c81c0bb2_dataset_splits.py +139 -0
- phoenix/db/migrations/versions/e76cbd66ffc3_add_experiments_dataset_examples.py +87 -0
- phoenix/db/models.py +669 -56
- phoenix/db/pg_config.py +10 -0
- phoenix/db/types/model_provider.py +4 -0
- phoenix/db/types/token_price_customization.py +29 -0
- phoenix/db/types/trace_retention.py +23 -15
- phoenix/experiments/evaluators/utils.py +3 -3
- phoenix/experiments/functions.py +160 -52
- phoenix/experiments/tracing.py +2 -2
- phoenix/experiments/types.py +1 -1
- phoenix/inferences/inferences.py +1 -2
- phoenix/server/api/auth.py +38 -7
- phoenix/server/api/auth_messages.py +46 -0
- phoenix/server/api/context.py +100 -4
- phoenix/server/api/dataloaders/__init__.py +79 -5
- phoenix/server/api/dataloaders/annotation_configs_by_project.py +31 -0
- phoenix/server/api/dataloaders/annotation_summaries.py +60 -8
- phoenix/server/api/dataloaders/average_experiment_repeated_run_group_latency.py +50 -0
- phoenix/server/api/dataloaders/average_experiment_run_latency.py +17 -24
- phoenix/server/api/dataloaders/cache/two_tier_cache.py +1 -2
- phoenix/server/api/dataloaders/dataset_dataset_splits.py +52 -0
- phoenix/server/api/dataloaders/dataset_example_revisions.py +0 -1
- phoenix/server/api/dataloaders/dataset_example_splits.py +40 -0
- phoenix/server/api/dataloaders/dataset_examples_and_versions_by_experiment_run.py +47 -0
- phoenix/server/api/dataloaders/dataset_labels.py +36 -0
- phoenix/server/api/dataloaders/document_evaluation_summaries.py +2 -2
- phoenix/server/api/dataloaders/document_evaluations.py +6 -9
- phoenix/server/api/dataloaders/experiment_annotation_summaries.py +88 -34
- phoenix/server/api/dataloaders/experiment_dataset_splits.py +43 -0
- phoenix/server/api/dataloaders/experiment_error_rates.py +21 -28
- phoenix/server/api/dataloaders/experiment_repeated_run_group_annotation_summaries.py +77 -0
- phoenix/server/api/dataloaders/experiment_repeated_run_groups.py +57 -0
- phoenix/server/api/dataloaders/experiment_runs_by_experiment_and_example.py +44 -0
- phoenix/server/api/dataloaders/last_used_times_by_generative_model_id.py +35 -0
- phoenix/server/api/dataloaders/latency_ms_quantile.py +40 -8
- phoenix/server/api/dataloaders/record_counts.py +37 -10
- phoenix/server/api/dataloaders/session_annotations_by_session.py +29 -0
- phoenix/server/api/dataloaders/span_cost_by_span.py +24 -0
- phoenix/server/api/dataloaders/span_cost_detail_summary_entries_by_generative_model.py +56 -0
- phoenix/server/api/dataloaders/span_cost_detail_summary_entries_by_project_session.py +57 -0
- phoenix/server/api/dataloaders/span_cost_detail_summary_entries_by_span.py +43 -0
- phoenix/server/api/dataloaders/span_cost_detail_summary_entries_by_trace.py +56 -0
- phoenix/server/api/dataloaders/span_cost_details_by_span_cost.py +27 -0
- phoenix/server/api/dataloaders/span_cost_summary_by_experiment.py +57 -0
- phoenix/server/api/dataloaders/span_cost_summary_by_experiment_repeated_run_group.py +64 -0
- phoenix/server/api/dataloaders/span_cost_summary_by_experiment_run.py +58 -0
- phoenix/server/api/dataloaders/span_cost_summary_by_generative_model.py +55 -0
- phoenix/server/api/dataloaders/span_cost_summary_by_project.py +152 -0
- phoenix/server/api/dataloaders/span_cost_summary_by_project_session.py +56 -0
- phoenix/server/api/dataloaders/span_cost_summary_by_trace.py +55 -0
- phoenix/server/api/dataloaders/span_costs.py +29 -0
- phoenix/server/api/dataloaders/table_fields.py +2 -2
- phoenix/server/api/dataloaders/token_prices_by_model.py +30 -0
- phoenix/server/api/dataloaders/trace_annotations_by_trace.py +27 -0
- phoenix/server/api/dataloaders/types.py +29 -0
- phoenix/server/api/exceptions.py +11 -1
- phoenix/server/api/helpers/dataset_helpers.py +5 -1
- phoenix/server/api/helpers/playground_clients.py +1243 -292
- phoenix/server/api/helpers/playground_registry.py +2 -2
- phoenix/server/api/helpers/playground_spans.py +8 -4
- phoenix/server/api/helpers/playground_users.py +26 -0
- phoenix/server/api/helpers/prompts/conversions/aws.py +83 -0
- phoenix/server/api/helpers/prompts/conversions/google.py +103 -0
- phoenix/server/api/helpers/prompts/models.py +205 -22
- phoenix/server/api/input_types/{SpanAnnotationFilter.py → AnnotationFilter.py} +22 -14
- phoenix/server/api/input_types/ChatCompletionInput.py +6 -2
- phoenix/server/api/input_types/CreateProjectInput.py +27 -0
- phoenix/server/api/input_types/CreateProjectSessionAnnotationInput.py +37 -0
- phoenix/server/api/input_types/DatasetFilter.py +17 -0
- phoenix/server/api/input_types/ExperimentRunSort.py +237 -0
- phoenix/server/api/input_types/GenerativeCredentialInput.py +9 -0
- phoenix/server/api/input_types/GenerativeModelInput.py +5 -0
- phoenix/server/api/input_types/ProjectSessionSort.py +161 -1
- phoenix/server/api/input_types/PromptFilter.py +14 -0
- phoenix/server/api/input_types/PromptVersionInput.py +52 -1
- phoenix/server/api/input_types/SpanSort.py +44 -7
- phoenix/server/api/input_types/TimeBinConfig.py +23 -0
- phoenix/server/api/input_types/UpdateAnnotationInput.py +34 -0
- phoenix/server/api/input_types/UserRoleInput.py +1 -0
- phoenix/server/api/mutations/__init__.py +10 -0
- phoenix/server/api/mutations/annotation_config_mutations.py +8 -8
- phoenix/server/api/mutations/api_key_mutations.py +19 -23
- phoenix/server/api/mutations/chat_mutations.py +154 -47
- phoenix/server/api/mutations/dataset_label_mutations.py +243 -0
- phoenix/server/api/mutations/dataset_mutations.py +21 -16
- phoenix/server/api/mutations/dataset_split_mutations.py +351 -0
- phoenix/server/api/mutations/experiment_mutations.py +2 -2
- phoenix/server/api/mutations/export_events_mutations.py +3 -3
- phoenix/server/api/mutations/model_mutations.py +210 -0
- phoenix/server/api/mutations/project_mutations.py +49 -10
- phoenix/server/api/mutations/project_session_annotations_mutations.py +158 -0
- phoenix/server/api/mutations/project_trace_retention_policy_mutations.py +8 -4
- phoenix/server/api/mutations/prompt_label_mutations.py +74 -65
- phoenix/server/api/mutations/prompt_mutations.py +65 -129
- phoenix/server/api/mutations/prompt_version_tag_mutations.py +11 -8
- phoenix/server/api/mutations/span_annotations_mutations.py +15 -10
- phoenix/server/api/mutations/trace_annotations_mutations.py +14 -10
- phoenix/server/api/mutations/trace_mutations.py +47 -3
- phoenix/server/api/mutations/user_mutations.py +66 -41
- phoenix/server/api/queries.py +768 -293
- phoenix/server/api/routers/__init__.py +2 -2
- phoenix/server/api/routers/auth.py +154 -88
- phoenix/server/api/routers/ldap.py +229 -0
- phoenix/server/api/routers/oauth2.py +369 -106
- phoenix/server/api/routers/v1/__init__.py +24 -4
- phoenix/server/api/routers/v1/annotation_configs.py +23 -31
- phoenix/server/api/routers/v1/annotations.py +481 -17
- phoenix/server/api/routers/v1/datasets.py +395 -81
- phoenix/server/api/routers/v1/documents.py +142 -0
- phoenix/server/api/routers/v1/evaluations.py +24 -31
- phoenix/server/api/routers/v1/experiment_evaluations.py +19 -8
- phoenix/server/api/routers/v1/experiment_runs.py +337 -59
- phoenix/server/api/routers/v1/experiments.py +479 -48
- phoenix/server/api/routers/v1/models.py +7 -0
- phoenix/server/api/routers/v1/projects.py +18 -49
- phoenix/server/api/routers/v1/prompts.py +54 -40
- phoenix/server/api/routers/v1/sessions.py +108 -0
- phoenix/server/api/routers/v1/spans.py +1091 -81
- phoenix/server/api/routers/v1/traces.py +132 -78
- phoenix/server/api/routers/v1/users.py +389 -0
- phoenix/server/api/routers/v1/utils.py +3 -7
- phoenix/server/api/subscriptions.py +305 -88
- phoenix/server/api/types/Annotation.py +90 -23
- phoenix/server/api/types/ApiKey.py +13 -17
- phoenix/server/api/types/AuthMethod.py +1 -0
- phoenix/server/api/types/ChatCompletionSubscriptionPayload.py +1 -0
- phoenix/server/api/types/CostBreakdown.py +12 -0
- phoenix/server/api/types/Dataset.py +226 -72
- phoenix/server/api/types/DatasetExample.py +88 -18
- phoenix/server/api/types/DatasetExperimentAnnotationSummary.py +10 -0
- phoenix/server/api/types/DatasetLabel.py +57 -0
- phoenix/server/api/types/DatasetSplit.py +98 -0
- phoenix/server/api/types/DatasetVersion.py +49 -4
- phoenix/server/api/types/DocumentAnnotation.py +212 -0
- phoenix/server/api/types/Experiment.py +264 -59
- phoenix/server/api/types/ExperimentComparison.py +5 -10
- phoenix/server/api/types/ExperimentRepeatedRunGroup.py +155 -0
- phoenix/server/api/types/ExperimentRepeatedRunGroupAnnotationSummary.py +9 -0
- phoenix/server/api/types/ExperimentRun.py +169 -65
- phoenix/server/api/types/ExperimentRunAnnotation.py +158 -39
- phoenix/server/api/types/GenerativeModel.py +245 -3
- phoenix/server/api/types/GenerativeProvider.py +70 -11
- phoenix/server/api/types/{Model.py → InferenceModel.py} +1 -1
- phoenix/server/api/types/ModelInterface.py +16 -0
- phoenix/server/api/types/PlaygroundModel.py +20 -0
- phoenix/server/api/types/Project.py +1278 -216
- phoenix/server/api/types/ProjectSession.py +188 -28
- phoenix/server/api/types/ProjectSessionAnnotation.py +187 -0
- phoenix/server/api/types/ProjectTraceRetentionPolicy.py +1 -1
- phoenix/server/api/types/Prompt.py +119 -39
- phoenix/server/api/types/PromptLabel.py +42 -25
- phoenix/server/api/types/PromptVersion.py +11 -8
- phoenix/server/api/types/PromptVersionTag.py +65 -25
- phoenix/server/api/types/ServerStatus.py +6 -0
- phoenix/server/api/types/Span.py +167 -123
- phoenix/server/api/types/SpanAnnotation.py +189 -42
- phoenix/server/api/types/SpanCostDetailSummaryEntry.py +10 -0
- phoenix/server/api/types/SpanCostSummary.py +10 -0
- phoenix/server/api/types/SystemApiKey.py +65 -1
- phoenix/server/api/types/TokenPrice.py +16 -0
- phoenix/server/api/types/TokenUsage.py +3 -3
- phoenix/server/api/types/Trace.py +223 -51
- phoenix/server/api/types/TraceAnnotation.py +149 -50
- phoenix/server/api/types/User.py +137 -32
- phoenix/server/api/types/UserApiKey.py +73 -26
- phoenix/server/api/types/node.py +10 -0
- phoenix/server/api/types/pagination.py +11 -2
- phoenix/server/app.py +290 -45
- phoenix/server/authorization.py +38 -3
- phoenix/server/bearer_auth.py +34 -24
- phoenix/server/cost_tracking/cost_details_calculator.py +196 -0
- phoenix/server/cost_tracking/cost_model_lookup.py +179 -0
- phoenix/server/cost_tracking/helpers.py +68 -0
- phoenix/server/cost_tracking/model_cost_manifest.json +3657 -830
- phoenix/server/cost_tracking/regex_specificity.py +397 -0
- phoenix/server/cost_tracking/token_cost_calculator.py +57 -0
- phoenix/server/daemons/__init__.py +0 -0
- phoenix/server/daemons/db_disk_usage_monitor.py +214 -0
- phoenix/server/daemons/generative_model_store.py +103 -0
- phoenix/server/daemons/span_cost_calculator.py +99 -0
- phoenix/server/dml_event.py +17 -0
- phoenix/server/dml_event_handler.py +5 -0
- phoenix/server/email/sender.py +56 -3
- phoenix/server/email/templates/db_disk_usage_notification.html +19 -0
- phoenix/server/email/types.py +11 -0
- phoenix/server/experiments/__init__.py +0 -0
- phoenix/server/experiments/utils.py +14 -0
- phoenix/server/grpc_server.py +11 -11
- phoenix/server/jwt_store.py +17 -15
- phoenix/server/ldap.py +1449 -0
- phoenix/server/main.py +26 -10
- phoenix/server/oauth2.py +330 -12
- phoenix/server/prometheus.py +66 -6
- phoenix/server/rate_limiters.py +4 -9
- phoenix/server/retention.py +33 -20
- phoenix/server/session_filters.py +49 -0
- phoenix/server/static/.vite/manifest.json +55 -51
- phoenix/server/static/assets/components-BreFUQQa.js +6702 -0
- phoenix/server/static/assets/{index-E0M82BdE.js → index-CTQoemZv.js} +140 -56
- phoenix/server/static/assets/pages-DBE5iYM3.js +9524 -0
- phoenix/server/static/assets/vendor-BGzfc4EU.css +1 -0
- phoenix/server/static/assets/vendor-DCE4v-Ot.js +920 -0
- phoenix/server/static/assets/vendor-codemirror-D5f205eT.js +25 -0
- phoenix/server/static/assets/vendor-recharts-V9cwpXsm.js +37 -0
- phoenix/server/static/assets/vendor-shiki-Do--csgv.js +5 -0
- phoenix/server/static/assets/vendor-three-CmB8bl_y.js +3840 -0
- phoenix/server/templates/index.html +40 -6
- phoenix/server/thread_server.py +1 -2
- phoenix/server/types.py +14 -4
- phoenix/server/utils.py +74 -0
- phoenix/session/client.py +56 -3
- phoenix/session/data_extractor.py +5 -0
- phoenix/session/evaluation.py +14 -5
- phoenix/session/session.py +45 -9
- phoenix/settings.py +5 -0
- phoenix/trace/attributes.py +80 -13
- phoenix/trace/dsl/helpers.py +90 -1
- phoenix/trace/dsl/query.py +8 -6
- phoenix/trace/projects.py +5 -0
- phoenix/utilities/template_formatters.py +1 -1
- phoenix/version.py +1 -1
- arize_phoenix-10.0.4.dist-info/RECORD +0 -405
- phoenix/server/api/types/Evaluation.py +0 -39
- phoenix/server/cost_tracking/cost_lookup.py +0 -255
- phoenix/server/static/assets/components-DULKeDfL.js +0 -4365
- phoenix/server/static/assets/pages-Cl0A-0U2.js +0 -7430
- phoenix/server/static/assets/vendor-WIZid84E.css +0 -1
- phoenix/server/static/assets/vendor-arizeai-Dy-0mSNw.js +0 -649
- phoenix/server/static/assets/vendor-codemirror-DBtifKNr.js +0 -33
- phoenix/server/static/assets/vendor-oB4u9zuV.js +0 -905
- phoenix/server/static/assets/vendor-recharts-D-T4KPz2.js +0 -59
- phoenix/server/static/assets/vendor-shiki-BMn4O_9F.js +0 -5
- phoenix/server/static/assets/vendor-three-C5WAXd5r.js +0 -2998
- phoenix/utilities/deprecation.py +0 -31
- {arize_phoenix-10.0.4.dist-info → arize_phoenix-12.28.1.dist-info}/entry_points.txt +0 -0
- {arize_phoenix-10.0.4.dist-info → arize_phoenix-12.28.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# This file is generated. Do not edit by hand.
|
|
2
|
+
|
|
3
|
+
from typing import Literal
|
|
4
|
+
|
|
5
|
+
from pydantic import BaseModel
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class PromptMessage(BaseModel):
|
|
9
|
+
role: Literal["user"]
|
|
10
|
+
content: str
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class ClassificationEvaluatorConfig(BaseModel):
|
|
14
|
+
name: str
|
|
15
|
+
description: str
|
|
16
|
+
optimization_direction: Literal["minimize", "maximize"]
|
|
17
|
+
messages: list[PromptMessage]
|
|
18
|
+
choices: dict[str, float]
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# This file is generated. Do not edit by hand.
|
|
2
|
+
# ruff: noqa: E501
|
|
3
|
+
|
|
4
|
+
from ._models import ClassificationEvaluatorConfig, PromptMessage
|
|
5
|
+
|
|
6
|
+
TOOL_SELECTION_CLASSIFICATION_EVALUATOR_CONFIG = ClassificationEvaluatorConfig(
|
|
7
|
+
name="tool_selection",
|
|
8
|
+
description="For determining if the correct tool was selected for a given context. Requires conversation context, a list of available tools, and the LLM's tool selections.",
|
|
9
|
+
optimization_direction="maximize",
|
|
10
|
+
messages=[
|
|
11
|
+
PromptMessage(
|
|
12
|
+
role="user",
|
|
13
|
+
content="You are an impartial judge evaluating an LLM's tool-calling behavior, specifically whether the LLM selected the most appropriate tool or tools for the task.\nYour task: Determine whether the LLM's tool selection was correct or incorrect based on: - The conversation context - The available tools - The LLM's tool invocation(s)\nCriteria Return \"correct\" only when ALL of the following are true: - The LLM chose the best available tool for the user query OR correctly avoided tools if none were needed. - The tool name exists in the available tools list. - The tool is allowed and safe to call. - The LLM selected the correct number of tools for the task.\nReturn \"incorrect\" if ANY of the following are true: - The LLM used a hallucinated or nonexistent tool. - The LLM selected a tool when none was needed. - The LLM did not use a tool when one was required. - The LLM chose a suboptimal or irrelevant tool. - The LLM selected an unsafe or not-permitted tool. - The tool name does not appear in the available tools list.\nBefore providing your final judgment, explain your reasoning and consider: - What does the input context require? - Can this be answered without tools, or is a tool necessary? - If a tool was selected, does it exist in the available tools? - Does the selected tool's description match the user's needs? - Is the selection safe and appropriate? - Is there a better tool available that should have been chosen instead?\n<data> <context> {{input}} </context>\n<available_tools> {{available_tools}} </available_tools>\n<tool_selection> {{tool_selection}} </tool_selection> </data>\nGiven the above data, is the tool selection correct or incorrect?",
|
|
14
|
+
)
|
|
15
|
+
],
|
|
16
|
+
choices={"correct": 1.0, "incorrect": 0.0},
|
|
17
|
+
)
|
phoenix/__init__.py
CHANGED
|
@@ -84,11 +84,12 @@ class PhoenixTraceOpenAILoader(Loader):
|
|
|
84
84
|
"The legacy `phoenix.trace.openai` instrumentor module has been removed.\n"
|
|
85
85
|
"Please use OpenInference to instrument the OpenAI SDK. Additionally, the "
|
|
86
86
|
"`phoenix.otel` module can be used to quickly configure OpenTelemetry:\n\n"
|
|
87
|
-
"https://
|
|
87
|
+
"https://arize.com/docs/phoenix/tracing/integrations-tracing/openai"
|
|
88
88
|
"\n\n"
|
|
89
89
|
"Example usage:\n\n"
|
|
90
|
+
"pip install openinference-instrumentation-openai\n\n"
|
|
90
91
|
"```python\n"
|
|
91
|
-
"from phoenix.otel register\n"
|
|
92
|
+
"from phoenix.otel import register\n"
|
|
92
93
|
"from openinference.instrumentation.openai import OpenAIInstrumentor\n\n"
|
|
93
94
|
"tracer_provider = register()\n"
|
|
94
95
|
"OpenAIInstrumentor().instrument(tracer_provider=tracer_provider)\n"
|
|
@@ -108,7 +109,7 @@ class PhoenixTraceLangchainLoader(Loader):
|
|
|
108
109
|
"The legacy `phoenix.trace.langchain` instrumentor module has been removed.\n"
|
|
109
110
|
"Please use OpenInference to instrument the LangChain SDK. Additionally, the "
|
|
110
111
|
"`phoenix.otel` module can be used to quickly configure OpenTelemetry:\n\n"
|
|
111
|
-
"https://
|
|
112
|
+
"https://arize.com/docs/phoenix/tracing/integrations-tracing/langchain"
|
|
112
113
|
"\n\n"
|
|
113
114
|
"Example usage:\n\n"
|
|
114
115
|
"```python\n"
|
|
@@ -129,7 +130,7 @@ class PhoenixTraceLlamaIndexLoader(Loader):
|
|
|
129
130
|
"The legacy `phoenix.trace.llama_index` instrumentor module has been removed.\n"
|
|
130
131
|
"Please use OpenInference to instrument the LlamaIndex SDK. Additionally, the "
|
|
131
132
|
"`phoenix.otel` module can be used to quickly configure OpenTelemetry:\n\n"
|
|
132
|
-
"https://
|
|
133
|
+
"https://arize.com/docs/phoenix/tracing/integrations-tracing/llamaindex"
|
|
133
134
|
"\n\n"
|
|
134
135
|
"Example usage:\n\n"
|
|
135
136
|
"```python\n"
|
phoenix/auth.py
CHANGED
|
@@ -2,7 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import re
|
|
4
4
|
from dataclasses import dataclass
|
|
5
|
-
from datetime import datetime, timedelta
|
|
5
|
+
from datetime import datetime, timedelta, timezone
|
|
6
6
|
from enum import Enum, auto
|
|
7
7
|
from hashlib import pbkdf2_hmac
|
|
8
8
|
from typing import Any, Literal, Optional, Protocol
|
|
@@ -47,6 +47,18 @@ def is_valid_password(*, password: Secret, salt: bytes, password_hash: bytes) ->
|
|
|
47
47
|
return password_hash == compute_password_hash(password=password, salt=salt)
|
|
48
48
|
|
|
49
49
|
|
|
50
|
+
def sanitize_email(email: str) -> str:
|
|
51
|
+
"""
|
|
52
|
+
Sanitizes an email address by trimming whitespace and converting to lowercase.
|
|
53
|
+
|
|
54
|
+
Args:
|
|
55
|
+
email (str): the email address to sanitize
|
|
56
|
+
Returns:
|
|
57
|
+
str: the sanitized email address
|
|
58
|
+
"""
|
|
59
|
+
return email.strip().lower()
|
|
60
|
+
|
|
61
|
+
|
|
50
62
|
def validate_email_format(email: str) -> None:
|
|
51
63
|
"""
|
|
52
64
|
Checks that the email has a valid format.
|
|
@@ -117,6 +129,18 @@ def set_oauth2_nonce_cookie(
|
|
|
117
129
|
)
|
|
118
130
|
|
|
119
131
|
|
|
132
|
+
def set_oauth2_code_verifier_cookie(
|
|
133
|
+
*, response: ResponseType, code_verifier: str, max_age: timedelta
|
|
134
|
+
) -> ResponseType:
|
|
135
|
+
return _set_cookie(
|
|
136
|
+
response=response,
|
|
137
|
+
cookie_name=PHOENIX_OAUTH2_CODE_VERIFIER_COOKIE_NAME,
|
|
138
|
+
cookie_max_age=max_age,
|
|
139
|
+
samesite="lax",
|
|
140
|
+
value=code_verifier,
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
|
|
120
144
|
def _set_cookie(
|
|
121
145
|
*,
|
|
122
146
|
response: ResponseType,
|
|
@@ -157,6 +181,11 @@ def delete_oauth2_nonce_cookie(response: ResponseType) -> ResponseType:
|
|
|
157
181
|
return response
|
|
158
182
|
|
|
159
183
|
|
|
184
|
+
def delete_oauth2_code_verifier_cookie(response: ResponseType) -> ResponseType:
|
|
185
|
+
response.delete_cookie(key=PHOENIX_OAUTH2_CODE_VERIFIER_COOKIE_NAME)
|
|
186
|
+
return response
|
|
187
|
+
|
|
188
|
+
|
|
160
189
|
@dataclass(frozen=True)
|
|
161
190
|
class _PasswordRequirements:
|
|
162
191
|
"""
|
|
@@ -258,6 +287,8 @@ PHOENIX_OAUTH2_STATE_COOKIE_NAME = "phoenix-oauth2-state"
|
|
|
258
287
|
"""The name of the cookie that stores the state used for the OAuth2 authorization code flow."""
|
|
259
288
|
PHOENIX_OAUTH2_NONCE_COOKIE_NAME = "phoenix-oauth2-nonce"
|
|
260
289
|
"""The name of the cookie that stores the nonce used for the OAuth2 authorization code flow."""
|
|
290
|
+
PHOENIX_OAUTH2_CODE_VERIFIER_COOKIE_NAME = "phoenix-oauth2-code-verifier"
|
|
291
|
+
"""The name of the cookie that stores the PKCE code verifier for OAuth2."""
|
|
261
292
|
DEFAULT_OAUTH2_LOGIN_EXPIRY_MINUTES = 15
|
|
262
293
|
"""
|
|
263
294
|
The default amount of time in minutes that can elapse between the initial
|
|
@@ -300,7 +331,13 @@ class ClaimSet:
|
|
|
300
331
|
|
|
301
332
|
@property
|
|
302
333
|
def status(self) -> ClaimSetStatus:
|
|
303
|
-
|
|
334
|
+
# Per JWT RFC 7519 Section 4.1.4, the expiration time identifies the time
|
|
335
|
+
# "on or after which" the JWT must not be accepted. Use <= for inclusive check.
|
|
336
|
+
# https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.4
|
|
337
|
+
if (
|
|
338
|
+
self.expiration_time
|
|
339
|
+
and self.expiration_time.timestamp() <= datetime.now(timezone.utc).timestamp()
|
|
340
|
+
):
|
|
304
341
|
return ClaimSetStatus.EXPIRED
|
|
305
342
|
if self.token_id is not None and self.subject is not None:
|
|
306
343
|
return ClaimSetStatus.VALID
|