arize-phoenix 3.16.1__py3-none-any.whl → 7.7.0__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.
Potentially problematic release.
This version of arize-phoenix might be problematic. Click here for more details.
- arize_phoenix-7.7.0.dist-info/METADATA +261 -0
- arize_phoenix-7.7.0.dist-info/RECORD +345 -0
- {arize_phoenix-3.16.1.dist-info → arize_phoenix-7.7.0.dist-info}/WHEEL +1 -1
- arize_phoenix-7.7.0.dist-info/entry_points.txt +3 -0
- phoenix/__init__.py +86 -14
- phoenix/auth.py +309 -0
- phoenix/config.py +675 -45
- phoenix/core/model.py +32 -30
- phoenix/core/model_schema.py +102 -109
- phoenix/core/model_schema_adapter.py +48 -45
- phoenix/datetime_utils.py +24 -3
- phoenix/db/README.md +54 -0
- phoenix/db/__init__.py +4 -0
- phoenix/db/alembic.ini +85 -0
- phoenix/db/bulk_inserter.py +294 -0
- phoenix/db/engines.py +208 -0
- phoenix/db/enums.py +20 -0
- phoenix/db/facilitator.py +113 -0
- phoenix/db/helpers.py +159 -0
- phoenix/db/insertion/constants.py +2 -0
- phoenix/db/insertion/dataset.py +227 -0
- phoenix/db/insertion/document_annotation.py +171 -0
- phoenix/db/insertion/evaluation.py +191 -0
- phoenix/db/insertion/helpers.py +98 -0
- phoenix/db/insertion/span.py +193 -0
- phoenix/db/insertion/span_annotation.py +158 -0
- phoenix/db/insertion/trace_annotation.py +158 -0
- phoenix/db/insertion/types.py +256 -0
- phoenix/db/migrate.py +86 -0
- phoenix/db/migrations/data_migration_scripts/populate_project_sessions.py +199 -0
- phoenix/db/migrations/env.py +114 -0
- phoenix/db/migrations/script.py.mako +26 -0
- phoenix/db/migrations/versions/10460e46d750_datasets.py +317 -0
- phoenix/db/migrations/versions/3be8647b87d8_add_token_columns_to_spans_table.py +126 -0
- phoenix/db/migrations/versions/4ded9e43755f_create_project_sessions_table.py +66 -0
- phoenix/db/migrations/versions/cd164e83824f_users_and_tokens.py +157 -0
- phoenix/db/migrations/versions/cf03bd6bae1d_init.py +280 -0
- phoenix/db/models.py +807 -0
- phoenix/exceptions.py +5 -1
- phoenix/experiments/__init__.py +6 -0
- phoenix/experiments/evaluators/__init__.py +29 -0
- phoenix/experiments/evaluators/base.py +158 -0
- phoenix/experiments/evaluators/code_evaluators.py +184 -0
- phoenix/experiments/evaluators/llm_evaluators.py +473 -0
- phoenix/experiments/evaluators/utils.py +236 -0
- phoenix/experiments/functions.py +772 -0
- phoenix/experiments/tracing.py +86 -0
- phoenix/experiments/types.py +726 -0
- phoenix/experiments/utils.py +25 -0
- phoenix/inferences/__init__.py +0 -0
- phoenix/{datasets → inferences}/errors.py +6 -5
- phoenix/{datasets → inferences}/fixtures.py +49 -42
- phoenix/{datasets/dataset.py → inferences/inferences.py} +121 -105
- phoenix/{datasets → inferences}/schema.py +11 -11
- phoenix/{datasets → inferences}/validation.py +13 -14
- phoenix/logging/__init__.py +3 -0
- phoenix/logging/_config.py +90 -0
- phoenix/logging/_filter.py +6 -0
- phoenix/logging/_formatter.py +69 -0
- phoenix/metrics/__init__.py +5 -4
- phoenix/metrics/binning.py +4 -3
- phoenix/metrics/metrics.py +2 -1
- phoenix/metrics/mixins.py +7 -6
- phoenix/metrics/retrieval_metrics.py +2 -1
- phoenix/metrics/timeseries.py +5 -4
- phoenix/metrics/wrappers.py +9 -3
- phoenix/pointcloud/clustering.py +5 -5
- phoenix/pointcloud/pointcloud.py +7 -5
- phoenix/pointcloud/projectors.py +5 -6
- phoenix/pointcloud/umap_parameters.py +53 -52
- phoenix/server/api/README.md +28 -0
- phoenix/server/api/auth.py +44 -0
- phoenix/server/api/context.py +152 -9
- phoenix/server/api/dataloaders/__init__.py +91 -0
- phoenix/server/api/dataloaders/annotation_summaries.py +139 -0
- phoenix/server/api/dataloaders/average_experiment_run_latency.py +54 -0
- phoenix/server/api/dataloaders/cache/__init__.py +3 -0
- phoenix/server/api/dataloaders/cache/two_tier_cache.py +68 -0
- phoenix/server/api/dataloaders/dataset_example_revisions.py +131 -0
- phoenix/server/api/dataloaders/dataset_example_spans.py +38 -0
- phoenix/server/api/dataloaders/document_evaluation_summaries.py +144 -0
- phoenix/server/api/dataloaders/document_evaluations.py +31 -0
- phoenix/server/api/dataloaders/document_retrieval_metrics.py +89 -0
- phoenix/server/api/dataloaders/experiment_annotation_summaries.py +79 -0
- phoenix/server/api/dataloaders/experiment_error_rates.py +58 -0
- phoenix/server/api/dataloaders/experiment_run_annotations.py +36 -0
- phoenix/server/api/dataloaders/experiment_run_counts.py +49 -0
- phoenix/server/api/dataloaders/experiment_sequence_number.py +44 -0
- phoenix/server/api/dataloaders/latency_ms_quantile.py +188 -0
- phoenix/server/api/dataloaders/min_start_or_max_end_times.py +85 -0
- phoenix/server/api/dataloaders/project_by_name.py +31 -0
- phoenix/server/api/dataloaders/record_counts.py +116 -0
- phoenix/server/api/dataloaders/session_io.py +79 -0
- phoenix/server/api/dataloaders/session_num_traces.py +30 -0
- phoenix/server/api/dataloaders/session_num_traces_with_error.py +32 -0
- phoenix/server/api/dataloaders/session_token_usages.py +41 -0
- phoenix/server/api/dataloaders/session_trace_latency_ms_quantile.py +55 -0
- phoenix/server/api/dataloaders/span_annotations.py +26 -0
- phoenix/server/api/dataloaders/span_dataset_examples.py +31 -0
- phoenix/server/api/dataloaders/span_descendants.py +57 -0
- phoenix/server/api/dataloaders/span_projects.py +33 -0
- phoenix/server/api/dataloaders/token_counts.py +124 -0
- phoenix/server/api/dataloaders/trace_by_trace_ids.py +25 -0
- phoenix/server/api/dataloaders/trace_root_spans.py +32 -0
- phoenix/server/api/dataloaders/user_roles.py +30 -0
- phoenix/server/api/dataloaders/users.py +33 -0
- phoenix/server/api/exceptions.py +48 -0
- phoenix/server/api/helpers/__init__.py +12 -0
- phoenix/server/api/helpers/dataset_helpers.py +217 -0
- phoenix/server/api/helpers/experiment_run_filters.py +763 -0
- phoenix/server/api/helpers/playground_clients.py +948 -0
- phoenix/server/api/helpers/playground_registry.py +70 -0
- phoenix/server/api/helpers/playground_spans.py +455 -0
- phoenix/server/api/input_types/AddExamplesToDatasetInput.py +16 -0
- phoenix/server/api/input_types/AddSpansToDatasetInput.py +14 -0
- phoenix/server/api/input_types/ChatCompletionInput.py +38 -0
- phoenix/server/api/input_types/ChatCompletionMessageInput.py +24 -0
- phoenix/server/api/input_types/ClearProjectInput.py +15 -0
- phoenix/server/api/input_types/ClusterInput.py +2 -2
- phoenix/server/api/input_types/CreateDatasetInput.py +12 -0
- phoenix/server/api/input_types/CreateSpanAnnotationInput.py +18 -0
- phoenix/server/api/input_types/CreateTraceAnnotationInput.py +18 -0
- phoenix/server/api/input_types/DataQualityMetricInput.py +5 -2
- phoenix/server/api/input_types/DatasetExampleInput.py +14 -0
- phoenix/server/api/input_types/DatasetSort.py +17 -0
- phoenix/server/api/input_types/DatasetVersionSort.py +16 -0
- phoenix/server/api/input_types/DeleteAnnotationsInput.py +7 -0
- phoenix/server/api/input_types/DeleteDatasetExamplesInput.py +13 -0
- phoenix/server/api/input_types/DeleteDatasetInput.py +7 -0
- phoenix/server/api/input_types/DeleteExperimentsInput.py +7 -0
- phoenix/server/api/input_types/DimensionFilter.py +4 -4
- phoenix/server/api/input_types/GenerativeModelInput.py +17 -0
- phoenix/server/api/input_types/Granularity.py +1 -1
- phoenix/server/api/input_types/InvocationParameters.py +162 -0
- phoenix/server/api/input_types/PatchAnnotationInput.py +19 -0
- phoenix/server/api/input_types/PatchDatasetExamplesInput.py +35 -0
- phoenix/server/api/input_types/PatchDatasetInput.py +14 -0
- phoenix/server/api/input_types/PerformanceMetricInput.py +5 -2
- phoenix/server/api/input_types/ProjectSessionSort.py +29 -0
- phoenix/server/api/input_types/SpanAnnotationSort.py +17 -0
- phoenix/server/api/input_types/SpanSort.py +134 -69
- phoenix/server/api/input_types/TemplateOptions.py +10 -0
- phoenix/server/api/input_types/TraceAnnotationSort.py +17 -0
- phoenix/server/api/input_types/UserRoleInput.py +9 -0
- phoenix/server/api/mutations/__init__.py +28 -0
- phoenix/server/api/mutations/api_key_mutations.py +167 -0
- phoenix/server/api/mutations/chat_mutations.py +593 -0
- phoenix/server/api/mutations/dataset_mutations.py +591 -0
- phoenix/server/api/mutations/experiment_mutations.py +75 -0
- phoenix/server/api/{types/ExportEventsMutation.py → mutations/export_events_mutations.py} +21 -18
- phoenix/server/api/mutations/project_mutations.py +57 -0
- phoenix/server/api/mutations/span_annotations_mutations.py +128 -0
- phoenix/server/api/mutations/trace_annotations_mutations.py +127 -0
- phoenix/server/api/mutations/user_mutations.py +329 -0
- phoenix/server/api/openapi/__init__.py +0 -0
- phoenix/server/api/openapi/main.py +17 -0
- phoenix/server/api/openapi/schema.py +16 -0
- phoenix/server/api/queries.py +738 -0
- phoenix/server/api/routers/__init__.py +11 -0
- phoenix/server/api/routers/auth.py +284 -0
- phoenix/server/api/routers/embeddings.py +26 -0
- phoenix/server/api/routers/oauth2.py +488 -0
- phoenix/server/api/routers/v1/__init__.py +64 -0
- phoenix/server/api/routers/v1/datasets.py +1017 -0
- phoenix/server/api/routers/v1/evaluations.py +362 -0
- phoenix/server/api/routers/v1/experiment_evaluations.py +115 -0
- phoenix/server/api/routers/v1/experiment_runs.py +167 -0
- phoenix/server/api/routers/v1/experiments.py +308 -0
- phoenix/server/api/routers/v1/pydantic_compat.py +78 -0
- phoenix/server/api/routers/v1/spans.py +267 -0
- phoenix/server/api/routers/v1/traces.py +208 -0
- phoenix/server/api/routers/v1/utils.py +95 -0
- phoenix/server/api/schema.py +44 -241
- phoenix/server/api/subscriptions.py +597 -0
- phoenix/server/api/types/Annotation.py +21 -0
- phoenix/server/api/types/AnnotationSummary.py +55 -0
- phoenix/server/api/types/AnnotatorKind.py +16 -0
- phoenix/server/api/types/ApiKey.py +27 -0
- phoenix/server/api/types/AuthMethod.py +9 -0
- phoenix/server/api/types/ChatCompletionMessageRole.py +11 -0
- phoenix/server/api/types/ChatCompletionSubscriptionPayload.py +46 -0
- phoenix/server/api/types/Cluster.py +25 -24
- phoenix/server/api/types/CreateDatasetPayload.py +8 -0
- phoenix/server/api/types/DataQualityMetric.py +31 -13
- phoenix/server/api/types/Dataset.py +288 -63
- phoenix/server/api/types/DatasetExample.py +85 -0
- phoenix/server/api/types/DatasetExampleRevision.py +34 -0
- phoenix/server/api/types/DatasetVersion.py +14 -0
- phoenix/server/api/types/Dimension.py +32 -31
- phoenix/server/api/types/DocumentEvaluationSummary.py +9 -8
- phoenix/server/api/types/EmbeddingDimension.py +56 -49
- phoenix/server/api/types/Evaluation.py +25 -31
- phoenix/server/api/types/EvaluationSummary.py +30 -50
- phoenix/server/api/types/Event.py +20 -20
- phoenix/server/api/types/ExampleRevisionInterface.py +14 -0
- phoenix/server/api/types/Experiment.py +152 -0
- phoenix/server/api/types/ExperimentAnnotationSummary.py +13 -0
- phoenix/server/api/types/ExperimentComparison.py +17 -0
- phoenix/server/api/types/ExperimentRun.py +119 -0
- phoenix/server/api/types/ExperimentRunAnnotation.py +56 -0
- phoenix/server/api/types/GenerativeModel.py +9 -0
- phoenix/server/api/types/GenerativeProvider.py +85 -0
- phoenix/server/api/types/Inferences.py +80 -0
- phoenix/server/api/types/InferencesRole.py +23 -0
- phoenix/server/api/types/LabelFraction.py +7 -0
- phoenix/server/api/types/MimeType.py +2 -2
- phoenix/server/api/types/Model.py +54 -54
- phoenix/server/api/types/PerformanceMetric.py +8 -5
- phoenix/server/api/types/Project.py +407 -142
- phoenix/server/api/types/ProjectSession.py +139 -0
- phoenix/server/api/types/Segments.py +4 -4
- phoenix/server/api/types/Span.py +221 -176
- phoenix/server/api/types/SpanAnnotation.py +43 -0
- phoenix/server/api/types/SpanIOValue.py +15 -0
- phoenix/server/api/types/SystemApiKey.py +9 -0
- phoenix/server/api/types/TemplateLanguage.py +10 -0
- phoenix/server/api/types/TimeSeries.py +19 -15
- phoenix/server/api/types/TokenUsage.py +11 -0
- phoenix/server/api/types/Trace.py +154 -0
- phoenix/server/api/types/TraceAnnotation.py +45 -0
- phoenix/server/api/types/UMAPPoints.py +7 -7
- phoenix/server/api/types/User.py +60 -0
- phoenix/server/api/types/UserApiKey.py +45 -0
- phoenix/server/api/types/UserRole.py +15 -0
- phoenix/server/api/types/node.py +4 -112
- phoenix/server/api/types/pagination.py +156 -57
- phoenix/server/api/utils.py +34 -0
- phoenix/server/app.py +864 -115
- phoenix/server/bearer_auth.py +163 -0
- phoenix/server/dml_event.py +136 -0
- phoenix/server/dml_event_handler.py +256 -0
- phoenix/server/email/__init__.py +0 -0
- phoenix/server/email/sender.py +97 -0
- phoenix/server/email/templates/__init__.py +0 -0
- phoenix/server/email/templates/password_reset.html +19 -0
- phoenix/server/email/types.py +11 -0
- phoenix/server/grpc_server.py +102 -0
- phoenix/server/jwt_store.py +505 -0
- phoenix/server/main.py +305 -116
- phoenix/server/oauth2.py +52 -0
- phoenix/server/openapi/__init__.py +0 -0
- phoenix/server/prometheus.py +111 -0
- phoenix/server/rate_limiters.py +188 -0
- phoenix/server/static/.vite/manifest.json +87 -0
- phoenix/server/static/assets/components-Cy9nwIvF.js +2125 -0
- phoenix/server/static/assets/index-BKvHIxkk.js +113 -0
- phoenix/server/static/assets/pages-CUi2xCVQ.js +4449 -0
- phoenix/server/static/assets/vendor-DvC8cT4X.js +894 -0
- phoenix/server/static/assets/vendor-DxkFTwjz.css +1 -0
- phoenix/server/static/assets/vendor-arizeai-Do1793cv.js +662 -0
- phoenix/server/static/assets/vendor-codemirror-BzwZPyJM.js +24 -0
- phoenix/server/static/assets/vendor-recharts-_Jb7JjhG.js +59 -0
- phoenix/server/static/assets/vendor-shiki-Cl9QBraO.js +5 -0
- phoenix/server/static/assets/vendor-three-DwGkEfCM.js +2998 -0
- phoenix/server/telemetry.py +68 -0
- phoenix/server/templates/index.html +82 -23
- phoenix/server/thread_server.py +3 -3
- phoenix/server/types.py +275 -0
- phoenix/services.py +27 -18
- phoenix/session/client.py +743 -68
- phoenix/session/data_extractor.py +31 -7
- phoenix/session/evaluation.py +3 -9
- phoenix/session/session.py +263 -219
- phoenix/settings.py +22 -0
- phoenix/trace/__init__.py +2 -22
- phoenix/trace/attributes.py +338 -0
- phoenix/trace/dsl/README.md +116 -0
- phoenix/trace/dsl/filter.py +663 -213
- phoenix/trace/dsl/helpers.py +73 -21
- phoenix/trace/dsl/query.py +574 -201
- phoenix/trace/exporter.py +24 -19
- phoenix/trace/fixtures.py +368 -32
- phoenix/trace/otel.py +71 -219
- phoenix/trace/projects.py +3 -2
- phoenix/trace/schemas.py +33 -11
- phoenix/trace/span_evaluations.py +21 -16
- phoenix/trace/span_json_decoder.py +6 -4
- phoenix/trace/span_json_encoder.py +2 -2
- phoenix/trace/trace_dataset.py +47 -32
- phoenix/trace/utils.py +21 -4
- phoenix/utilities/__init__.py +0 -26
- phoenix/utilities/client.py +132 -0
- phoenix/utilities/deprecation.py +31 -0
- phoenix/utilities/error_handling.py +3 -2
- phoenix/utilities/json.py +109 -0
- phoenix/utilities/logging.py +8 -0
- phoenix/utilities/project.py +2 -2
- phoenix/utilities/re.py +49 -0
- phoenix/utilities/span_store.py +0 -23
- phoenix/utilities/template_formatters.py +99 -0
- phoenix/version.py +1 -1
- arize_phoenix-3.16.1.dist-info/METADATA +0 -495
- arize_phoenix-3.16.1.dist-info/RECORD +0 -178
- phoenix/core/project.py +0 -619
- phoenix/core/traces.py +0 -96
- phoenix/experimental/evals/__init__.py +0 -73
- phoenix/experimental/evals/evaluators.py +0 -413
- phoenix/experimental/evals/functions/__init__.py +0 -4
- phoenix/experimental/evals/functions/classify.py +0 -453
- phoenix/experimental/evals/functions/executor.py +0 -353
- phoenix/experimental/evals/functions/generate.py +0 -138
- phoenix/experimental/evals/functions/processing.py +0 -76
- phoenix/experimental/evals/models/__init__.py +0 -14
- phoenix/experimental/evals/models/anthropic.py +0 -175
- phoenix/experimental/evals/models/base.py +0 -170
- phoenix/experimental/evals/models/bedrock.py +0 -221
- phoenix/experimental/evals/models/litellm.py +0 -134
- phoenix/experimental/evals/models/openai.py +0 -448
- phoenix/experimental/evals/models/rate_limiters.py +0 -246
- phoenix/experimental/evals/models/vertex.py +0 -173
- phoenix/experimental/evals/models/vertexai.py +0 -186
- phoenix/experimental/evals/retrievals.py +0 -96
- phoenix/experimental/evals/templates/__init__.py +0 -50
- phoenix/experimental/evals/templates/default_templates.py +0 -472
- phoenix/experimental/evals/templates/template.py +0 -195
- phoenix/experimental/evals/utils/__init__.py +0 -172
- phoenix/experimental/evals/utils/threads.py +0 -27
- phoenix/server/api/helpers.py +0 -11
- phoenix/server/api/routers/evaluation_handler.py +0 -109
- phoenix/server/api/routers/span_handler.py +0 -70
- phoenix/server/api/routers/trace_handler.py +0 -60
- phoenix/server/api/types/DatasetRole.py +0 -23
- phoenix/server/static/index.css +0 -6
- phoenix/server/static/index.js +0 -7447
- phoenix/storage/span_store/__init__.py +0 -23
- phoenix/storage/span_store/text_file.py +0 -85
- phoenix/trace/dsl/missing.py +0 -60
- phoenix/trace/langchain/__init__.py +0 -3
- phoenix/trace/langchain/instrumentor.py +0 -35
- phoenix/trace/llama_index/__init__.py +0 -3
- phoenix/trace/llama_index/callback.py +0 -102
- phoenix/trace/openai/__init__.py +0 -3
- phoenix/trace/openai/instrumentor.py +0 -30
- {arize_phoenix-3.16.1.dist-info → arize_phoenix-7.7.0.dist-info}/licenses/IP_NOTICE +0 -0
- {arize_phoenix-3.16.1.dist-info → arize_phoenix-7.7.0.dist-info}/licenses/LICENSE +0 -0
- /phoenix/{datasets → db/insertion}/__init__.py +0 -0
- /phoenix/{experimental → db/migrations}/__init__.py +0 -0
- /phoenix/{storage → db/migrations/data_migration_scripts}/__init__.py +0 -0
phoenix/session/session.py
CHANGED
|
@@ -1,26 +1,19 @@
|
|
|
1
1
|
import json
|
|
2
2
|
import logging
|
|
3
3
|
import os
|
|
4
|
+
import shutil
|
|
4
5
|
import warnings
|
|
5
6
|
from abc import ABC, abstractmethod
|
|
6
7
|
from collections import UserList
|
|
8
|
+
from collections.abc import Iterable, Mapping
|
|
7
9
|
from datetime import datetime
|
|
8
10
|
from enum import Enum
|
|
9
11
|
from importlib.util import find_spec
|
|
12
|
+
from itertools import chain
|
|
10
13
|
from pathlib import Path
|
|
11
14
|
from tempfile import TemporaryDirectory
|
|
12
|
-
from
|
|
13
|
-
from
|
|
14
|
-
TYPE_CHECKING,
|
|
15
|
-
Any,
|
|
16
|
-
Iterable,
|
|
17
|
-
List,
|
|
18
|
-
Mapping,
|
|
19
|
-
NamedTuple,
|
|
20
|
-
Optional,
|
|
21
|
-
Set,
|
|
22
|
-
Union,
|
|
23
|
-
)
|
|
15
|
+
from typing import TYPE_CHECKING, Any, NamedTuple, Optional, Union
|
|
16
|
+
from urllib.parse import urljoin
|
|
24
17
|
|
|
25
18
|
import pandas as pd
|
|
26
19
|
|
|
@@ -29,26 +22,32 @@ from phoenix.config import (
|
|
|
29
22
|
ENV_PHOENIX_COLLECTOR_ENDPOINT,
|
|
30
23
|
ENV_PHOENIX_HOST,
|
|
31
24
|
ENV_PHOENIX_PORT,
|
|
25
|
+
ensure_working_dir,
|
|
26
|
+
get_env_database_connection_str,
|
|
27
|
+
get_env_enable_websockets,
|
|
32
28
|
get_env_host,
|
|
33
29
|
get_env_port,
|
|
34
|
-
get_env_project_name,
|
|
35
30
|
get_exported_files,
|
|
31
|
+
get_working_dir,
|
|
36
32
|
)
|
|
37
|
-
from phoenix.core.model_schema_adapter import
|
|
38
|
-
from phoenix.
|
|
39
|
-
from phoenix.datasets.dataset import EMPTY_DATASET, Dataset
|
|
33
|
+
from phoenix.core.model_schema_adapter import create_model_from_inferences
|
|
34
|
+
from phoenix.inferences.inferences import EMPTY_INFERENCES, Inferences
|
|
40
35
|
from phoenix.pointcloud.umap_parameters import get_umap_parameters
|
|
41
|
-
from phoenix.server.app import
|
|
36
|
+
from phoenix.server.app import (
|
|
37
|
+
_db,
|
|
38
|
+
create_app,
|
|
39
|
+
create_engine_and_run_migrations,
|
|
40
|
+
instrument_engine_if_enabled,
|
|
41
|
+
)
|
|
42
42
|
from phoenix.server.thread_server import ThreadServer
|
|
43
|
+
from phoenix.server.types import DbSessionFactory
|
|
43
44
|
from phoenix.services import AppService
|
|
44
45
|
from phoenix.session.client import Client
|
|
45
|
-
from phoenix.session.data_extractor import TraceDataExtractor
|
|
46
|
+
from phoenix.session.data_extractor import DEFAULT_SPAN_LIMIT, TraceDataExtractor
|
|
46
47
|
from phoenix.session.evaluation import encode_evaluations
|
|
47
48
|
from phoenix.trace import Evaluations
|
|
48
49
|
from phoenix.trace.dsl.query import SpanQuery
|
|
49
50
|
from phoenix.trace.trace_dataset import TraceDataset
|
|
50
|
-
from phoenix.utilities import query_spans
|
|
51
|
-
from phoenix.utilities.span_store import get_span_store, load_traces_data_from_store
|
|
52
51
|
|
|
53
52
|
try:
|
|
54
53
|
from IPython.display import IFrame # type: ignore
|
|
@@ -64,6 +63,13 @@ if TYPE_CHECKING:
|
|
|
64
63
|
else:
|
|
65
64
|
_BaseList = UserList
|
|
66
65
|
|
|
66
|
+
# Temporary directory for the duration of the session
|
|
67
|
+
global _session_working_dir
|
|
68
|
+
_session_working_dir: Optional["TemporaryDirectory[str]"] = None
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
DEFAULT_TIMEOUT_IN_SECONDS = 5
|
|
72
|
+
|
|
67
73
|
|
|
68
74
|
class NotebookEnvironment(Enum):
|
|
69
75
|
COLAB = "colab"
|
|
@@ -74,8 +80,8 @@ class NotebookEnvironment(Enum):
|
|
|
74
80
|
|
|
75
81
|
class ExportedData(_BaseList):
|
|
76
82
|
def __init__(self) -> None:
|
|
77
|
-
self.paths:
|
|
78
|
-
self.names:
|
|
83
|
+
self.paths: set[Path] = set()
|
|
84
|
+
self.names: list[str] = []
|
|
79
85
|
super().__init__()
|
|
80
86
|
|
|
81
87
|
def __repr__(self) -> str:
|
|
@@ -95,50 +101,30 @@ class Session(TraceDataExtractor, ABC):
|
|
|
95
101
|
"""Session that maintains a 1-1 shared state with the Phoenix App."""
|
|
96
102
|
|
|
97
103
|
trace_dataset: Optional[TraceDataset]
|
|
98
|
-
traces: Optional[Traces]
|
|
99
104
|
notebook_env: NotebookEnvironment
|
|
100
105
|
"""The notebook environment that the session is running in."""
|
|
101
106
|
|
|
102
|
-
def __dir__(self) ->
|
|
107
|
+
def __dir__(self) -> list[str]:
|
|
103
108
|
return ["exports", "view", "url"]
|
|
104
109
|
|
|
105
110
|
def __init__(
|
|
106
111
|
self,
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
112
|
+
database_url: str,
|
|
113
|
+
primary_inferences: Inferences,
|
|
114
|
+
reference_inferences: Optional[Inferences] = None,
|
|
115
|
+
corpus_inferences: Optional[Inferences] = None,
|
|
110
116
|
trace_dataset: Optional[TraceDataset] = None,
|
|
111
117
|
default_umap_parameters: Optional[Mapping[str, Any]] = None,
|
|
112
118
|
host: Optional[str] = None,
|
|
113
119
|
port: Optional[int] = None,
|
|
114
120
|
notebook_env: Optional[NotebookEnvironment] = None,
|
|
115
121
|
):
|
|
116
|
-
self.
|
|
117
|
-
self.
|
|
118
|
-
self.
|
|
122
|
+
self._database_url = database_url
|
|
123
|
+
self.primary_inferences = primary_inferences
|
|
124
|
+
self.reference_inferences = reference_inferences
|
|
125
|
+
self.corpus_inferences = corpus_inferences
|
|
119
126
|
self.trace_dataset = trace_dataset
|
|
120
127
|
self.umap_parameters = get_umap_parameters(default_umap_parameters)
|
|
121
|
-
self.model = create_model_from_datasets(
|
|
122
|
-
primary_dataset,
|
|
123
|
-
reference_dataset,
|
|
124
|
-
)
|
|
125
|
-
|
|
126
|
-
self.corpus = (
|
|
127
|
-
create_model_from_datasets(
|
|
128
|
-
corpus_dataset,
|
|
129
|
-
)
|
|
130
|
-
if corpus_dataset is not None
|
|
131
|
-
else None
|
|
132
|
-
)
|
|
133
|
-
|
|
134
|
-
self.traces = Traces()
|
|
135
|
-
if trace_dataset:
|
|
136
|
-
for span in trace_dataset.to_spans():
|
|
137
|
-
self.traces.put(span)
|
|
138
|
-
for evaluations in trace_dataset.evaluations:
|
|
139
|
-
for pb_evaluation in encode_evaluations(evaluations):
|
|
140
|
-
self.traces.put(pb_evaluation)
|
|
141
|
-
|
|
142
128
|
self.host = host or get_env_host()
|
|
143
129
|
self.port = port or get_env_port()
|
|
144
130
|
self.temp_dir = TemporaryDirectory()
|
|
@@ -147,6 +133,88 @@ class Session(TraceDataExtractor, ABC):
|
|
|
147
133
|
self.exported_data = ExportedData()
|
|
148
134
|
self.notebook_env = notebook_env or _get_notebook_environment()
|
|
149
135
|
self.root_path = _get_root_path(self.notebook_env, self.port)
|
|
136
|
+
host = "127.0.0.1" if self.host == "0.0.0.0" else self.host
|
|
137
|
+
self._client = Client(
|
|
138
|
+
endpoint=f"http://{host}:{self.port}", warn_if_server_not_running=False
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
def query_spans(
|
|
142
|
+
self,
|
|
143
|
+
*queries: SpanQuery,
|
|
144
|
+
start_time: Optional[datetime] = None,
|
|
145
|
+
end_time: Optional[datetime] = None,
|
|
146
|
+
limit: Optional[int] = DEFAULT_SPAN_LIMIT,
|
|
147
|
+
root_spans_only: Optional[bool] = None,
|
|
148
|
+
project_name: Optional[str] = None,
|
|
149
|
+
# Deprecated fields
|
|
150
|
+
stop_time: Optional[datetime] = None,
|
|
151
|
+
timeout: Optional[int] = DEFAULT_TIMEOUT_IN_SECONDS,
|
|
152
|
+
) -> Optional[Union[pd.DataFrame, list[pd.DataFrame]]]:
|
|
153
|
+
"""
|
|
154
|
+
Queries the spans in the project based on the provided parameters.
|
|
155
|
+
|
|
156
|
+
Parameters
|
|
157
|
+
----------
|
|
158
|
+
queries : *SpanQuery
|
|
159
|
+
Variable-length argument list of SpanQuery objects representing
|
|
160
|
+
the queries to be executed.
|
|
161
|
+
|
|
162
|
+
start_time : datetime, optional
|
|
163
|
+
datetime representing the start time of the query.
|
|
164
|
+
|
|
165
|
+
end_time : datetime, optional
|
|
166
|
+
datetime representing the end time of the query.
|
|
167
|
+
|
|
168
|
+
root_spans_only : boolean, optional
|
|
169
|
+
whether to include only root spans in the results.
|
|
170
|
+
|
|
171
|
+
project_name : string, optional
|
|
172
|
+
name of the project to query. Defaults to the project name set
|
|
173
|
+
in the environment variable `PHOENIX_PROJECT_NAME` or 'default' if not set.
|
|
174
|
+
|
|
175
|
+
Returns:
|
|
176
|
+
results : DataFrame
|
|
177
|
+
DataFrame or list of DataFrames containing the query results.
|
|
178
|
+
"""
|
|
179
|
+
if stop_time is not None:
|
|
180
|
+
warnings.warn(
|
|
181
|
+
"The `stop_time` parameter is deprecated and will be removed in a future release. "
|
|
182
|
+
"Please use `end_time` instead.",
|
|
183
|
+
DeprecationWarning,
|
|
184
|
+
)
|
|
185
|
+
end_time = stop_time
|
|
186
|
+
return self._client.query_spans(
|
|
187
|
+
*queries,
|
|
188
|
+
start_time=start_time,
|
|
189
|
+
end_time=end_time,
|
|
190
|
+
limit=limit,
|
|
191
|
+
root_spans_only=root_spans_only,
|
|
192
|
+
project_name=project_name,
|
|
193
|
+
)
|
|
194
|
+
|
|
195
|
+
def get_evaluations(
|
|
196
|
+
self,
|
|
197
|
+
project_name: Optional[str] = None,
|
|
198
|
+
) -> list[Evaluations]:
|
|
199
|
+
"""
|
|
200
|
+
Get the evaluations for a project.
|
|
201
|
+
|
|
202
|
+
Parameters
|
|
203
|
+
----------
|
|
204
|
+
project_name : str, optional
|
|
205
|
+
The name of the project. If not provided, the project name set
|
|
206
|
+
in the environment variable `PHOENIX_PROJECT_NAME` will be used.
|
|
207
|
+
Otherwise, 'default' will be used.
|
|
208
|
+
|
|
209
|
+
Returns
|
|
210
|
+
-------
|
|
211
|
+
evaluations : list[Evaluations]
|
|
212
|
+
A list of evaluations for the specified project.
|
|
213
|
+
|
|
214
|
+
"""
|
|
215
|
+
return self._client.get_evaluations(
|
|
216
|
+
project_name=project_name,
|
|
217
|
+
)
|
|
150
218
|
|
|
151
219
|
@abstractmethod
|
|
152
220
|
def end(self) -> None:
|
|
@@ -170,23 +238,29 @@ class Session(TraceDataExtractor, ABC):
|
|
|
170
238
|
self.exported_data.add(files)
|
|
171
239
|
return self.exported_data
|
|
172
240
|
|
|
173
|
-
def view(self, height: int = 1000) -> "IFrame":
|
|
174
|
-
"""
|
|
175
|
-
Returns an IFrame that can be displayed in a notebook to view the app.
|
|
241
|
+
def view(self, *, height: int = 1000, slug: str = "") -> "IFrame":
|
|
242
|
+
"""View the session in a notebook embedded iFrame.
|
|
176
243
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
244
|
+
Args:
|
|
245
|
+
slug (str, optional): the path of the app to view
|
|
246
|
+
height (int, optional): the height of the iFrame in px. Defaults to 1000.
|
|
247
|
+
|
|
248
|
+
Returns:
|
|
249
|
+
IFrame: the iFrame will be rendered in the notebook
|
|
181
250
|
"""
|
|
251
|
+
url_to_view = urljoin(self.url, slug)
|
|
182
252
|
print(f"📺 Opening a view to the Phoenix app. The app is running at {self.url}")
|
|
183
|
-
return IFrame(src=
|
|
253
|
+
return IFrame(src=url_to_view, width="100%", height=height)
|
|
184
254
|
|
|
185
255
|
@property
|
|
186
256
|
def url(self) -> str:
|
|
187
257
|
"""Returns the url for the phoenix app"""
|
|
188
258
|
return _get_url(self.host, self.port, self.notebook_env)
|
|
189
259
|
|
|
260
|
+
@property
|
|
261
|
+
def database_url(self) -> str:
|
|
262
|
+
return self._database_url
|
|
263
|
+
|
|
190
264
|
|
|
191
265
|
_session: Optional[Session] = None
|
|
192
266
|
|
|
@@ -194,9 +268,11 @@ _session: Optional[Session] = None
|
|
|
194
268
|
class ProcessSession(Session):
|
|
195
269
|
def __init__(
|
|
196
270
|
self,
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
271
|
+
database_url: str,
|
|
272
|
+
primary_inferences: Inferences,
|
|
273
|
+
enable_websockets: bool,
|
|
274
|
+
reference_inferences: Optional[Inferences] = None,
|
|
275
|
+
corpus_inferences: Optional[Inferences] = None,
|
|
200
276
|
trace_dataset: Optional[TraceDataset] = None,
|
|
201
277
|
default_umap_parameters: Optional[Mapping[str, Any]] = None,
|
|
202
278
|
host: Optional[str] = None,
|
|
@@ -205,20 +281,21 @@ class ProcessSession(Session):
|
|
|
205
281
|
notebook_env: Optional[NotebookEnvironment] = None,
|
|
206
282
|
) -> None:
|
|
207
283
|
super().__init__(
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
284
|
+
database_url=database_url,
|
|
285
|
+
primary_inferences=primary_inferences,
|
|
286
|
+
reference_inferences=reference_inferences,
|
|
287
|
+
corpus_inferences=corpus_inferences,
|
|
211
288
|
trace_dataset=trace_dataset,
|
|
212
289
|
default_umap_parameters=default_umap_parameters,
|
|
213
290
|
host=host,
|
|
214
291
|
port=port,
|
|
215
292
|
notebook_env=notebook_env,
|
|
216
293
|
)
|
|
217
|
-
|
|
218
|
-
if isinstance(
|
|
219
|
-
|
|
220
|
-
if isinstance(
|
|
221
|
-
|
|
294
|
+
primary_inferences.to_disc()
|
|
295
|
+
if isinstance(reference_inferences, Inferences):
|
|
296
|
+
reference_inferences.to_disc()
|
|
297
|
+
if isinstance(corpus_inferences, Inferences):
|
|
298
|
+
corpus_inferences.to_disc()
|
|
222
299
|
if isinstance(trace_dataset, TraceDataset):
|
|
223
300
|
trace_dataset.to_disc()
|
|
224
301
|
umap_params_str = (
|
|
@@ -228,26 +305,23 @@ class ProcessSession(Session):
|
|
|
228
305
|
)
|
|
229
306
|
# Initialize an app service that keeps the server running
|
|
230
307
|
self.app_service = AppService(
|
|
231
|
-
|
|
232
|
-
self.
|
|
233
|
-
self.
|
|
234
|
-
self.
|
|
235
|
-
self.
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
308
|
+
database_url=database_url,
|
|
309
|
+
export_path=self.export_path,
|
|
310
|
+
host=self.host,
|
|
311
|
+
port=self.port,
|
|
312
|
+
root_path=self.root_path,
|
|
313
|
+
primary_inferences_name=self.primary_inferences.name,
|
|
314
|
+
umap_params=umap_params_str,
|
|
315
|
+
reference_inferences_name=(
|
|
316
|
+
self.reference_inferences.name if self.reference_inferences is not None else None
|
|
239
317
|
),
|
|
240
|
-
|
|
241
|
-
self.
|
|
318
|
+
corpus_inferences_name=(
|
|
319
|
+
self.corpus_inferences.name if self.corpus_inferences is not None else None
|
|
242
320
|
),
|
|
243
321
|
trace_dataset_name=(
|
|
244
322
|
self.trace_dataset.name if self.trace_dataset is not None else None
|
|
245
323
|
),
|
|
246
|
-
|
|
247
|
-
host = "127.0.0.1" if self.host == "0.0.0.0" else self.host
|
|
248
|
-
self._client = Client(
|
|
249
|
-
endpoint=f"http://{host}:{self.port}",
|
|
250
|
-
use_active_session_if_available=False,
|
|
324
|
+
enable_websockets=enable_websockets,
|
|
251
325
|
)
|
|
252
326
|
|
|
253
327
|
@property
|
|
@@ -258,35 +332,15 @@ class ProcessSession(Session):
|
|
|
258
332
|
self.app_service.stop()
|
|
259
333
|
self.temp_dir.cleanup()
|
|
260
334
|
|
|
261
|
-
def query_spans(
|
|
262
|
-
self,
|
|
263
|
-
*queries: SpanQuery,
|
|
264
|
-
start_time: Optional[datetime] = None,
|
|
265
|
-
stop_time: Optional[datetime] = None,
|
|
266
|
-
root_spans_only: Optional[bool] = None,
|
|
267
|
-
project_name: Optional[str] = None,
|
|
268
|
-
) -> Optional[Union[pd.DataFrame, List[pd.DataFrame]]]:
|
|
269
|
-
return self._client.query_spans(
|
|
270
|
-
*queries,
|
|
271
|
-
start_time=start_time,
|
|
272
|
-
stop_time=stop_time,
|
|
273
|
-
root_spans_only=root_spans_only,
|
|
274
|
-
project_name=project_name,
|
|
275
|
-
)
|
|
276
|
-
|
|
277
|
-
def get_evaluations(
|
|
278
|
-
self,
|
|
279
|
-
project_name: Optional[str] = None,
|
|
280
|
-
) -> List[Evaluations]:
|
|
281
|
-
return self._client.get_evaluations()
|
|
282
|
-
|
|
283
335
|
|
|
284
336
|
class ThreadSession(Session):
|
|
285
337
|
def __init__(
|
|
286
338
|
self,
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
339
|
+
database_url: str,
|
|
340
|
+
primary_inferences: Inferences,
|
|
341
|
+
enable_websockets: bool,
|
|
342
|
+
reference_inferences: Optional[Inferences] = None,
|
|
343
|
+
corpus_inferences: Optional[Inferences] = None,
|
|
290
344
|
trace_dataset: Optional[TraceDataset] = None,
|
|
291
345
|
default_umap_parameters: Optional[Mapping[str, Any]] = None,
|
|
292
346
|
host: Optional[str] = None,
|
|
@@ -295,29 +349,46 @@ class ThreadSession(Session):
|
|
|
295
349
|
notebook_env: Optional[NotebookEnvironment] = None,
|
|
296
350
|
):
|
|
297
351
|
super().__init__(
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
352
|
+
database_url=database_url,
|
|
353
|
+
primary_inferences=primary_inferences,
|
|
354
|
+
reference_inferences=reference_inferences,
|
|
355
|
+
corpus_inferences=corpus_inferences,
|
|
301
356
|
trace_dataset=trace_dataset,
|
|
302
357
|
default_umap_parameters=default_umap_parameters,
|
|
303
358
|
host=host,
|
|
304
359
|
port=port,
|
|
305
360
|
notebook_env=notebook_env,
|
|
306
361
|
)
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
362
|
+
self.model = create_model_from_inferences(
|
|
363
|
+
primary_inferences,
|
|
364
|
+
reference_inferences,
|
|
365
|
+
)
|
|
366
|
+
self.corpus = (
|
|
367
|
+
create_model_from_inferences(
|
|
368
|
+
corpus_inferences,
|
|
369
|
+
)
|
|
370
|
+
if corpus_inferences is not None
|
|
371
|
+
else None
|
|
372
|
+
)
|
|
313
373
|
# Initialize an app service that keeps the server running
|
|
374
|
+
engine = create_engine_and_run_migrations(database_url)
|
|
375
|
+
instrumentation_cleanups = instrument_engine_if_enabled(engine)
|
|
376
|
+
factory = DbSessionFactory(db=_db(engine), dialect=engine.dialect.name)
|
|
314
377
|
self.app = create_app(
|
|
378
|
+
db=factory,
|
|
315
379
|
export_path=self.export_path,
|
|
316
380
|
model=self.model,
|
|
381
|
+
authentication_enabled=False,
|
|
382
|
+
enable_websockets=enable_websockets,
|
|
317
383
|
corpus=self.corpus,
|
|
318
|
-
traces=self.traces,
|
|
319
384
|
umap_params=self.umap_parameters,
|
|
320
|
-
|
|
385
|
+
initial_spans=trace_dataset.to_spans() if trace_dataset else None,
|
|
386
|
+
initial_evaluations=(
|
|
387
|
+
chain.from_iterable(map(encode_evaluations, initial_evaluations))
|
|
388
|
+
if (trace_dataset and (initial_evaluations := trace_dataset.evaluations))
|
|
389
|
+
else None
|
|
390
|
+
),
|
|
391
|
+
shutdown_callbacks=instrumentation_cleanups,
|
|
321
392
|
)
|
|
322
393
|
self.server = ThreadServer(
|
|
323
394
|
app=self.app,
|
|
@@ -336,103 +407,43 @@ class ThreadSession(Session):
|
|
|
336
407
|
self.server.close()
|
|
337
408
|
self.temp_dir.cleanup()
|
|
338
409
|
|
|
339
|
-
def query_spans(
|
|
340
|
-
self,
|
|
341
|
-
*queries: SpanQuery,
|
|
342
|
-
start_time: Optional[datetime] = None,
|
|
343
|
-
stop_time: Optional[datetime] = None,
|
|
344
|
-
root_spans_only: Optional[bool] = None,
|
|
345
|
-
project_name: Optional[str] = None,
|
|
346
|
-
) -> Optional[Union[pd.DataFrame, List[pd.DataFrame]]]:
|
|
347
|
-
"""
|
|
348
|
-
Queries the spans in the project based on the provided parameters.
|
|
349
|
-
|
|
350
|
-
Parameters
|
|
351
|
-
----------
|
|
352
|
-
queries : *SpanQuery
|
|
353
|
-
Variable-length argument list of SpanQuery objects representing
|
|
354
|
-
the queries to be executed.
|
|
355
|
-
|
|
356
|
-
start_time : datetime, optional
|
|
357
|
-
datetime representing the start time of the query.
|
|
358
|
-
|
|
359
|
-
stop_time : datetime, optional
|
|
360
|
-
datetime representing the stop time of the query.
|
|
361
410
|
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
if
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
SpanQuery.from_dict(
|
|
382
|
-
query.to_dict(),
|
|
383
|
-
evals=project,
|
|
384
|
-
valid_eval_names=valid_eval_names,
|
|
411
|
+
def delete_all(prompt_before_delete: Optional[bool] = True) -> None:
|
|
412
|
+
"""
|
|
413
|
+
Deletes the entire contents of the working directory. This will delete, traces, evaluations,
|
|
414
|
+
and any other data stored in the working directory.
|
|
415
|
+
"""
|
|
416
|
+
global _session_working_dir
|
|
417
|
+
working_dir = get_working_dir()
|
|
418
|
+
directories_to_delete = []
|
|
419
|
+
if working_dir.exists():
|
|
420
|
+
directories_to_delete.append(working_dir)
|
|
421
|
+
if _session_working_dir is not None:
|
|
422
|
+
directories_to_delete.append(Path(_session_working_dir.name))
|
|
423
|
+
|
|
424
|
+
# Loop through directories to delete
|
|
425
|
+
for directory in directories_to_delete:
|
|
426
|
+
if prompt_before_delete:
|
|
427
|
+
input(
|
|
428
|
+
f"You have data at {directory}. Are you sure you want to delete?"
|
|
429
|
+
+ " This cannot be undone. Press Enter to delete, Escape to cancel."
|
|
385
430
|
)
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
results = query_spans(
|
|
389
|
-
project,
|
|
390
|
-
*queries,
|
|
391
|
-
start_time=start_time,
|
|
392
|
-
stop_time=stop_time,
|
|
393
|
-
root_spans_only=root_spans_only,
|
|
394
|
-
)
|
|
395
|
-
if len(results) == 1:
|
|
396
|
-
df = results[0]
|
|
397
|
-
return None if df.shape == (0, 0) else df
|
|
398
|
-
return results
|
|
399
|
-
|
|
400
|
-
def get_evaluations(
|
|
401
|
-
self,
|
|
402
|
-
project_name: Optional[str] = None,
|
|
403
|
-
) -> List[Evaluations]:
|
|
404
|
-
"""
|
|
405
|
-
Get the evaluations for a project.
|
|
406
|
-
|
|
407
|
-
Parameters
|
|
408
|
-
----------
|
|
409
|
-
project_name : str, optional
|
|
410
|
-
The name of the project. If not provided, the project name set
|
|
411
|
-
in the environment variable `PHOENIX_PROJECT_NAME` will be used.
|
|
412
|
-
Otherwise, 'default' will be used.
|
|
413
|
-
|
|
414
|
-
Returns
|
|
415
|
-
-------
|
|
416
|
-
evaluations : List[Evaluations]
|
|
417
|
-
A list of evaluations for the specified project.
|
|
418
|
-
|
|
419
|
-
"""
|
|
420
|
-
project_name = project_name or get_env_project_name()
|
|
421
|
-
if not (traces := self.traces) or not (project := traces.get_project(project_name)):
|
|
422
|
-
return []
|
|
423
|
-
return project.export_evaluations()
|
|
431
|
+
shutil.rmtree(directory)
|
|
432
|
+
_session_working_dir = None
|
|
424
433
|
|
|
425
434
|
|
|
426
435
|
def launch_app(
|
|
427
|
-
primary: Optional[
|
|
428
|
-
reference: Optional[
|
|
429
|
-
corpus: Optional[
|
|
436
|
+
primary: Optional[Inferences] = None,
|
|
437
|
+
reference: Optional[Inferences] = None,
|
|
438
|
+
corpus: Optional[Inferences] = None,
|
|
430
439
|
trace: Optional[TraceDataset] = None,
|
|
431
440
|
default_umap_parameters: Optional[Mapping[str, Any]] = None,
|
|
432
441
|
host: Optional[str] = None,
|
|
433
442
|
port: Optional[int] = None,
|
|
434
443
|
run_in_thread: bool = True,
|
|
435
444
|
notebook_environment: Optional[Union[NotebookEnvironment, str]] = None,
|
|
445
|
+
use_temp_dir: bool = True,
|
|
446
|
+
enable_websockets: Optional[bool] = None,
|
|
436
447
|
) -> Optional[Session]:
|
|
437
448
|
"""
|
|
438
449
|
Launches the phoenix application and returns a session to interact with.
|
|
@@ -447,7 +458,7 @@ def launch_app(
|
|
|
447
458
|
corpus : Dataset, optional
|
|
448
459
|
The dataset containing corpus for LLM context retrieval.
|
|
449
460
|
trace: TraceDataset, optional
|
|
450
|
-
|
|
461
|
+
The trace dataset containing the trace data.
|
|
451
462
|
host: str, optional
|
|
452
463
|
The host on which the server runs. It can also be set using environment
|
|
453
464
|
variable `PHOENIX_HOST`, otherwise it defaults to `127.0.0.1`.
|
|
@@ -457,13 +468,18 @@ def launch_app(
|
|
|
457
468
|
Defaults to 6006.
|
|
458
469
|
run_in_thread: bool, optional, default=True
|
|
459
470
|
Whether the server should run in a Thread or Process.
|
|
460
|
-
default_umap_parameters:
|
|
471
|
+
default_umap_parameters: dict[str, Union[int, float]], optional, default=None
|
|
461
472
|
User specified default UMAP parameters
|
|
462
473
|
eg: {"n_neighbors": 10, "n_samples": 5, "min_dist": 0.5}
|
|
463
474
|
notebook_environment: str, optional, default=None
|
|
464
475
|
The environment the notebook is running in. This is either 'local', 'colab', or 'sagemaker'.
|
|
465
476
|
If not provided, phoenix will try to infer the environment. This is only needed if
|
|
466
477
|
there is a failure to infer the environment.
|
|
478
|
+
use_temp_dir: bool, optional, default=True
|
|
479
|
+
Whether to use a temporary directory to store the data. If set to False, the data will be
|
|
480
|
+
stored in the directory specified by PHOENIX_WORKING_DIR environment variable via SQLite.
|
|
481
|
+
enable_websockets: bool, optional, default=False
|
|
482
|
+
Whether to enable websockets.
|
|
467
483
|
|
|
468
484
|
Returns
|
|
469
485
|
-------
|
|
@@ -473,17 +489,21 @@ def launch_app(
|
|
|
473
489
|
Examples
|
|
474
490
|
--------
|
|
475
491
|
>>> import phoenix as px
|
|
476
|
-
>>> # construct
|
|
477
|
-
>>>
|
|
478
|
-
>>> session = px.launch_app(
|
|
492
|
+
>>> # construct an inference set to analyze
|
|
493
|
+
>>> inferences = px.Inferences(...)
|
|
494
|
+
>>> session = px.launch_app(inferences)
|
|
479
495
|
"""
|
|
480
496
|
global _session
|
|
481
497
|
|
|
498
|
+
# First we must ensure that the working directory is setup
|
|
499
|
+
# NB: this is because the working directory can be deleted by the user
|
|
500
|
+
ensure_working_dir()
|
|
501
|
+
|
|
482
502
|
# Stopgap solution to allow the app to run without a primary dataset
|
|
483
503
|
if primary is None:
|
|
484
|
-
# Dummy
|
|
485
|
-
# TODO: pass through the lack of a primary
|
|
486
|
-
primary =
|
|
504
|
+
# Dummy inferences
|
|
505
|
+
# TODO: pass through the lack of a primary inferences to the app
|
|
506
|
+
primary = EMPTY_INFERENCES
|
|
487
507
|
|
|
488
508
|
if _session is not None and _session.active:
|
|
489
509
|
logger.warning(
|
|
@@ -533,10 +553,23 @@ def launch_app(
|
|
|
533
553
|
|
|
534
554
|
host = host or get_env_host()
|
|
535
555
|
port = port or get_env_port()
|
|
556
|
+
if use_temp_dir:
|
|
557
|
+
global _session_working_dir
|
|
558
|
+
_session_working_dir = _session_working_dir or TemporaryDirectory()
|
|
559
|
+
database_url = f"sqlite:///{_session_working_dir.name}/phoenix.db"
|
|
560
|
+
else:
|
|
561
|
+
database_url = get_env_database_connection_str()
|
|
562
|
+
|
|
563
|
+
enable_websockets_env = get_env_enable_websockets() or False
|
|
564
|
+
enable_websockets = (
|
|
565
|
+
enable_websockets if enable_websockets is not None else enable_websockets_env
|
|
566
|
+
)
|
|
536
567
|
|
|
537
568
|
if run_in_thread:
|
|
538
569
|
_session = ThreadSession(
|
|
570
|
+
database_url,
|
|
539
571
|
primary,
|
|
572
|
+
enable_websockets,
|
|
540
573
|
reference,
|
|
541
574
|
corpus,
|
|
542
575
|
trace,
|
|
@@ -548,7 +581,9 @@ def launch_app(
|
|
|
548
581
|
# TODO: catch exceptions from thread
|
|
549
582
|
else:
|
|
550
583
|
_session = ProcessSession(
|
|
584
|
+
database_url,
|
|
551
585
|
primary,
|
|
586
|
+
enable_websockets,
|
|
552
587
|
reference,
|
|
553
588
|
corpus,
|
|
554
589
|
trace,
|
|
@@ -568,7 +603,8 @@ def launch_app(
|
|
|
568
603
|
return None
|
|
569
604
|
|
|
570
605
|
print(f"🌍 To view the Phoenix app in your browser, visit {_session.url}")
|
|
571
|
-
|
|
606
|
+
if not use_temp_dir:
|
|
607
|
+
print(f"💽 Your data is being persisted to {database_url}")
|
|
572
608
|
print("📖 For more information on how to use Phoenix, check out https://docs.arize.com/phoenix")
|
|
573
609
|
return _session
|
|
574
610
|
|
|
@@ -582,10 +618,15 @@ def active_session() -> Optional[Session]:
|
|
|
582
618
|
return None
|
|
583
619
|
|
|
584
620
|
|
|
585
|
-
def close_app() -> None:
|
|
621
|
+
def close_app(delete_data: bool = False) -> None:
|
|
586
622
|
"""
|
|
587
623
|
Closes the phoenix application.
|
|
588
624
|
The application server is shut down and will no longer be accessible.
|
|
625
|
+
|
|
626
|
+
Parameters
|
|
627
|
+
----------
|
|
628
|
+
delete_data : bool, optional
|
|
629
|
+
If set to true, all stored phoenix data, including traces and evaluations. Default False.
|
|
589
630
|
"""
|
|
590
631
|
global _session
|
|
591
632
|
if _session is None:
|
|
@@ -594,12 +635,15 @@ def close_app() -> None:
|
|
|
594
635
|
_session.end()
|
|
595
636
|
_session = None
|
|
596
637
|
logger.info("Session closed")
|
|
638
|
+
if delete_data:
|
|
639
|
+
logger.info("Deleting all data")
|
|
640
|
+
delete_all(prompt_before_delete=False)
|
|
597
641
|
|
|
598
642
|
|
|
599
643
|
def _get_url(host: str, port: int, notebook_env: NotebookEnvironment) -> str:
|
|
600
644
|
"""Determines the IFrame URL based on whether this is in a Colab or in a local notebook"""
|
|
601
645
|
if notebook_env == NotebookEnvironment.COLAB:
|
|
602
|
-
from google.colab.output import eval_js
|
|
646
|
+
from google.colab.output import eval_js
|
|
603
647
|
|
|
604
648
|
return str(eval_js(f"google.colab.kernel.proxyPort({port}, {{'cache': true}})"))
|
|
605
649
|
if notebook_env == NotebookEnvironment.SAGEMAKER:
|
|
@@ -617,7 +661,7 @@ def _get_url(host: str, port: int, notebook_env: NotebookEnvironment) -> str:
|
|
|
617
661
|
def _is_colab() -> bool:
|
|
618
662
|
"""Determines whether this is in a Colab"""
|
|
619
663
|
try:
|
|
620
|
-
import google.colab #
|
|
664
|
+
import google.colab # noqa: F401
|
|
621
665
|
except ImportError:
|
|
622
666
|
return False
|
|
623
667
|
try:
|