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
phoenix/server/api/auth.py
CHANGED
|
@@ -3,8 +3,10 @@ from typing import Any
|
|
|
3
3
|
|
|
4
4
|
from strawberry import Info
|
|
5
5
|
from strawberry.permission import BasePermission
|
|
6
|
+
from typing_extensions import override
|
|
6
7
|
|
|
7
|
-
from phoenix.
|
|
8
|
+
from phoenix.config import get_env_support_email
|
|
9
|
+
from phoenix.server.api.exceptions import InsufficientStorage, Unauthorized
|
|
8
10
|
from phoenix.server.bearer_auth import PhoenixUser
|
|
9
11
|
|
|
10
12
|
|
|
@@ -20,16 +22,45 @@ class IsNotReadOnly(Authorization):
|
|
|
20
22
|
return not info.context.read_only
|
|
21
23
|
|
|
22
24
|
|
|
23
|
-
class
|
|
24
|
-
""
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
class IsNotViewer(Authorization):
|
|
26
|
+
message = "Viewers cannot perform this action"
|
|
27
|
+
|
|
28
|
+
def has_permission(self, source: Any, info: Info, **kwargs: Any) -> bool:
|
|
29
|
+
if not info.context.auth_enabled:
|
|
30
|
+
return True
|
|
31
|
+
return isinstance((user := info.context.user), PhoenixUser) and not user.is_viewer
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class IsLocked(BasePermission):
|
|
27
35
|
"""
|
|
36
|
+
Permission class that restricts data-modifying operations when insufficient storage.
|
|
28
37
|
|
|
29
|
-
|
|
38
|
+
When database storage capacity is exceeded, this permission blocks mutations and
|
|
39
|
+
subscriptions that create or update data, while allowing queries and delete mutations
|
|
40
|
+
to continue. This prevents database overflow while maintaining read access and the
|
|
41
|
+
ability to free up space through deletions.
|
|
30
42
|
|
|
43
|
+
Raises:
|
|
44
|
+
InsufficientStorage: When storage capacity is exceeded and data operations
|
|
45
|
+
are temporarily disabled. The error includes guidance for resolution
|
|
46
|
+
and support contact information if configured.
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
@override
|
|
50
|
+
def on_unauthorized(self) -> None:
|
|
51
|
+
"""Create user-friendly error message when storage operations are blocked."""
|
|
52
|
+
message = (
|
|
53
|
+
"Database operations are disabled due to insufficient storage. "
|
|
54
|
+
"Please delete old data or increase storage."
|
|
55
|
+
)
|
|
56
|
+
if support_email := get_env_support_email():
|
|
57
|
+
message += f" Need help? Contact us at {support_email}"
|
|
58
|
+
raise InsufficientStorage(message)
|
|
59
|
+
|
|
60
|
+
@override
|
|
31
61
|
def has_permission(self, source: Any, info: Info, **kwargs: Any) -> bool:
|
|
32
|
-
|
|
62
|
+
"""Check if database operations are allowed based on storage capacity and lock status."""
|
|
63
|
+
return not (info.context.db.should_not_insert_or_update or info.context.locked)
|
|
33
64
|
|
|
34
65
|
|
|
35
66
|
MSG_ADMIN_ONLY = "Only admin can perform this action"
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# ruff: noqa: E501
|
|
2
|
+
"""
|
|
3
|
+
Authentication error and success message codes.
|
|
4
|
+
|
|
5
|
+
These codes are used in authentication flows to safely communicate status
|
|
6
|
+
to users via query parameters. Using codes instead of raw messages prevents
|
|
7
|
+
social engineering and phishing attacks.
|
|
8
|
+
|
|
9
|
+
The messages are passed to the frontend via window.Config to ensure a single
|
|
10
|
+
source of truth between backend and frontend.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from types import MappingProxyType
|
|
14
|
+
from typing import Literal, Mapping, get_args
|
|
15
|
+
|
|
16
|
+
# Error code type - used for type hints in redirect functions
|
|
17
|
+
AuthErrorCode = Literal[
|
|
18
|
+
"unknown_idp",
|
|
19
|
+
"auth_failed",
|
|
20
|
+
"invalid_state",
|
|
21
|
+
"unsafe_return_url",
|
|
22
|
+
"oauth_error",
|
|
23
|
+
"no_oidc_support",
|
|
24
|
+
"missing_email_scope",
|
|
25
|
+
"email_in_use",
|
|
26
|
+
"sign_in_not_allowed",
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
# Error messages - passed to frontend via window.Config.authErrorMessages
|
|
30
|
+
# Backend generates these codes when redirecting users after OAuth errors
|
|
31
|
+
AUTH_ERROR_MESSAGES: Mapping[AuthErrorCode, str] = MappingProxyType(
|
|
32
|
+
{
|
|
33
|
+
"unknown_idp": "Unknown identity provider.",
|
|
34
|
+
"auth_failed": "Authentication failed. Please contact your administrator.",
|
|
35
|
+
"invalid_state": "Invalid authentication state. Please try again.",
|
|
36
|
+
"unsafe_return_url": "Invalid return URL. Please try again.",
|
|
37
|
+
"oauth_error": "Authentication failed. Please try again.",
|
|
38
|
+
"no_oidc_support": "Your identity provider does not appear to support OpenID Connect. Please contact your administrator.",
|
|
39
|
+
"missing_email_scope": "Please ensure your identity provider is configured to use the 'email' scope.",
|
|
40
|
+
"email_in_use": "An account with this email already exists.",
|
|
41
|
+
"sign_in_not_allowed": "Sign in is not allowed. Please contact your administrator.",
|
|
42
|
+
}
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
# Runtime assertion to ensure AUTH_ERROR_MESSAGES keys match AuthErrorCode Literal values
|
|
46
|
+
assert set(AUTH_ERROR_MESSAGES.keys()) == set(get_args(AuthErrorCode))
|
phoenix/server/api/context.py
CHANGED
|
@@ -15,19 +15,29 @@ from phoenix.auth import (
|
|
|
15
15
|
from phoenix.core.model_schema import Model
|
|
16
16
|
from phoenix.db import models
|
|
17
17
|
from phoenix.server.api.dataloaders import (
|
|
18
|
+
AnnotationConfigsByProjectDataLoader,
|
|
18
19
|
AnnotationSummaryDataLoader,
|
|
20
|
+
AverageExperimentRepeatedRunGroupLatencyDataLoader,
|
|
19
21
|
AverageExperimentRunLatencyDataLoader,
|
|
20
22
|
CacheForDataLoaders,
|
|
23
|
+
DatasetDatasetSplitsDataLoader,
|
|
21
24
|
DatasetExampleRevisionsDataLoader,
|
|
25
|
+
DatasetExamplesAndVersionsByExperimentRunDataLoader,
|
|
22
26
|
DatasetExampleSpansDataLoader,
|
|
27
|
+
DatasetExampleSplitsDataLoader,
|
|
23
28
|
DocumentEvaluationsDataLoader,
|
|
24
29
|
DocumentEvaluationSummaryDataLoader,
|
|
25
30
|
DocumentRetrievalMetricsDataLoader,
|
|
26
31
|
ExperimentAnnotationSummaryDataLoader,
|
|
32
|
+
ExperimentDatasetSplitsDataLoader,
|
|
27
33
|
ExperimentErrorRatesDataLoader,
|
|
34
|
+
ExperimentRepeatedRunGroupAnnotationSummariesDataLoader,
|
|
35
|
+
ExperimentRepeatedRunGroupsDataLoader,
|
|
28
36
|
ExperimentRunAnnotations,
|
|
29
37
|
ExperimentRunCountsDataLoader,
|
|
38
|
+
ExperimentRunsByExperimentAndExampleDataLoader,
|
|
30
39
|
ExperimentSequenceNumberDataLoader,
|
|
40
|
+
LastUsedTimesByGenerativeModelIdDataLoader,
|
|
31
41
|
LatencyMsQuantileDataLoader,
|
|
32
42
|
MinStartOrMaxEndTimeDataLoader,
|
|
33
43
|
NumChildSpansDataLoader,
|
|
@@ -36,6 +46,7 @@ from phoenix.server.api.dataloaders import (
|
|
|
36
46
|
ProjectIdsByTraceRetentionPolicyIdDataLoader,
|
|
37
47
|
PromptVersionSequenceNumberDataLoader,
|
|
38
48
|
RecordCountDataLoader,
|
|
49
|
+
SessionAnnotationsBySessionDataLoader,
|
|
39
50
|
SessionIODataLoader,
|
|
40
51
|
SessionNumTracesDataLoader,
|
|
41
52
|
SessionNumTracesWithErrorDataLoader,
|
|
@@ -43,18 +54,35 @@ from phoenix.server.api.dataloaders import (
|
|
|
43
54
|
SessionTraceLatencyMsQuantileDataLoader,
|
|
44
55
|
SpanAnnotationsDataLoader,
|
|
45
56
|
SpanByIdDataLoader,
|
|
57
|
+
SpanCostBySpanDataLoader,
|
|
58
|
+
SpanCostDetailsBySpanCostDataLoader,
|
|
59
|
+
SpanCostDetailSummaryEntriesByGenerativeModelDataLoader,
|
|
60
|
+
SpanCostDetailSummaryEntriesByProjectSessionDataLoader,
|
|
61
|
+
SpanCostDetailSummaryEntriesBySpanDataLoader,
|
|
62
|
+
SpanCostDetailSummaryEntriesByTraceDataLoader,
|
|
63
|
+
SpanCostSummaryByExperimentDataLoader,
|
|
64
|
+
SpanCostSummaryByExperimentRepeatedRunGroupDataLoader,
|
|
65
|
+
SpanCostSummaryByExperimentRunDataLoader,
|
|
66
|
+
SpanCostSummaryByGenerativeModelDataLoader,
|
|
67
|
+
SpanCostSummaryByProjectDataLoader,
|
|
68
|
+
SpanCostSummaryByProjectSessionDataLoader,
|
|
69
|
+
SpanCostSummaryByTraceDataLoader,
|
|
46
70
|
SpanDatasetExamplesDataLoader,
|
|
47
71
|
SpanDescendantsDataLoader,
|
|
48
72
|
SpanProjectsDataLoader,
|
|
49
73
|
TableFieldsDataLoader,
|
|
50
74
|
TokenCountDataLoader,
|
|
75
|
+
TokenPricesByModelDataLoader,
|
|
76
|
+
TraceAnnotationsByTraceDataLoader,
|
|
51
77
|
TraceByTraceIdsDataLoader,
|
|
52
78
|
TraceRetentionPolicyIdByProjectIdDataLoader,
|
|
53
79
|
TraceRootSpansDataLoader,
|
|
54
80
|
UserRolesDataLoader,
|
|
55
81
|
UsersDataLoader,
|
|
56
82
|
)
|
|
83
|
+
from phoenix.server.api.dataloaders.dataset_labels import DatasetLabelsDataLoader
|
|
57
84
|
from phoenix.server.bearer_auth import PhoenixUser
|
|
85
|
+
from phoenix.server.daemons.span_cost_calculator import SpanCostCalculator
|
|
58
86
|
from phoenix.server.dml_event import DmlEvent
|
|
59
87
|
from phoenix.server.email.types import EmailSender
|
|
60
88
|
from phoenix.server.types import (
|
|
@@ -68,47 +96,107 @@ from phoenix.server.types import (
|
|
|
68
96
|
|
|
69
97
|
@dataclass
|
|
70
98
|
class DataLoaders:
|
|
99
|
+
annotation_configs_by_project: AnnotationConfigsByProjectDataLoader
|
|
100
|
+
annotation_summaries: AnnotationSummaryDataLoader
|
|
101
|
+
average_experiment_repeated_run_group_latency: (
|
|
102
|
+
AverageExperimentRepeatedRunGroupLatencyDataLoader
|
|
103
|
+
)
|
|
71
104
|
average_experiment_run_latency: AverageExperimentRunLatencyDataLoader
|
|
105
|
+
dataset_example_fields: TableFieldsDataLoader
|
|
72
106
|
dataset_example_revisions: DatasetExampleRevisionsDataLoader
|
|
73
107
|
dataset_example_spans: DatasetExampleSpansDataLoader
|
|
108
|
+
dataset_labels: DatasetLabelsDataLoader
|
|
109
|
+
dataset_label_fields: TableFieldsDataLoader
|
|
110
|
+
dataset_dataset_splits: DatasetDatasetSplitsDataLoader
|
|
111
|
+
dataset_examples_and_versions_by_experiment_run: (
|
|
112
|
+
DatasetExamplesAndVersionsByExperimentRunDataLoader
|
|
113
|
+
)
|
|
114
|
+
dataset_example_splits: DatasetExampleSplitsDataLoader
|
|
115
|
+
dataset_fields: TableFieldsDataLoader
|
|
116
|
+
dataset_split_fields: TableFieldsDataLoader
|
|
117
|
+
dataset_version_fields: TableFieldsDataLoader
|
|
118
|
+
document_annotation_fields: TableFieldsDataLoader
|
|
74
119
|
document_evaluation_summaries: DocumentEvaluationSummaryDataLoader
|
|
75
120
|
document_evaluations: DocumentEvaluationsDataLoader
|
|
76
121
|
document_retrieval_metrics: DocumentRetrievalMetricsDataLoader
|
|
77
|
-
annotation_summaries: AnnotationSummaryDataLoader
|
|
78
122
|
experiment_annotation_summaries: ExperimentAnnotationSummaryDataLoader
|
|
123
|
+
experiment_dataset_splits: ExperimentDatasetSplitsDataLoader
|
|
79
124
|
experiment_error_rates: ExperimentErrorRatesDataLoader
|
|
125
|
+
experiment_fields: TableFieldsDataLoader
|
|
126
|
+
experiment_repeated_run_group_annotation_summaries: (
|
|
127
|
+
ExperimentRepeatedRunGroupAnnotationSummariesDataLoader
|
|
128
|
+
)
|
|
129
|
+
experiment_repeated_run_groups: ExperimentRepeatedRunGroupsDataLoader
|
|
130
|
+
experiment_run_annotation_fields: TableFieldsDataLoader
|
|
80
131
|
experiment_run_annotations: ExperimentRunAnnotations
|
|
81
132
|
experiment_run_counts: ExperimentRunCountsDataLoader
|
|
133
|
+
experiment_run_fields: TableFieldsDataLoader
|
|
134
|
+
experiment_runs_by_experiment_and_example: ExperimentRunsByExperimentAndExampleDataLoader
|
|
82
135
|
experiment_sequence_number: ExperimentSequenceNumberDataLoader
|
|
136
|
+
generative_model_fields: TableFieldsDataLoader
|
|
137
|
+
last_used_times_by_generative_model_id: LastUsedTimesByGenerativeModelIdDataLoader
|
|
83
138
|
latency_ms_quantile: LatencyMsQuantileDataLoader
|
|
84
139
|
min_start_or_max_end_times: MinStartOrMaxEndTimeDataLoader
|
|
85
140
|
num_child_spans: NumChildSpansDataLoader
|
|
86
141
|
num_spans_per_trace: NumSpansPerTraceDataLoader
|
|
142
|
+
project_by_name: ProjectByNameDataLoader
|
|
87
143
|
project_fields: TableFieldsDataLoader
|
|
144
|
+
project_trace_retention_policy_fields: TableFieldsDataLoader
|
|
88
145
|
projects_by_trace_retention_policy_id: ProjectIdsByTraceRetentionPolicyIdDataLoader
|
|
146
|
+
prompt_fields: TableFieldsDataLoader
|
|
147
|
+
prompt_label_fields: TableFieldsDataLoader
|
|
89
148
|
prompt_version_sequence_number: PromptVersionSequenceNumberDataLoader
|
|
149
|
+
prompt_version_tag_fields: TableFieldsDataLoader
|
|
150
|
+
project_session_annotation_fields: TableFieldsDataLoader
|
|
151
|
+
project_session_fields: TableFieldsDataLoader
|
|
90
152
|
record_counts: RecordCountDataLoader
|
|
153
|
+
session_annotations_by_session: SessionAnnotationsBySessionDataLoader
|
|
91
154
|
session_first_inputs: SessionIODataLoader
|
|
92
155
|
session_last_outputs: SessionIODataLoader
|
|
93
156
|
session_num_traces: SessionNumTracesDataLoader
|
|
94
157
|
session_num_traces_with_error: SessionNumTracesWithErrorDataLoader
|
|
95
158
|
session_token_usages: SessionTokenUsagesDataLoader
|
|
96
159
|
session_trace_latency_ms_quantile: SessionTraceLatencyMsQuantileDataLoader
|
|
160
|
+
span_annotation_fields: TableFieldsDataLoader
|
|
97
161
|
span_annotations: SpanAnnotationsDataLoader
|
|
98
162
|
span_by_id: SpanByIdDataLoader
|
|
163
|
+
span_cost_by_span: SpanCostBySpanDataLoader
|
|
164
|
+
span_cost_detail_fields: TableFieldsDataLoader
|
|
165
|
+
span_cost_detail_summary_entries_by_generative_model: (
|
|
166
|
+
SpanCostDetailSummaryEntriesByGenerativeModelDataLoader
|
|
167
|
+
)
|
|
168
|
+
span_cost_detail_summary_entries_by_project_session: (
|
|
169
|
+
SpanCostDetailSummaryEntriesByProjectSessionDataLoader
|
|
170
|
+
)
|
|
171
|
+
span_cost_detail_summary_entries_by_span: SpanCostDetailSummaryEntriesBySpanDataLoader
|
|
172
|
+
span_cost_detail_summary_entries_by_trace: SpanCostDetailSummaryEntriesByTraceDataLoader
|
|
173
|
+
span_cost_details_by_span_cost: SpanCostDetailsBySpanCostDataLoader
|
|
174
|
+
span_cost_fields: TableFieldsDataLoader
|
|
175
|
+
span_cost_summary_by_experiment: SpanCostSummaryByExperimentDataLoader
|
|
176
|
+
span_cost_summary_by_experiment_repeated_run_group: (
|
|
177
|
+
SpanCostSummaryByExperimentRepeatedRunGroupDataLoader
|
|
178
|
+
)
|
|
179
|
+
span_cost_summary_by_experiment_run: SpanCostSummaryByExperimentRunDataLoader
|
|
180
|
+
span_cost_summary_by_generative_model: SpanCostSummaryByGenerativeModelDataLoader
|
|
181
|
+
span_cost_summary_by_project: SpanCostSummaryByProjectDataLoader
|
|
182
|
+
span_cost_summary_by_project_session: SpanCostSummaryByProjectSessionDataLoader
|
|
183
|
+
span_cost_summary_by_trace: SpanCostSummaryByTraceDataLoader
|
|
99
184
|
span_dataset_examples: SpanDatasetExamplesDataLoader
|
|
100
185
|
span_descendants: SpanDescendantsDataLoader
|
|
101
186
|
span_fields: TableFieldsDataLoader
|
|
102
187
|
span_projects: SpanProjectsDataLoader
|
|
103
188
|
token_counts: TokenCountDataLoader
|
|
189
|
+
token_prices_by_model: TokenPricesByModelDataLoader
|
|
190
|
+
trace_annotation_fields: TableFieldsDataLoader
|
|
191
|
+
trace_annotations_by_trace: TraceAnnotationsByTraceDataLoader
|
|
104
192
|
trace_by_trace_ids: TraceByTraceIdsDataLoader
|
|
105
193
|
trace_fields: TableFieldsDataLoader
|
|
106
194
|
trace_retention_policy_id_by_project_id: TraceRetentionPolicyIdByProjectIdDataLoader
|
|
107
|
-
project_trace_retention_policy_fields: TableFieldsDataLoader
|
|
108
195
|
trace_root_spans: TraceRootSpansDataLoader
|
|
109
|
-
project_by_name: ProjectByNameDataLoader
|
|
110
|
-
users: UsersDataLoader
|
|
111
196
|
user_roles: UserRolesDataLoader
|
|
197
|
+
user_api_key_fields: TableFieldsDataLoader
|
|
198
|
+
user_fields: TableFieldsDataLoader
|
|
199
|
+
users: UsersDataLoader
|
|
112
200
|
|
|
113
201
|
|
|
114
202
|
class _NoOp:
|
|
@@ -123,6 +211,7 @@ class Context(BaseContext):
|
|
|
123
211
|
cache_for_dataloaders: Optional[CacheForDataLoaders]
|
|
124
212
|
model: Model
|
|
125
213
|
export_path: Path
|
|
214
|
+
span_cost_calculator: SpanCostCalculator
|
|
126
215
|
last_updated_at: CanGetLastUpdatedAt = _NoOp()
|
|
127
216
|
event_queue: CanPutItem[DmlEvent] = _NoOp()
|
|
128
217
|
corpus: Optional[Model] = None
|
|
@@ -181,3 +270,10 @@ class Context(BaseContext):
|
|
|
181
270
|
@cached_property
|
|
182
271
|
def user(self) -> PhoenixUser:
|
|
183
272
|
return cast(PhoenixUser, self.get_request().user)
|
|
273
|
+
|
|
274
|
+
@cached_property
|
|
275
|
+
def user_id(self) -> Optional[int]:
|
|
276
|
+
try:
|
|
277
|
+
return int(self.user.identity)
|
|
278
|
+
except Exception:
|
|
279
|
+
return None
|
|
@@ -1,9 +1,23 @@
|
|
|
1
1
|
from dataclasses import dataclass, field
|
|
2
2
|
|
|
3
|
+
from phoenix.server.api.dataloaders.span_cost_detail_summary_entries_by_project_session import (
|
|
4
|
+
SpanCostDetailSummaryEntriesByProjectSessionDataLoader,
|
|
5
|
+
)
|
|
6
|
+
|
|
7
|
+
from .annotation_configs_by_project import AnnotationConfigsByProjectDataLoader
|
|
3
8
|
from .annotation_summaries import AnnotationSummaryCache, AnnotationSummaryDataLoader
|
|
9
|
+
from .average_experiment_repeated_run_group_latency import (
|
|
10
|
+
AverageExperimentRepeatedRunGroupLatencyDataLoader,
|
|
11
|
+
)
|
|
4
12
|
from .average_experiment_run_latency import AverageExperimentRunLatencyDataLoader
|
|
13
|
+
from .dataset_dataset_splits import DatasetDatasetSplitsDataLoader
|
|
5
14
|
from .dataset_example_revisions import DatasetExampleRevisionsDataLoader
|
|
6
15
|
from .dataset_example_spans import DatasetExampleSpansDataLoader
|
|
16
|
+
from .dataset_example_splits import DatasetExampleSplitsDataLoader
|
|
17
|
+
from .dataset_examples_and_versions_by_experiment_run import (
|
|
18
|
+
DatasetExamplesAndVersionsByExperimentRunDataLoader,
|
|
19
|
+
)
|
|
20
|
+
from .dataset_labels import DatasetLabelsDataLoader
|
|
7
21
|
from .document_evaluation_summaries import (
|
|
8
22
|
DocumentEvaluationSummaryCache,
|
|
9
23
|
DocumentEvaluationSummaryDataLoader,
|
|
@@ -11,10 +25,19 @@ from .document_evaluation_summaries import (
|
|
|
11
25
|
from .document_evaluations import DocumentEvaluationsDataLoader
|
|
12
26
|
from .document_retrieval_metrics import DocumentRetrievalMetricsDataLoader
|
|
13
27
|
from .experiment_annotation_summaries import ExperimentAnnotationSummaryDataLoader
|
|
28
|
+
from .experiment_dataset_splits import ExperimentDatasetSplitsDataLoader
|
|
14
29
|
from .experiment_error_rates import ExperimentErrorRatesDataLoader
|
|
30
|
+
from .experiment_repeated_run_group_annotation_summaries import (
|
|
31
|
+
ExperimentRepeatedRunGroupAnnotationSummariesDataLoader,
|
|
32
|
+
)
|
|
33
|
+
from .experiment_repeated_run_groups import ExperimentRepeatedRunGroupsDataLoader
|
|
15
34
|
from .experiment_run_annotations import ExperimentRunAnnotations
|
|
16
35
|
from .experiment_run_counts import ExperimentRunCountsDataLoader
|
|
36
|
+
from .experiment_runs_by_experiment_and_example import (
|
|
37
|
+
ExperimentRunsByExperimentAndExampleDataLoader,
|
|
38
|
+
)
|
|
17
39
|
from .experiment_sequence_number import ExperimentSequenceNumberDataLoader
|
|
40
|
+
from .last_used_times_by_generative_model_id import LastUsedTimesByGenerativeModelIdDataLoader
|
|
18
41
|
from .latency_ms_quantile import LatencyMsQuantileCache, LatencyMsQuantileDataLoader
|
|
19
42
|
from .min_start_or_max_end_times import MinStartOrMaxEndTimeCache, MinStartOrMaxEndTimeDataLoader
|
|
20
43
|
from .num_child_spans import NumChildSpansDataLoader
|
|
@@ -23,6 +46,7 @@ from .project_by_name import ProjectByNameDataLoader
|
|
|
23
46
|
from .project_ids_by_trace_retention_policy_id import ProjectIdsByTraceRetentionPolicyIdDataLoader
|
|
24
47
|
from .prompt_version_sequence_number import PromptVersionSequenceNumberDataLoader
|
|
25
48
|
from .record_counts import RecordCountCache, RecordCountDataLoader
|
|
49
|
+
from .session_annotations_by_session import SessionAnnotationsBySessionDataLoader
|
|
26
50
|
from .session_io import SessionIODataLoader
|
|
27
51
|
from .session_num_traces import SessionNumTracesDataLoader
|
|
28
52
|
from .session_num_traces_with_error import SessionNumTracesWithErrorDataLoader
|
|
@@ -30,11 +54,30 @@ from .session_token_usages import SessionTokenUsagesDataLoader
|
|
|
30
54
|
from .session_trace_latency_ms_quantile import SessionTraceLatencyMsQuantileDataLoader
|
|
31
55
|
from .span_annotations import SpanAnnotationsDataLoader
|
|
32
56
|
from .span_by_id import SpanByIdDataLoader
|
|
57
|
+
from .span_cost_by_span import SpanCostBySpanDataLoader
|
|
58
|
+
from .span_cost_detail_summary_entries_by_generative_model import (
|
|
59
|
+
SpanCostDetailSummaryEntriesByGenerativeModelDataLoader,
|
|
60
|
+
)
|
|
61
|
+
from .span_cost_detail_summary_entries_by_span import SpanCostDetailSummaryEntriesBySpanDataLoader
|
|
62
|
+
from .span_cost_detail_summary_entries_by_trace import SpanCostDetailSummaryEntriesByTraceDataLoader
|
|
63
|
+
from .span_cost_details_by_span_cost import SpanCostDetailsBySpanCostDataLoader
|
|
64
|
+
from .span_cost_summary_by_experiment import SpanCostSummaryByExperimentDataLoader
|
|
65
|
+
from .span_cost_summary_by_experiment_repeated_run_group import (
|
|
66
|
+
SpanCostSummaryByExperimentRepeatedRunGroupDataLoader,
|
|
67
|
+
)
|
|
68
|
+
from .span_cost_summary_by_experiment_run import SpanCostSummaryByExperimentRunDataLoader
|
|
69
|
+
from .span_cost_summary_by_generative_model import SpanCostSummaryByGenerativeModelDataLoader
|
|
70
|
+
from .span_cost_summary_by_project import SpanCostSummaryByProjectDataLoader, SpanCostSummaryCache
|
|
71
|
+
from .span_cost_summary_by_project_session import SpanCostSummaryByProjectSessionDataLoader
|
|
72
|
+
from .span_cost_summary_by_trace import SpanCostSummaryByTraceDataLoader
|
|
73
|
+
from .span_costs import SpanCostsDataLoader
|
|
33
74
|
from .span_dataset_examples import SpanDatasetExamplesDataLoader
|
|
34
75
|
from .span_descendants import SpanDescendantsDataLoader
|
|
35
76
|
from .span_projects import SpanProjectsDataLoader
|
|
36
77
|
from .table_fields import TableFieldsDataLoader
|
|
37
78
|
from .token_counts import TokenCountCache, TokenCountDataLoader
|
|
79
|
+
from .token_prices_by_model import TokenPricesByModelDataLoader
|
|
80
|
+
from .trace_annotations_by_trace import TraceAnnotationsByTraceDataLoader
|
|
38
81
|
from .trace_by_trace_ids import TraceByTraceIdsDataLoader
|
|
39
82
|
from .trace_retention_policy_id_by_project_id import TraceRetentionPolicyIdByProjectIdDataLoader
|
|
40
83
|
from .trace_root_spans import TraceRootSpansDataLoader
|
|
@@ -42,44 +85,72 @@ from .user_roles import UserRolesDataLoader
|
|
|
42
85
|
from .users import UsersDataLoader
|
|
43
86
|
|
|
44
87
|
__all__ = [
|
|
45
|
-
"
|
|
88
|
+
"AnnotationConfigsByProjectDataLoader",
|
|
89
|
+
"AnnotationSummaryDataLoader",
|
|
90
|
+
"AverageExperimentRepeatedRunGroupLatencyDataLoader",
|
|
46
91
|
"AverageExperimentRunLatencyDataLoader",
|
|
92
|
+
"CacheForDataLoaders",
|
|
93
|
+
"DatasetDatasetSplitsDataLoader",
|
|
47
94
|
"DatasetExampleRevisionsDataLoader",
|
|
48
95
|
"DatasetExampleSpansDataLoader",
|
|
96
|
+
"DatasetExamplesAndVersionsByExperimentRunDataLoader",
|
|
97
|
+
"DatasetExampleSplitsDataLoader",
|
|
98
|
+
"DatasetLabelsDataLoader",
|
|
99
|
+
"ExperimentDatasetSplitsDataLoader",
|
|
49
100
|
"DocumentEvaluationSummaryDataLoader",
|
|
50
101
|
"DocumentEvaluationsDataLoader",
|
|
51
102
|
"DocumentRetrievalMetricsDataLoader",
|
|
52
|
-
"AnnotationSummaryDataLoader",
|
|
53
103
|
"ExperimentAnnotationSummaryDataLoader",
|
|
54
104
|
"ExperimentErrorRatesDataLoader",
|
|
105
|
+
"ExperimentRepeatedRunGroupsDataLoader",
|
|
106
|
+
"ExperimentRepeatedRunGroupAnnotationSummariesDataLoader",
|
|
55
107
|
"ExperimentRunAnnotations",
|
|
56
108
|
"ExperimentRunCountsDataLoader",
|
|
109
|
+
"ExperimentRunsByExperimentAndExampleDataLoader",
|
|
57
110
|
"ExperimentSequenceNumberDataLoader",
|
|
111
|
+
"LastUsedTimesByGenerativeModelIdDataLoader",
|
|
58
112
|
"LatencyMsQuantileDataLoader",
|
|
59
113
|
"MinStartOrMaxEndTimeDataLoader",
|
|
60
114
|
"NumChildSpansDataLoader",
|
|
61
115
|
"NumSpansPerTraceDataLoader",
|
|
116
|
+
"ProjectByNameDataLoader",
|
|
62
117
|
"ProjectIdsByTraceRetentionPolicyIdDataLoader",
|
|
63
118
|
"PromptVersionSequenceNumberDataLoader",
|
|
64
119
|
"RecordCountDataLoader",
|
|
120
|
+
"SessionAnnotationsBySessionDataLoader",
|
|
65
121
|
"SessionIODataLoader",
|
|
66
122
|
"SessionNumTracesDataLoader",
|
|
67
123
|
"SessionNumTracesWithErrorDataLoader",
|
|
68
124
|
"SessionTokenUsagesDataLoader",
|
|
69
125
|
"SessionTraceLatencyMsQuantileDataLoader",
|
|
126
|
+
"SpanAnnotationsDataLoader",
|
|
70
127
|
"SpanByIdDataLoader",
|
|
128
|
+
"SpanCostBySpanDataLoader",
|
|
129
|
+
"SpanCostDetailSummaryEntriesByGenerativeModelDataLoader",
|
|
130
|
+
"SpanCostDetailSummaryEntriesByProjectSessionDataLoader",
|
|
131
|
+
"SpanCostDetailSummaryEntriesBySpanDataLoader",
|
|
132
|
+
"SpanCostDetailSummaryEntriesByTraceDataLoader",
|
|
133
|
+
"SpanCostDetailsBySpanCostDataLoader",
|
|
134
|
+
"SpanCostSummaryByExperimentDataLoader",
|
|
135
|
+
"SpanCostSummaryByExperimentRepeatedRunGroupDataLoader",
|
|
136
|
+
"SpanCostSummaryByExperimentRunDataLoader",
|
|
137
|
+
"SpanCostSummaryByGenerativeModelDataLoader",
|
|
138
|
+
"SpanCostSummaryByProjectDataLoader",
|
|
139
|
+
"SpanCostSummaryByProjectSessionDataLoader",
|
|
140
|
+
"SpanCostSummaryByTraceDataLoader",
|
|
141
|
+
"SpanCostsDataLoader",
|
|
71
142
|
"SpanDatasetExamplesDataLoader",
|
|
72
143
|
"SpanDescendantsDataLoader",
|
|
73
144
|
"SpanProjectsDataLoader",
|
|
74
145
|
"TableFieldsDataLoader",
|
|
75
146
|
"TokenCountDataLoader",
|
|
147
|
+
"TokenPricesByModelDataLoader",
|
|
148
|
+
"TraceAnnotationsByTraceDataLoader",
|
|
76
149
|
"TraceByTraceIdsDataLoader",
|
|
77
150
|
"TraceRetentionPolicyIdByProjectIdDataLoader",
|
|
78
151
|
"TraceRootSpansDataLoader",
|
|
79
|
-
"ProjectByNameDataLoader",
|
|
80
|
-
"SpanAnnotationsDataLoader",
|
|
81
|
-
"UsersDataLoader",
|
|
82
152
|
"UserRolesDataLoader",
|
|
153
|
+
"UsersDataLoader",
|
|
83
154
|
]
|
|
84
155
|
|
|
85
156
|
|
|
@@ -103,3 +174,6 @@ class CacheForDataLoaders:
|
|
|
103
174
|
token_count: TokenCountCache = field(
|
|
104
175
|
default_factory=TokenCountCache,
|
|
105
176
|
)
|
|
177
|
+
token_cost: SpanCostSummaryCache = field(
|
|
178
|
+
default_factory=SpanCostSummaryCache,
|
|
179
|
+
)
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
from collections import defaultdict
|
|
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
|
+
ProjectId: TypeAlias = int
|
|
11
|
+
Key: TypeAlias = ProjectId
|
|
12
|
+
Result: TypeAlias = tuple[models.AnnotationConfig, ...]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class AnnotationConfigsByProjectDataLoader(DataLoader[Key, Result]):
|
|
16
|
+
def __init__(self, db: DbSessionFactory) -> None:
|
|
17
|
+
super().__init__(load_fn=self._load_fn)
|
|
18
|
+
self._db = db
|
|
19
|
+
|
|
20
|
+
async def _load_fn(self, keys: list[Key]) -> list[Result]:
|
|
21
|
+
stmt = (
|
|
22
|
+
select(models.ProjectAnnotationConfig.project_id, models.AnnotationConfig)
|
|
23
|
+
.join_from(models.ProjectAnnotationConfig, models.AnnotationConfig)
|
|
24
|
+
.where(models.ProjectAnnotationConfig.project_id.in_(keys))
|
|
25
|
+
)
|
|
26
|
+
results: defaultdict[Key, list[models.AnnotationConfig]] = defaultdict(list)
|
|
27
|
+
async with self._db() as session:
|
|
28
|
+
data = await session.stream(stmt)
|
|
29
|
+
async for id_, config in data:
|
|
30
|
+
results[id_].append(config)
|
|
31
|
+
return [tuple(results[k]) for k in keys]
|
|
@@ -13,6 +13,7 @@ from phoenix.db import models
|
|
|
13
13
|
from phoenix.server.api.dataloaders.cache import TwoTierCache
|
|
14
14
|
from phoenix.server.api.input_types.TimeRange import TimeRange
|
|
15
15
|
from phoenix.server.api.types.AnnotationSummary import AnnotationSummary
|
|
16
|
+
from phoenix.server.session_filters import get_filtered_session_rowids_subquery
|
|
16
17
|
from phoenix.server.types import DbSessionFactory
|
|
17
18
|
from phoenix.trace.dsl import SpanFilter
|
|
18
19
|
|
|
@@ -20,27 +21,41 @@ Kind: TypeAlias = Literal["span", "trace"]
|
|
|
20
21
|
ProjectRowId: TypeAlias = int
|
|
21
22
|
TimeInterval: TypeAlias = tuple[Optional[datetime], Optional[datetime]]
|
|
22
23
|
FilterCondition: TypeAlias = Optional[str]
|
|
24
|
+
SessionFilterCondition: TypeAlias = Optional[str]
|
|
23
25
|
AnnotationName: TypeAlias = str
|
|
24
26
|
|
|
25
|
-
Segment: TypeAlias = tuple[
|
|
27
|
+
Segment: TypeAlias = tuple[
|
|
28
|
+
Kind,
|
|
29
|
+
ProjectRowId,
|
|
30
|
+
TimeInterval,
|
|
31
|
+
FilterCondition,
|
|
32
|
+
SessionFilterCondition,
|
|
33
|
+
]
|
|
26
34
|
Param: TypeAlias = AnnotationName
|
|
27
35
|
|
|
28
|
-
Key: TypeAlias = tuple[
|
|
36
|
+
Key: TypeAlias = tuple[
|
|
37
|
+
Kind,
|
|
38
|
+
ProjectRowId,
|
|
39
|
+
Optional[TimeRange],
|
|
40
|
+
FilterCondition,
|
|
41
|
+
SessionFilterCondition,
|
|
42
|
+
AnnotationName,
|
|
43
|
+
]
|
|
29
44
|
Result: TypeAlias = Optional[AnnotationSummary]
|
|
30
45
|
ResultPosition: TypeAlias = int
|
|
31
46
|
DEFAULT_VALUE: Result = None
|
|
32
47
|
|
|
33
48
|
|
|
34
49
|
def _cache_key_fn(key: Key) -> tuple[Segment, Param]:
|
|
35
|
-
kind, project_rowid, time_range, filter_condition, eval_name = key
|
|
50
|
+
kind, project_rowid, time_range, filter_condition, session_filter_condition, eval_name = key
|
|
36
51
|
interval = (
|
|
37
52
|
(time_range.start, time_range.end) if isinstance(time_range, TimeRange) else (None, None)
|
|
38
53
|
)
|
|
39
|
-
return (kind, project_rowid, interval, filter_condition), eval_name
|
|
54
|
+
return (kind, project_rowid, interval, filter_condition, session_filter_condition), eval_name
|
|
40
55
|
|
|
41
56
|
|
|
42
57
|
_Section: TypeAlias = tuple[ProjectRowId, AnnotationName, Kind]
|
|
43
|
-
_SubKey: TypeAlias = tuple[TimeInterval, FilterCondition]
|
|
58
|
+
_SubKey: TypeAlias = tuple[TimeInterval, FilterCondition, SessionFilterCondition]
|
|
44
59
|
|
|
45
60
|
|
|
46
61
|
class AnnotationSummaryCache(
|
|
@@ -61,8 +76,21 @@ class AnnotationSummaryCache(
|
|
|
61
76
|
del self._cache[section]
|
|
62
77
|
|
|
63
78
|
def _cache_key(self, key: Key) -> tuple[_Section, _SubKey]:
|
|
64
|
-
(
|
|
65
|
-
|
|
79
|
+
(
|
|
80
|
+
(
|
|
81
|
+
kind,
|
|
82
|
+
project_rowid,
|
|
83
|
+
interval,
|
|
84
|
+
filter_condition,
|
|
85
|
+
session_filter_condition,
|
|
86
|
+
),
|
|
87
|
+
annotation_name,
|
|
88
|
+
) = _cache_key_fn(key)
|
|
89
|
+
return (project_rowid, annotation_name, kind), (
|
|
90
|
+
interval,
|
|
91
|
+
filter_condition,
|
|
92
|
+
session_filter_condition,
|
|
93
|
+
)
|
|
66
94
|
|
|
67
95
|
|
|
68
96
|
class AnnotationSummaryDataLoader(DataLoader[Key, Result]):
|
|
@@ -102,7 +130,9 @@ def _get_stmt(
|
|
|
102
130
|
segment: Segment,
|
|
103
131
|
*annotation_names: Param,
|
|
104
132
|
) -> Select[Any]:
|
|
105
|
-
kind, project_rowid, (start_time, end_time), filter_condition =
|
|
133
|
+
kind, project_rowid, (start_time, end_time), filter_condition, session_filter_condition = (
|
|
134
|
+
segment
|
|
135
|
+
)
|
|
106
136
|
|
|
107
137
|
annotation_model: Union[Type[models.SpanAnnotation], Type[models.TraceAnnotation]]
|
|
108
138
|
entity_model: Union[Type[models.Span], Type[models.Trace]]
|
|
@@ -144,6 +174,19 @@ def _get_stmt(
|
|
|
144
174
|
entity_count_query = entity_count_query.where(
|
|
145
175
|
cast(Type[models.Trace], entity_model).project_rowid == project_rowid
|
|
146
176
|
)
|
|
177
|
+
else:
|
|
178
|
+
assert_never(kind)
|
|
179
|
+
|
|
180
|
+
if session_filter_condition:
|
|
181
|
+
filtered_session_rowids = get_filtered_session_rowids_subquery(
|
|
182
|
+
session_filter_condition=session_filter_condition,
|
|
183
|
+
project_rowids=[project_rowid],
|
|
184
|
+
start_time=start_time,
|
|
185
|
+
end_time=end_time,
|
|
186
|
+
)
|
|
187
|
+
entity_count_query = entity_count_query.where(
|
|
188
|
+
models.Trace.project_session_rowid.in_(filtered_session_rowids)
|
|
189
|
+
)
|
|
147
190
|
|
|
148
191
|
entity_count_query = entity_count_query.where(
|
|
149
192
|
or_(score_column.is_not(None), label_column.is_not(None))
|
|
@@ -186,6 +229,15 @@ def _get_stmt(
|
|
|
186
229
|
else:
|
|
187
230
|
assert_never(kind)
|
|
188
231
|
|
|
232
|
+
if session_filter_condition:
|
|
233
|
+
filtered_session_rowids = get_filtered_session_rowids_subquery(
|
|
234
|
+
session_filter_condition=session_filter_condition,
|
|
235
|
+
project_rowids=[project_rowid],
|
|
236
|
+
start_time=start_time,
|
|
237
|
+
end_time=end_time,
|
|
238
|
+
)
|
|
239
|
+
base_stmt = base_stmt.where(models.Trace.project_session_rowid.in_(filtered_session_rowids))
|
|
240
|
+
|
|
189
241
|
base_stmt = base_stmt.where(or_(score_column.is_not(None), label_column.is_not(None)))
|
|
190
242
|
base_stmt = base_stmt.where(name_column.in_(annotation_names))
|
|
191
243
|
|