From b2e7773223020a92b8843c8abbac8356d2ce331f Mon Sep 17 00:00:00 2001 From: Karthik Kalyanaraman <105607645+karthikscale3@users.noreply.github.com> Date: Thu, 10 Oct 2024 13:24:07 -0700 Subject: [PATCH 1/3] Fix missing instrumentation types (#377) * add instrumentation types * bump version * fix --- src/langtrace_python_sdk/types/__init__.py | 36 +++++++++++++--------- src/langtrace_python_sdk/version.py | 2 +- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/src/langtrace_python_sdk/types/__init__.py b/src/langtrace_python_sdk/types/__init__.py index 3173efae..0ee5b250 100644 --- a/src/langtrace_python_sdk/types/__init__.py +++ b/src/langtrace_python_sdk/types/__init__.py @@ -3,27 +3,33 @@ class InstrumentationType(Enum): - OPENAI = "openai" - COHERE = "cohere" ANTHROPIC = "anthropic" - GROQ = "groq" - MISTRAL = "mistral" - PINECONE = "pinecone-client" - LLAMAINDEX = "llama-index" + AUTOGEN = "autogen" CHROMADB = "chromadb" - QDRANT = "qdrant" + COHERE = "cohere" + CREW_AI = "crewai" + CREWAI = "crewai" + DSPY = "dspy-ai" + EMBEDCHAIN = "embedchain" + GEMINI = "google-generativeai" + GOOGLE_CLOUD_AI_PLATFORM = "google-cloud-aiplatform" + GOOGLE_GENERATIVEAI = "google-generativeai" + GROQ = "groq" LANGCHAIN = "langchain" - LANGCHAIN_CORE = "langchain-core" LANGCHAIN_COMMUNITY = "langchain-community" + LANGCHAIN_CORE = "langchain-core" LANGGRAPH = "langgraph" - WEAVIATE = "weaviate" - OLLAMA = "ollama" - AUTOGEN = "autogen" - DSPY = "dspy-ai" - CREWAI = "crewai" - GEMINI = "google-generativeai" - VERTEXAI = "google-cloud-aiplatform" + LITELLM = "litellm" + LLAMAINDEX = "llama-index" + MISTRAL = "mistral" MISTRALAI = "mistralai" + OLLAMA = "ollama" + OPENAI = "openai" + PINECONE = "pinecone-client" + QDRANT = "qdrant" + SQLALCHEMY = "sqlalchemy" + VERTEXAI = "vertexai" + WEAVIATE = "weaviate" @staticmethod def from_string(value: str): diff --git a/src/langtrace_python_sdk/version.py b/src/langtrace_python_sdk/version.py index 05527687..131942e7 100644 --- a/src/langtrace_python_sdk/version.py +++ b/src/langtrace_python_sdk/version.py @@ -1 +1 @@ -__version__ = "3.0.1" +__version__ = "3.0.2" From 0b8defc4ef651000dca75e5cff9359851a3f748e Mon Sep 17 00:00:00 2001 From: Ali Waleed Date: Wed, 16 Oct 2024 20:14:44 +0300 Subject: [PATCH 2/3] Migrate to `oTel` exporters (#381) * migrate to otel exporters + litellm example * bump version * abstract exporter headers and `service_name` --- src/examples/litellm_example/basic.py | 6 +- src/examples/litellm_example/config.yaml | 10 +++ src/examples/litellm_example/proxy_basic.py | 16 +++++ src/langtrace_python_sdk/langtrace.py | 69 +++++++++++++++++---- src/langtrace_python_sdk/version.py | 2 +- 5 files changed, 86 insertions(+), 17 deletions(-) create mode 100644 src/examples/litellm_example/config.yaml create mode 100644 src/examples/litellm_example/proxy_basic.py diff --git a/src/examples/litellm_example/basic.py b/src/examples/litellm_example/basic.py index 9131c1a0..2a711b51 100644 --- a/src/examples/litellm_example/basic.py +++ b/src/examples/litellm_example/basic.py @@ -1,4 +1,3 @@ -from langtrace_python_sdk import with_langtrace_root_span, langtrace from dotenv import load_dotenv from litellm import completion, acompletion import litellm @@ -8,11 +7,9 @@ litellm.success_callback = ["langtrace"] -langtrace.init() litellm.set_verbose = False -@with_langtrace_root_span("Litellm Example OpenAI") def openAI(streaming=False): response = completion( model="gpt-3.5-turbo", @@ -56,7 +53,6 @@ def anthropic(streaming=False): print("ERORRRR", e) -# @with_langtrace_root_span("Litellm Example OpenAI Async Streaming") async def async_anthropic(streaming=False): response = await acompletion( model="claude-2.1", @@ -93,6 +89,6 @@ def cohere(streaming=False): if __name__ == "__main__": # openAI() - anthropic(streaming=False) + # anthropic(streaming=False) cohere(streaming=True) # asyncio.run(async_anthropic(streaming=True)) diff --git a/src/examples/litellm_example/config.yaml b/src/examples/litellm_example/config.yaml new file mode 100644 index 00000000..a83f4c29 --- /dev/null +++ b/src/examples/litellm_example/config.yaml @@ -0,0 +1,10 @@ +model_list: + - model_name: "gpt-4" # all requests where model not in your config go to this deployment + litellm_params: + model: openai/gpt-4 # set `openai/` to use the openai route + +litellm_settings: + success_callback: ["langtrace"] + +environment_variables: + LANGTRACE_API_KEY: "fake-api-key" diff --git a/src/examples/litellm_example/proxy_basic.py b/src/examples/litellm_example/proxy_basic.py new file mode 100644 index 00000000..97a3920f --- /dev/null +++ b/src/examples/litellm_example/proxy_basic.py @@ -0,0 +1,16 @@ +import openai +from dotenv import load_dotenv + +load_dotenv() + +client = openai.OpenAI(base_url="http://0.0.0.0:4000") + +# request sent to model set on litellm proxy, `litellm --model` +response = client.chat.completions.create( + model="gpt-4", + messages=[ + {"role": "user", "content": "this is a test request, write a short poem"} + ], +) + +print(response) diff --git a/src/langtrace_python_sdk/langtrace.py b/src/langtrace_python_sdk/langtrace.py index 6ca027a4..210c349a 100644 --- a/src/langtrace_python_sdk/langtrace.py +++ b/src/langtrace_python_sdk/langtrace.py @@ -31,10 +31,15 @@ SimpleSpanProcessor, ) +from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import ( + OTLPSpanExporter as GRPCExporter, +) +from opentelemetry.exporter.otlp.proto.http.trace_exporter import ( + OTLPSpanExporter as HTTPExporter, +) from langtrace_python_sdk.constants.exporter.langtrace_exporter import ( LANGTRACE_REMOTE_URL, ) -from langtrace_python_sdk.extensions.langtrace_exporter import LangTraceExporter from langtrace_python_sdk.instrumentation import ( AnthropicInstrumentation, ChromaInstrumentation, @@ -59,6 +64,8 @@ VertexAIInstrumentation, WeaviateInstrumentation, ) +from opentelemetry.util.re import parse_env_headers + from langtrace_python_sdk.types import DisableInstrumentations, InstrumentationMethods from langtrace_python_sdk.utils import ( check_if_sdk_is_outdated, @@ -74,7 +81,7 @@ class LangtraceConfig: def __init__(self, **kwargs): - self.api_key = kwargs.get("api_key") + self.api_key = kwargs.get("api_key") or os.environ.get("LANGTRACE_API_KEY") self.batch = kwargs.get("batch", True) self.write_spans_to_console = kwargs.get("write_spans_to_console", False) self.custom_remote_exporter = kwargs.get("custom_remote_exporter") @@ -83,7 +90,11 @@ def __init__(self, **kwargs): self.disable_tracing_for_functions = kwargs.get("disable_tracing_for_functions") self.service_name = kwargs.get("service_name") self.disable_logging = kwargs.get("disable_logging", False) - self.headers = kwargs.get("headers", {}) + self.headers = ( + kwargs.get("headers") + or os.environ.get("LANGTRACE_HEADERS") + or os.environ.get("OTEL_EXPORTER_OTLP_HEADERS") + ) def get_host(config: LangtraceConfig) -> str: @@ -96,23 +107,50 @@ def get_host(config: LangtraceConfig) -> str: ) +def get_service_name(config: LangtraceConfig): + service_name = os.environ.get("OTEL_SERVICE_NAME") + if service_name: + return service_name + + resource_attributes = os.environ.get("OTEL_RESOURCE_ATTRIBUTES") + if resource_attributes: + attrs = dict(attr.split("=") for attr in resource_attributes.split(",")) + if "service.name" in attrs: + return attrs["service.name"] + + if config.service_name: + return config.service_name + + return sys.argv[0] + + def setup_tracer_provider(config: LangtraceConfig, host: str) -> TracerProvider: sampler = LangtraceSampler(disabled_methods=config.disable_tracing_for_functions) - resource = Resource.create( - attributes={ - SERVICE_NAME: os.environ.get("OTEL_SERVICE_NAME") - or config.service_name - or sys.argv[0] - } - ) + resource = Resource.create(attributes={SERVICE_NAME: get_service_name(config)}) return TracerProvider(resource=resource, sampler=sampler) +def get_headers(config: LangtraceConfig): + if not config.headers: + return { + "x-api-key": config.api_key, + } + + if isinstance(config.headers, str): + return parse_env_headers(config.headers, liberal=True) + + return config.headers + + def get_exporter(config: LangtraceConfig, host: str): if config.custom_remote_exporter: return config.custom_remote_exporter - return LangTraceExporter(host, config.api_key, config.disable_logging) + headers = get_headers(config) + if "http" in host.lower() or "https" in host.lower(): + return HTTPExporter(endpoint=host, headers=headers) + else: + return GRPCExporter(endpoint=host, headers=headers) def add_span_processor(provider: TracerProvider, config: LangtraceConfig, exporter): @@ -200,6 +238,15 @@ def init( + Fore.RESET ) + if host == LANGTRACE_REMOTE_URL and not config.api_key: + print(Fore.RED) + print( + "Missing Langtrace API key, proceed to https://langtrace.ai to create one" + ) + print("Set the API key as an environment variable LANGTRACE_API_KEY") + print(Fore.RESET) + return + provider = setup_tracer_provider(config, host) exporter = get_exporter(config, host) diff --git a/src/langtrace_python_sdk/version.py b/src/langtrace_python_sdk/version.py index 131942e7..f5f41e56 100644 --- a/src/langtrace_python_sdk/version.py +++ b/src/langtrace_python_sdk/version.py @@ -1 +1 @@ -__version__ = "3.0.2" +__version__ = "3.1.0" From 13b8055afd2d43a98f09d490328e57352ebb5514 Mon Sep 17 00:00:00 2001 From: Ali Waleed Date: Thu, 17 Oct 2024 16:02:35 +0300 Subject: [PATCH 3/3] append `api/trace` if sending to langtrace cloud --- src/langtrace_python_sdk/langtrace.py | 1 + src/langtrace_python_sdk/version.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/langtrace_python_sdk/langtrace.py b/src/langtrace_python_sdk/langtrace.py index 210c349a..94749621 100644 --- a/src/langtrace_python_sdk/langtrace.py +++ b/src/langtrace_python_sdk/langtrace.py @@ -147,6 +147,7 @@ def get_exporter(config: LangtraceConfig, host: str): return config.custom_remote_exporter headers = get_headers(config) + host = f"{host}/api/trace" if host == LANGTRACE_REMOTE_URL else host if "http" in host.lower() or "https" in host.lower(): return HTTPExporter(endpoint=host, headers=headers) else: diff --git a/src/langtrace_python_sdk/version.py b/src/langtrace_python_sdk/version.py index f5f41e56..d539d50c 100644 --- a/src/langtrace_python_sdk/version.py +++ b/src/langtrace_python_sdk/version.py @@ -1 +1 @@ -__version__ = "3.1.0" +__version__ = "3.1.1"