langtrace-python-sdk 3.3.22__py3-none-any.whl → 3.3.23__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.
- examples/gemini_example/main.py +3 -3
- examples/google_genai_example/__init__.py +7 -0
- examples/google_genai_example/main.py +27 -0
- langtrace_python_sdk/instrumentation/__init__.py +2 -0
- langtrace_python_sdk/instrumentation/google_genai/__init__.py +3 -0
- langtrace_python_sdk/instrumentation/google_genai/instrumentation.py +30 -0
- langtrace_python_sdk/instrumentation/google_genai/patch.py +126 -0
- langtrace_python_sdk/langtrace.py +2 -0
- langtrace_python_sdk/version.py +1 -1
- {langtrace_python_sdk-3.3.22.dist-info → langtrace_python_sdk-3.3.23.dist-info}/METADATA +1 -1
- {langtrace_python_sdk-3.3.22.dist-info → langtrace_python_sdk-3.3.23.dist-info}/RECORD +14 -9
- {langtrace_python_sdk-3.3.22.dist-info → langtrace_python_sdk-3.3.23.dist-info}/WHEEL +0 -0
- {langtrace_python_sdk-3.3.22.dist-info → langtrace_python_sdk-3.3.23.dist-info}/entry_points.txt +0 -0
- {langtrace_python_sdk-3.3.22.dist-info → langtrace_python_sdk-3.3.23.dist-info}/licenses/LICENSE +0 -0
examples/gemini_example/main.py
CHANGED
@@ -20,16 +20,16 @@ async def async_demo():
|
|
20
20
|
|
21
21
|
def basic():
|
22
22
|
generate()
|
23
|
-
generate(stream=True, with_tools=True)
|
23
|
+
# generate(stream=True, with_tools=True)
|
24
24
|
|
25
25
|
# image_to_text()
|
26
26
|
# audio_to_text()
|
27
|
-
asyncio.run(async_demo())
|
27
|
+
# asyncio.run(async_demo())
|
28
28
|
|
29
29
|
|
30
30
|
def generate(stream=False, with_tools=False):
|
31
31
|
model = genai.GenerativeModel(
|
32
|
-
"gemini-
|
32
|
+
"gemini-2.0-flash-exp", system_instruction="You are a cat. Your name is Neko."
|
33
33
|
)
|
34
34
|
|
35
35
|
response = model.generate_content(
|
@@ -0,0 +1,27 @@
|
|
1
|
+
from google import genai
|
2
|
+
from dotenv import load_dotenv
|
3
|
+
import os
|
4
|
+
from langtrace_python_sdk import langtrace
|
5
|
+
|
6
|
+
load_dotenv()
|
7
|
+
langtrace.init(write_spans_to_console=False)
|
8
|
+
|
9
|
+
|
10
|
+
def generate_content():
|
11
|
+
# Only run this block for Google AI API
|
12
|
+
client = genai.Client(api_key=os.getenv("GEMINI_API_KEY"))
|
13
|
+
response = client.models.generate_content(
|
14
|
+
model="gemini-2.0-flash-exp", contents="What is your name?"
|
15
|
+
)
|
16
|
+
|
17
|
+
print(response.text)
|
18
|
+
|
19
|
+
|
20
|
+
def generate_content_streaming():
|
21
|
+
client = genai.Client(api_key=os.getenv("GEMINI_API_KEY"))
|
22
|
+
response = client.models.generate_content_stream(
|
23
|
+
model="gemini-2.0-flash-exp", contents="What is your name?"
|
24
|
+
)
|
25
|
+
|
26
|
+
for chunk in response:
|
27
|
+
pass
|
@@ -24,6 +24,7 @@ from .litellm import LiteLLMInstrumentation
|
|
24
24
|
from .pymongo import PyMongoInstrumentation
|
25
25
|
from .cerebras import CerebrasInstrumentation
|
26
26
|
from .milvus import MilvusInstrumentation
|
27
|
+
from .google_genai import GoogleGenaiInstrumentation
|
27
28
|
|
28
29
|
__all__ = [
|
29
30
|
"AnthropicInstrumentation",
|
@@ -52,4 +53,5 @@ __all__ = [
|
|
52
53
|
"AWSBedrockInstrumentation",
|
53
54
|
"CerebrasInstrumentation",
|
54
55
|
"MilvusInstrumentation",
|
56
|
+
"GoogleGenaiInstrumentation",
|
55
57
|
]
|
@@ -0,0 +1,30 @@
|
|
1
|
+
from typing import Collection
|
2
|
+
from importlib_metadata import version as v
|
3
|
+
from wrapt import wrap_function_wrapper as _W
|
4
|
+
from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
|
5
|
+
from opentelemetry.trace import get_tracer
|
6
|
+
from .patch import patch_google_genai, patch_google_genai_streaming
|
7
|
+
|
8
|
+
|
9
|
+
class GoogleGenaiInstrumentation(BaseInstrumentor):
|
10
|
+
def instrumentation_dependencies(self) -> Collection[str]:
|
11
|
+
return ["google-genai >= 0.1.0", "google-generativeai < 1.0.0"]
|
12
|
+
|
13
|
+
def _instrument(self, **kwargs):
|
14
|
+
trace_provider = kwargs.get("tracer_provider")
|
15
|
+
tracer = get_tracer(__name__, "", trace_provider)
|
16
|
+
version = v("google-genai")
|
17
|
+
|
18
|
+
_W(
|
19
|
+
module="google.genai",
|
20
|
+
name="models.Models.generate_content",
|
21
|
+
wrapper=patch_google_genai(tracer, version),
|
22
|
+
)
|
23
|
+
_W(
|
24
|
+
module="google.genai",
|
25
|
+
name="models.Models.generate_content_stream",
|
26
|
+
wrapper=patch_google_genai_streaming(tracer, version),
|
27
|
+
)
|
28
|
+
|
29
|
+
def _uninstrument(self, **kwargs):
|
30
|
+
pass
|
@@ -0,0 +1,126 @@
|
|
1
|
+
from langtrace_python_sdk.utils.llm import (
|
2
|
+
get_langtrace_attributes,
|
3
|
+
get_llm_request_attributes,
|
4
|
+
set_span_attributes,
|
5
|
+
set_usage_attributes,
|
6
|
+
set_span_attribute,
|
7
|
+
set_event_completion,
|
8
|
+
)
|
9
|
+
from langtrace_python_sdk.utils import handle_span_error
|
10
|
+
|
11
|
+
from opentelemetry.trace import Tracer, SpanKind
|
12
|
+
from opentelemetry.sdk.trace import Span
|
13
|
+
from langtrace.trace_attributes import SpanAttributes
|
14
|
+
|
15
|
+
from typing import Iterator
|
16
|
+
|
17
|
+
|
18
|
+
def patch_google_genai(tracer: Tracer, version: str):
|
19
|
+
def traced_method(wrapped, instance, args, kwargs):
|
20
|
+
prompt = [
|
21
|
+
{
|
22
|
+
"role": "user",
|
23
|
+
"content": kwargs["contents"],
|
24
|
+
}
|
25
|
+
]
|
26
|
+
span_attributes = {
|
27
|
+
**get_langtrace_attributes(
|
28
|
+
service_provider="google_genai", version=version
|
29
|
+
),
|
30
|
+
**get_llm_request_attributes(kwargs=kwargs, prompts=prompt),
|
31
|
+
}
|
32
|
+
with tracer.start_as_current_span(
|
33
|
+
name="google.genai.generate_content",
|
34
|
+
kind=SpanKind.CLIENT,
|
35
|
+
) as span:
|
36
|
+
try:
|
37
|
+
set_span_attributes(span, span_attributes)
|
38
|
+
response = wrapped(*args, **kwargs)
|
39
|
+
set_response_attributes(span, response)
|
40
|
+
return response
|
41
|
+
except Exception as error:
|
42
|
+
handle_span_error(span, error)
|
43
|
+
raise
|
44
|
+
|
45
|
+
return traced_method
|
46
|
+
|
47
|
+
|
48
|
+
def patch_google_genai_streaming(tracer: Tracer, version: str):
|
49
|
+
def traced_method(wrapped, instance, args, kwargs):
|
50
|
+
prompt = [
|
51
|
+
{
|
52
|
+
"role": "user",
|
53
|
+
"content": kwargs["contents"],
|
54
|
+
}
|
55
|
+
]
|
56
|
+
span_attributes = {
|
57
|
+
**get_langtrace_attributes(
|
58
|
+
service_provider="google_genai", version=version
|
59
|
+
),
|
60
|
+
**get_llm_request_attributes(kwargs=kwargs, prompts=prompt),
|
61
|
+
}
|
62
|
+
with tracer.start_as_current_span(
|
63
|
+
name="google.genai.generate_content_stream",
|
64
|
+
kind=SpanKind.CLIENT,
|
65
|
+
) as span:
|
66
|
+
set_span_attributes(span, span_attributes)
|
67
|
+
response = wrapped(*args, **kwargs)
|
68
|
+
set_streaming_response_attributes(span, response)
|
69
|
+
return response
|
70
|
+
|
71
|
+
return traced_method
|
72
|
+
|
73
|
+
|
74
|
+
def set_streaming_response_attributes(span: Span, response):
|
75
|
+
accum_completion = ""
|
76
|
+
for chunk in response:
|
77
|
+
set_span_attribute(
|
78
|
+
span,
|
79
|
+
SpanAttributes.LLM_RESPONSE_MODEL,
|
80
|
+
chunk.model_version,
|
81
|
+
)
|
82
|
+
candidates = chunk.candidates
|
83
|
+
for candidate in candidates:
|
84
|
+
set_span_attribute(
|
85
|
+
span,
|
86
|
+
SpanAttributes.LLM_RESPONSE_FINISH_REASON,
|
87
|
+
candidate.finish_reason,
|
88
|
+
)
|
89
|
+
|
90
|
+
accum_completion += candidate.content.parts[0].text
|
91
|
+
|
92
|
+
if chunk.usage_metadata:
|
93
|
+
set_usage_attributes(
|
94
|
+
span,
|
95
|
+
{
|
96
|
+
"input_tokens": chunk.usage_metadata.prompt_token_count,
|
97
|
+
"output_tokens": chunk.usage_metadata.candidates_token_count,
|
98
|
+
},
|
99
|
+
)
|
100
|
+
set_event_completion(span, [{"role": "assistant", "content": accum_completion}])
|
101
|
+
|
102
|
+
|
103
|
+
def set_response_attributes(span: Span, response):
|
104
|
+
completions = []
|
105
|
+
for candidate in response.candidates:
|
106
|
+
set_span_attribute(
|
107
|
+
span, SpanAttributes.LLM_RESPONSE_FINISH_REASON, candidate.finish_reason
|
108
|
+
)
|
109
|
+
parts = candidate.content.parts
|
110
|
+
role = candidate.content.role
|
111
|
+
completion = {
|
112
|
+
"role": role or "assistant",
|
113
|
+
"content": [part.text for part in parts],
|
114
|
+
}
|
115
|
+
completions.append(completion)
|
116
|
+
|
117
|
+
set_span_attribute(span, SpanAttributes.LLM_RESPONSE_MODEL, response.model_version)
|
118
|
+
set_event_completion(span, completions)
|
119
|
+
if response.usage_metadata:
|
120
|
+
set_usage_attributes(
|
121
|
+
span,
|
122
|
+
{
|
123
|
+
"input_tokens": response.usage_metadata.prompt_token_count,
|
124
|
+
"output_tokens": response.usage_metadata.candidates_token_count,
|
125
|
+
},
|
126
|
+
)
|
@@ -68,6 +68,7 @@ from langtrace_python_sdk.instrumentation import (
|
|
68
68
|
PyMongoInstrumentation,
|
69
69
|
CerebrasInstrumentation,
|
70
70
|
MilvusInstrumentation,
|
71
|
+
GoogleGenaiInstrumentation,
|
71
72
|
)
|
72
73
|
from opentelemetry.util.re import parse_env_headers
|
73
74
|
|
@@ -301,6 +302,7 @@ def init(
|
|
301
302
|
"vertexai": VertexAIInstrumentation(),
|
302
303
|
"google-cloud-aiplatform": VertexAIInstrumentation(),
|
303
304
|
"google-generativeai": GeminiInstrumentation(),
|
305
|
+
"google-genai": GoogleGenaiInstrumentation(),
|
304
306
|
"mistralai": MistralInstrumentation(),
|
305
307
|
"boto3": AWSBedrockInstrumentation(),
|
306
308
|
"autogen": AutogenInstrumentation(),
|
langtrace_python_sdk/version.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
__version__ = "3.3.
|
1
|
+
__version__ = "3.3.23"
|
@@ -53,7 +53,9 @@ examples/fastapi_example/__init__.py,sha256=INIfvJP7zC_KkJCtulS1qbh61-MJTPAHnzAg
|
|
53
53
|
examples/fastapi_example/basic_route.py,sha256=_IRXjkOtJQ-bTIGa1WbvUF_2LF4bjghjyXt4YrHaRvw,1170
|
54
54
|
examples/gemini_example/__init__.py,sha256=omVgLyIiLc3c0zwy3vTtYKdeenYEXzEbLZsYiPEvJT4,81
|
55
55
|
examples/gemini_example/function_tools.py,sha256=ZOBrdPy_8s3NDfsF5A4RXIoUi2VXlD8og4UsWz_8AuQ,2700
|
56
|
-
examples/gemini_example/main.py,sha256=
|
56
|
+
examples/gemini_example/main.py,sha256=issqP-0ofP2NzscXuT4ZoD9TemAyTt04o_EhhIrUo7g,2480
|
57
|
+
examples/google_genai_example/__init__.py,sha256=k2Hp4asgvKzrKV_E8sJ-_TDxCvP7aLXZdV-dxVUJKwo,175
|
58
|
+
examples/google_genai_example/main.py,sha256=DcEom8iqlTRFZhDxGEpBNs5GZDOHiZkVakSBM2bwcx4,717
|
57
59
|
examples/hiveagent_example/basic.py,sha256=Sd7I5w8w5Xx7ODaydTY30yiq9HwJDMKHQywrZjgehP0,441
|
58
60
|
examples/inspect_ai_example/basic_eval.py,sha256=hDg2BB9ONNpOGRVH08HsghnS1373sOnq6dyDmUQd9gY,1040
|
59
61
|
examples/langchain_example/__init__.py,sha256=hYsiJzR050yCwip4-KZD9EhSLeBMeOUU1eQzyXSfwRs,669
|
@@ -108,8 +110,8 @@ examples/vertexai_example/main.py,sha256=gndId5X5ksD-ycxnAWMdEqIDbLc3kz5Vt8vm4YP
|
|
108
110
|
examples/weaviate_example/__init__.py,sha256=8JMDBsRSEV10HfTd-YC7xb4txBjD3la56snk-Bbg2Kw,618
|
109
111
|
examples/weaviate_example/query_text.py,sha256=wPHQTc_58kPoKTZMygVjTj-2ZcdrIuaausJfMxNQnQc,127162
|
110
112
|
langtrace_python_sdk/__init__.py,sha256=VZM6i71NR7pBQK6XvJWRelknuTYUhqwqE7PlicKa5Wg,1166
|
111
|
-
langtrace_python_sdk/langtrace.py,sha256=
|
112
|
-
langtrace_python_sdk/version.py,sha256=
|
113
|
+
langtrace_python_sdk/langtrace.py,sha256=jvfrnkAxc41dmIvwNuVcXwCWyV2vqhGV5qAr5KiMHBA,13239
|
114
|
+
langtrace_python_sdk/version.py,sha256=Q6BbHmX4u_5OYiZVZRbbX2mSRD5cDGkLiRAb8Pu2590,23
|
113
115
|
langtrace_python_sdk/constants/__init__.py,sha256=3CNYkWMdd1DrkGqzLUgNZXjdAlM6UFMlf_F-odAToyc,146
|
114
116
|
langtrace_python_sdk/constants/exporter/langtrace_exporter.py,sha256=EVCrouYCpY98f0KSaKr4PzNxPULTZZO6dSA_crEOyJU,106
|
115
117
|
langtrace_python_sdk/constants/instrumentation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -134,7 +136,7 @@ langtrace_python_sdk/constants/instrumentation/weaviate.py,sha256=gtv-JBxvNGClEM
|
|
134
136
|
langtrace_python_sdk/extensions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
135
137
|
langtrace_python_sdk/extensions/langtrace_exporter.py,sha256=ckd8dMmY6h2oxE04p1JFLwUB5PSJX_Cy4eDFEM6aj4Y,6605
|
136
138
|
langtrace_python_sdk/extensions/langtrace_filesystem.py,sha256=34fZutG28EJ66l67OvTGsydAH3ZpXgikdE7hVLqBpG4,7863
|
137
|
-
langtrace_python_sdk/instrumentation/__init__.py,sha256=
|
139
|
+
langtrace_python_sdk/instrumentation/__init__.py,sha256=ojgb2IcXfeTr_1F4tcr0il3W3iaUnbIofYw11ogsq-8,2089
|
138
140
|
langtrace_python_sdk/instrumentation/anthropic/__init__.py,sha256=donrurJAGYlxrSRA3BIf76jGeUcAx9Tq8CVpah68S0Y,101
|
139
141
|
langtrace_python_sdk/instrumentation/anthropic/instrumentation.py,sha256=ndXdruI0BG7n75rsuEpKjfzePxrZxg40gZ39ONmD_v4,1845
|
140
142
|
langtrace_python_sdk/instrumentation/anthropic/patch.py,sha256=ztPN4VZujoxYOKhTbFnup7Ibms9NAzYCPAJY43NUgKw,4935
|
@@ -168,6 +170,9 @@ langtrace_python_sdk/instrumentation/embedchain/patch.py,sha256=ovvBrtqUDwGSmSgK
|
|
168
170
|
langtrace_python_sdk/instrumentation/gemini/__init__.py,sha256=ilWmKA4Li-g3DX6R10WQ4v-51VljxToEnJpOQoQB5uQ,88
|
169
171
|
langtrace_python_sdk/instrumentation/gemini/instrumentation.py,sha256=eGWr2dy1f_9TVZiXSH_MlNQINyS4I28EsOTKREdMVio,1304
|
170
172
|
langtrace_python_sdk/instrumentation/gemini/patch.py,sha256=PG5E5v253x2ufQ81-aUUFzDRYq-DDhiqwmNoplHPjsM,6261
|
173
|
+
langtrace_python_sdk/instrumentation/google_genai/__init__.py,sha256=nQ2kSsUDpLGZ_kz2QGddDwnawL9juVA7pW4G-BOe5VI,98
|
174
|
+
langtrace_python_sdk/instrumentation/google_genai/instrumentation.py,sha256=oqKDhVcRRHhD5tK3adAIQo9Bpe7CA-k33gla1IymwXU,1080
|
175
|
+
langtrace_python_sdk/instrumentation/google_genai/patch.py,sha256=X0TWY1D4XHweaNu70PlXBDzKEaHIibLpkJiIsp4jF6A,4115
|
171
176
|
langtrace_python_sdk/instrumentation/groq/__init__.py,sha256=ZXeq_nrej6Lm_uoMFEg8wbSejhjB2UJ5IoHQBPc2-C0,91
|
172
177
|
langtrace_python_sdk/instrumentation/groq/instrumentation.py,sha256=Ttf07XVKhdYY1_fqJc7QWiSdmgEhEVyQB_3Az2_wqYo,1832
|
173
178
|
langtrace_python_sdk/instrumentation/groq/patch.py,sha256=J0h8SXEw2LyMIJhKZTVydEysyKfSLWkCuhEharzDS4w,23161
|
@@ -272,8 +277,8 @@ tests/pinecone/cassettes/test_query.yaml,sha256=b5v9G3ssUy00oG63PlFUR3JErF2Js-5A
|
|
272
277
|
tests/pinecone/cassettes/test_upsert.yaml,sha256=neWmQ1v3d03V8WoLl8FoFeeCYImb8pxlJBWnFd_lITU,38607
|
273
278
|
tests/qdrant/conftest.py,sha256=9n0uHxxIjWk9fbYc4bx-uP8lSAgLBVx-cV9UjnsyCHM,381
|
274
279
|
tests/qdrant/test_qdrant.py,sha256=pzjAjVY2kmsmGfrI2Gs2xrolfuaNHz7l1fqGQCjp5_o,3353
|
275
|
-
langtrace_python_sdk-3.3.
|
276
|
-
langtrace_python_sdk-3.3.
|
277
|
-
langtrace_python_sdk-3.3.
|
278
|
-
langtrace_python_sdk-3.3.
|
279
|
-
langtrace_python_sdk-3.3.
|
280
|
+
langtrace_python_sdk-3.3.23.dist-info/METADATA,sha256=KuERJmhF9i6f40sX0ty1TVq_6zaiAefIEmwTr78vkz8,15676
|
281
|
+
langtrace_python_sdk-3.3.23.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
282
|
+
langtrace_python_sdk-3.3.23.dist-info/entry_points.txt,sha256=1_b9-qvf2fE7uQNZcbUei9vLpFZBbbh9LrtGw95ssAo,70
|
283
|
+
langtrace_python_sdk-3.3.23.dist-info/licenses/LICENSE,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
|
284
|
+
langtrace_python_sdk-3.3.23.dist-info/RECORD,,
|
File without changes
|
{langtrace_python_sdk-3.3.22.dist-info → langtrace_python_sdk-3.3.23.dist-info}/entry_points.txt
RENAMED
File without changes
|
{langtrace_python_sdk-3.3.22.dist-info → langtrace_python_sdk-3.3.23.dist-info}/licenses/LICENSE
RENAMED
File without changes
|