From 9b220cf560734bb2ebad9a2e0c966000ebc557c4 Mon Sep 17 00:00:00 2001 From: Mikyo King Date: Fri, 8 Mar 2024 17:35:06 -0700 Subject: [PATCH 1/4] feat(projects): add support for the PHOENIX_PROJECT_NAME param --- src/phoenix/config.py | 10 ++++++ src/phoenix/session/client.py | 9 ++++- src/phoenix/session/session.py | 38 ++++++++++++++++++--- src/phoenix/trace/langchain/instrumentor.py | 7 +++- src/phoenix/trace/llama_index/callback.py | 7 +++- src/phoenix/trace/openai/instrumentor.py | 7 +++- 6 files changed, 69 insertions(+), 9 deletions(-) diff --git a/src/phoenix/config.py b/src/phoenix/config.py index fe7dac30e3..320c449664 100644 --- a/src/phoenix/config.py +++ b/src/phoenix/config.py @@ -3,6 +3,8 @@ from pathlib import Path from typing import List, Optional +from phoenix.core.project import DEFAULT_PROJECT_NAME + # Phoenix environment variables ENV_PHOENIX_PORT = "PHOENIX_PORT" ENV_PHOENIX_HOST = "PHOENIX_HOST" @@ -17,6 +19,10 @@ The directory in which to save, load, and export datasets. This directory must be accessible by both the Phoenix server and the notebook environment. """ +ENV_PHOENIX_PROJECT_NAME = "PHOENIX_PROJECT_NAME" +""" +The project name to use when logging traces and evals. defaults to 'default'. +""" def _get_temp_path() -> Path: @@ -113,3 +119,7 @@ def get_env_host() -> str: def get_env_collector_endpoint() -> Optional[str]: return os.getenv(ENV_PHOENIX_COLLECTOR_ENDPOINT) + + +def get_env_project_name() -> str: + return os.getenv(ENV_PHOENIX_PROJECT_NAME) or DEFAULT_PROJECT_NAME diff --git a/src/phoenix/session/client.py b/src/phoenix/session/client.py index eec35ccd4d..72c71507cf 100644 --- a/src/phoenix/session/client.py +++ b/src/phoenix/session/client.py @@ -11,7 +11,12 @@ from requests import Session import phoenix as px -from phoenix.config import get_env_collector_endpoint, get_env_host, get_env_port +from phoenix.config import ( + get_env_collector_endpoint, + get_env_host, + get_env_port, + get_env_project_name, +) from phoenix.session.data_extractor import TraceDataExtractor from phoenix.trace import Evaluations from phoenix.trace.dsl import SpanQuery @@ -59,6 +64,7 @@ def query_spans( root_spans_only: Optional[bool] = None, project_name: Optional[str] = None, ) -> Optional[Union[pd.DataFrame, List[pd.DataFrame]]]: + project_name = project_name or get_env_project_name() if not queries: queries = (SpanQuery(),) if self._use_active_session_if_available and (session := px.active_session()): @@ -102,6 +108,7 @@ def get_evaluations( self, project_name: Optional[str] = None, ) -> List[Evaluations]: + project_name = project_name or get_env_project_name() if self._use_active_session_if_available and (session := px.active_session()): return session.get_evaluations(project_name=project_name) response = self._session.get( diff --git a/src/phoenix/session/session.py b/src/phoenix/session/session.py index 268b0574e8..16a6ddea0e 100644 --- a/src/phoenix/session/session.py +++ b/src/phoenix/session/session.py @@ -26,10 +26,10 @@ ENV_PHOENIX_COLLECTOR_ENDPOINT, get_env_host, get_env_port, + get_env_project_name, get_exported_files, ) from phoenix.core.model_schema_adapter import create_model_from_datasets -from phoenix.core.project import DEFAULT_PROJECT_NAME from phoenix.core.traces import Traces from phoenix.datasets.dataset import EMPTY_DATASET, Dataset from phoenix.pointcloud.umap_parameters import get_umap_parameters @@ -331,8 +331,25 @@ def query_spans( root_spans_only: Optional[bool] = None, project_name: Optional[str] = None, ) -> Optional[Union[pd.DataFrame, List[pd.DataFrame]]]: + """ + Queries the spans in the project based on the provided parameters. + + Args: + queries: Variable-length argument list of SpanQuery objects + representing the queries to be executed. start_time: Optional + datetime object representing the start time of the query. stop_time: + Optional datetime object representing the stop time of the query. + root_spans_only: Optional boolean indicating whether to include only + root spans in the results. project_name: Optional string + representing the name of the project to query. Defaults to the project name + set in the environment variable `PHOENIX_PROJECT_NAME` or 'default' if not set. + + Returns: + Optional pandas DataFrame or list of DataFrames containing the query + results. + """ if not (traces := self.traces) or not ( - project := traces.get_project(project_name or DEFAULT_PROJECT_NAME) + project := traces.get_project(project_name or get_env_project_name()) ): return None if not queries: @@ -362,9 +379,20 @@ def get_evaluations( self, project_name: Optional[str] = None, ) -> List[Evaluations]: - if not (traces := self.traces) or not ( - project := traces.get_project(project_name or DEFAULT_PROJECT_NAME) - ): + """ + Get the evaluations for a project. + + Args: + project_name (str, optional): The name of the project. If not + provided, the project name set in the environment variable + `PHOENIX_PROJECT_NAME` will be used. Otherwise, 'default' will be used. + + Returns: + List[Evaluations]: A list of evaluations for the specified project. + + """ + project_name = project_name or get_env_project_name() + if not (traces := self.traces) or not (project := traces.get_project(project_name)): return [] return project.export_evaluations() diff --git a/src/phoenix/trace/langchain/instrumentor.py b/src/phoenix/trace/langchain/instrumentor.py index 9ac35f332a..bccf9b8139 100644 --- a/src/phoenix/trace/langchain/instrumentor.py +++ b/src/phoenix/trace/langchain/instrumentor.py @@ -4,9 +4,12 @@ from typing import Any from openinference.instrumentation.langchain import LangChainInstrumentor as Instrumentor +from openinference.semconv.resource import ResourceAttributes from opentelemetry.sdk import trace as trace_sdk +from opentelemetry.sdk.resources import Resource from opentelemetry.sdk.trace.export import SimpleSpanProcessor +from phoenix.config import get_env_project_name from phoenix.trace.exporter import _OpenInferenceExporter from phoenix.trace.tracer import _show_deprecation_warnings @@ -26,6 +29,8 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__() def instrument(self) -> None: - tracer_provider = trace_sdk.TracerProvider() + tracer_provider = trace_sdk.TracerProvider( + resource=Resource({ResourceAttributes.PROJECT_NAME: get_env_project_name()}) + ) tracer_provider.add_span_processor(SimpleSpanProcessor(_OpenInferenceExporter())) super().instrument(skip_dep_check=True, tracer_provider=tracer_provider) diff --git a/src/phoenix/trace/llama_index/callback.py b/src/phoenix/trace/llama_index/callback.py index c71c9c62ab..6c834a9d46 100644 --- a/src/phoenix/trace/llama_index/callback.py +++ b/src/phoenix/trace/llama_index/callback.py @@ -3,10 +3,13 @@ from importlib.util import find_spec from typing import Any +from openinference.semconv.resource import ResourceAttributes from opentelemetry import trace as trace_api from opentelemetry.sdk import trace as trace_sdk +from opentelemetry.sdk.resources import Resource from opentelemetry.sdk.trace.export import SimpleSpanProcessor +from phoenix.config import get_env_project_name from phoenix.trace.errors import IncompatibleLibraryVersionError from phoenix.trace.exporter import _OpenInferenceExporter from phoenix.trace.tracer import _show_deprecation_warnings @@ -72,6 +75,8 @@ class OpenInferenceTraceCallbackHandler(_OpenInferenceTraceCallbackHandler): def __init__(self, *args: Any, **kwargs: Any) -> None: _show_deprecation_warnings(self, *args, **kwargs) - tracer_provider = trace_sdk.TracerProvider() + tracer_provider = trace_sdk.TracerProvider( + resource=Resource({ResourceAttributes.PROJECT_NAME: get_env_project_name()}) + ) tracer_provider.add_span_processor(SimpleSpanProcessor(_OpenInferenceExporter())) super().__init__(trace_api.get_tracer(__name__, __version__, tracer_provider)) diff --git a/src/phoenix/trace/openai/instrumentor.py b/src/phoenix/trace/openai/instrumentor.py index b38b1e7724..13716c2ef2 100644 --- a/src/phoenix/trace/openai/instrumentor.py +++ b/src/phoenix/trace/openai/instrumentor.py @@ -4,9 +4,12 @@ from typing import Any from openinference.instrumentation.openai import OpenAIInstrumentor as Instrumentor +from openinference.semconv.resource import ResourceAttributes from opentelemetry.sdk import trace as trace_sdk +from opentelemetry.sdk.resources import Resource from opentelemetry.sdk.trace.export import SimpleSpanProcessor +from phoenix.config import get_env_project_name from phoenix.trace.exporter import _OpenInferenceExporter from phoenix.trace.tracer import _show_deprecation_warnings @@ -21,6 +24,8 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__() def instrument(self) -> None: - tracer_provider = trace_sdk.TracerProvider() + tracer_provider = trace_sdk.TracerProvider( + resource=Resource({ResourceAttributes.PROJECT_NAME: get_env_project_name()}) + ) tracer_provider.add_span_processor(SimpleSpanProcessor(_OpenInferenceExporter())) super().instrument(skip_dep_check=True, tracer_provider=tracer_provider) From 2b5e3e8027a9caf0bd90b71ea82690ca2ab77189 Mon Sep 17 00:00:00 2001 From: Mikyo King Date: Fri, 8 Mar 2024 17:42:03 -0700 Subject: [PATCH 2/4] remove circular deps --- src/phoenix/config.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/phoenix/config.py b/src/phoenix/config.py index 320c449664..9e5cf2a89b 100644 --- a/src/phoenix/config.py +++ b/src/phoenix/config.py @@ -3,8 +3,6 @@ from pathlib import Path from typing import List, Optional -from phoenix.core.project import DEFAULT_PROJECT_NAME - # Phoenix environment variables ENV_PHOENIX_PORT = "PHOENIX_PORT" ENV_PHOENIX_HOST = "PHOENIX_HOST" @@ -122,4 +120,4 @@ def get_env_collector_endpoint() -> Optional[str]: def get_env_project_name() -> str: - return os.getenv(ENV_PHOENIX_PROJECT_NAME) or DEFAULT_PROJECT_NAME + return os.getenv(ENV_PHOENIX_PROJECT_NAME) or "config" From 18ca991a6e2c353c4cfdd99a850529c7b35c0a42 Mon Sep 17 00:00:00 2001 From: Mikyo King Date: Fri, 8 Mar 2024 20:00:49 -0700 Subject: [PATCH 3/4] fix docsctrings --- src/phoenix/config.py | 2 +- src/phoenix/session/session.py | 47 ++++++++++++++++++++++------------ 2 files changed, 31 insertions(+), 18 deletions(-) diff --git a/src/phoenix/config.py b/src/phoenix/config.py index 9e5cf2a89b..f091c387f6 100644 --- a/src/phoenix/config.py +++ b/src/phoenix/config.py @@ -120,4 +120,4 @@ def get_env_collector_endpoint() -> Optional[str]: def get_env_project_name() -> str: - return os.getenv(ENV_PHOENIX_PROJECT_NAME) or "config" + return os.getenv(ENV_PHOENIX_PROJECT_NAME) or "default" diff --git a/src/phoenix/session/session.py b/src/phoenix/session/session.py index 16a6ddea0e..b8379d2462 100644 --- a/src/phoenix/session/session.py +++ b/src/phoenix/session/session.py @@ -334,19 +334,28 @@ def query_spans( """ Queries the spans in the project based on the provided parameters. - Args: - queries: Variable-length argument list of SpanQuery objects - representing the queries to be executed. start_time: Optional - datetime object representing the start time of the query. stop_time: - Optional datetime object representing the stop time of the query. - root_spans_only: Optional boolean indicating whether to include only - root spans in the results. project_name: Optional string - representing the name of the project to query. Defaults to the project name - set in the environment variable `PHOENIX_PROJECT_NAME` or 'default' if not set. + Parameters + ---------- + queries : *SpanQuery + Variable-length argument list of SpanQuery objects representing + the queries to be executed. + + start_time : datetime, optional + datetime representing the start time of the query. + + stop_time : datetime, optional + datetime representing the stop time of the query. + + root_spans_only : boolean, optional + whether to include only root spans in the results. + + project_name : (string, optional) + name of the project to query. Defaults to the project name set + in the environment variable `PHOENIX_PROJECT_NAME` or 'default' if not set. Returns: - Optional pandas DataFrame or list of DataFrames containing the query - results. + results : DataFrame + DataFrame or list of DataFrames containing the query results. """ if not (traces := self.traces) or not ( project := traces.get_project(project_name or get_env_project_name()) @@ -382,13 +391,17 @@ def get_evaluations( """ Get the evaluations for a project. - Args: - project_name (str, optional): The name of the project. If not - provided, the project name set in the environment variable - `PHOENIX_PROJECT_NAME` will be used. Otherwise, 'default' will be used. + Parameters + ---------- + project_name : str, optional + The name of the project. If not provided, the project name set + in the environment variable `PHOENIX_PROJECT_NAME` will be used. + Otherwise, 'default' will be used. - Returns: - List[Evaluations]: A list of evaluations for the specified project. + Returns + ------- + evaluations : List[Evaluations] + A list of evaluations for the specified project. """ project_name = project_name or get_env_project_name() From b6d3ed6291aa544484a2fdf3459010547887afd8 Mon Sep 17 00:00:00 2001 From: Mikyo King Date: Fri, 8 Mar 2024 20:05:32 -0700 Subject: [PATCH 4/4] fix string --- src/phoenix/session/session.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/phoenix/session/session.py b/src/phoenix/session/session.py index b8379d2462..d021f340cb 100644 --- a/src/phoenix/session/session.py +++ b/src/phoenix/session/session.py @@ -349,7 +349,7 @@ def query_spans( root_spans_only : boolean, optional whether to include only root spans in the results. - project_name : (string, optional) + project_name : string, optional name of the project to query. Defaults to the project name set in the environment variable `PHOENIX_PROJECT_NAME` or 'default' if not set.