langtrace-python-sdk 2.0.7__py3-none-any.whl → 2.0.8__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/pinecone_example/basic.py +9 -8
- langtrace_python_sdk/__init__.py +2 -1
- langtrace_python_sdk/instrumentation/pinecone/patch.py +56 -0
- langtrace_python_sdk/instrumentation/qdrant/patch.py +35 -3
- langtrace_python_sdk/langtrace.py +3 -1
- langtrace_python_sdk/utils/__init__.py +7 -0
- langtrace_python_sdk/utils/llm.py +8 -0
- langtrace_python_sdk/utils/prompt_registry.py +82 -0
- langtrace_python_sdk/utils/silently_fail.py +19 -0
- langtrace_python_sdk/utils/types.py +0 -0
- langtrace_python_sdk/version.py +1 -1
- {langtrace_python_sdk-2.0.7.dist-info → langtrace_python_sdk-2.0.8.dist-info}/METADATA +12 -1
- {langtrace_python_sdk-2.0.7.dist-info → langtrace_python_sdk-2.0.8.dist-info}/RECORD +23 -14
- tests/chroma/conftest.py +15 -0
- tests/chroma/test_chroma.py +29 -68
- tests/pinecone/cassettes/test_query.yaml +822 -0
- tests/pinecone/cassettes/test_upsert.yaml +565 -0
- tests/pinecone/conftest.py +39 -0
- tests/pinecone/test_pinecone.py +81 -71
- tests/qdrant/conftest.py +19 -0
- tests/qdrant/test_qdrant.py +92 -0
- {langtrace_python_sdk-2.0.7.dist-info → langtrace_python_sdk-2.0.8.dist-info}/WHEEL +0 -0
- {langtrace_python_sdk-2.0.7.dist-info → langtrace_python_sdk-2.0.8.dist-info}/licenses/LICENSE +0 -0
|
@@ -2,19 +2,16 @@
|
|
|
2
2
|
This example demonstrates how to use Pinecone with Langtrace.
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
+
from langtrace_python_sdk import langtrace
|
|
5
6
|
from dotenv import find_dotenv, load_dotenv
|
|
6
7
|
from openai import OpenAI
|
|
7
8
|
from pinecone import Pinecone
|
|
8
9
|
|
|
9
|
-
from langtrace_python_sdk import langtrace
|
|
10
10
|
from langtrace_python_sdk.utils.with_root_span import with_langtrace_root_span
|
|
11
11
|
|
|
12
12
|
_ = load_dotenv(find_dotenv())
|
|
13
13
|
|
|
14
|
-
langtrace.init(
|
|
15
|
-
write_spans_to_console=True,
|
|
16
|
-
disable_instrumentations={"all_except": ["pinecone", "openai"]},
|
|
17
|
-
)
|
|
14
|
+
langtrace.init()
|
|
18
15
|
|
|
19
16
|
client = OpenAI()
|
|
20
17
|
pinecone = Pinecone()
|
|
@@ -30,10 +27,14 @@ def basic():
|
|
|
30
27
|
|
|
31
28
|
embedding = result.data[0].embedding
|
|
32
29
|
|
|
33
|
-
unique_id = "
|
|
30
|
+
unique_id = "unique_random_id"
|
|
34
31
|
data_to_upsert = {"id": unique_id, "values": embedding}
|
|
35
32
|
|
|
36
33
|
index = pinecone.Index("test-index")
|
|
37
|
-
index.upsert(vectors=[data_to_upsert])
|
|
34
|
+
res = index.upsert(vectors=[data_to_upsert], namespace="test-namespace")
|
|
35
|
+
print("res", res)
|
|
38
36
|
|
|
39
|
-
resp = index.query(
|
|
37
|
+
resp = index.query(
|
|
38
|
+
vector=embedding, top_k=1, include_values=False, namespace="test-namespace"
|
|
39
|
+
)
|
|
40
|
+
print(resp)
|
langtrace_python_sdk/__init__.py
CHANGED
|
@@ -16,5 +16,6 @@ limitations under the License.
|
|
|
16
16
|
|
|
17
17
|
from langtrace_python_sdk import langtrace
|
|
18
18
|
from langtrace_python_sdk.utils.with_root_span import with_langtrace_root_span
|
|
19
|
+
from langtrace_python_sdk.utils.prompt_registry import get_prompt_from_registry
|
|
19
20
|
|
|
20
|
-
__all__ = ["langtrace", "with_langtrace_root_span"]
|
|
21
|
+
__all__ = ["langtrace", "with_langtrace_root_span", "get_prompt_from_registry"]
|
|
@@ -15,6 +15,8 @@ limitations under the License.
|
|
|
15
15
|
"""
|
|
16
16
|
|
|
17
17
|
from langtrace.trace_attributes import DatabaseSpanAttributes
|
|
18
|
+
from langtrace_python_sdk.utils import set_span_attribute
|
|
19
|
+
from langtrace_python_sdk.utils.silently_fail import silently_fail
|
|
18
20
|
from opentelemetry import baggage
|
|
19
21
|
from opentelemetry.trace import SpanKind
|
|
20
22
|
from opentelemetry.trace.status import Status, StatusCode
|
|
@@ -24,6 +26,7 @@ from langtrace_python_sdk.constants.instrumentation.common import (
|
|
|
24
26
|
SERVICE_PROVIDERS,
|
|
25
27
|
)
|
|
26
28
|
from langtrace_python_sdk.constants.instrumentation.pinecone import APIS
|
|
29
|
+
import json
|
|
27
30
|
|
|
28
31
|
|
|
29
32
|
def generic_patch(original_method, method, version, tracer):
|
|
@@ -49,12 +52,21 @@ def generic_patch(original_method, method, version, tracer):
|
|
|
49
52
|
attributes = DatabaseSpanAttributes(**span_attributes)
|
|
50
53
|
|
|
51
54
|
with tracer.start_as_current_span(api["METHOD"], kind=SpanKind.CLIENT) as span:
|
|
55
|
+
|
|
56
|
+
if span.is_recording():
|
|
57
|
+
set_span_attribute(span, "server.address", instance._config.host)
|
|
58
|
+
if method == "QUERY":
|
|
59
|
+
set_query_input_attributes(span, kwargs)
|
|
60
|
+
|
|
52
61
|
for field, value in attributes.model_dump(by_alias=True).items():
|
|
53
62
|
if value is not None:
|
|
54
63
|
span.set_attribute(field, value)
|
|
55
64
|
try:
|
|
56
65
|
# Attempt to call the original method
|
|
57
66
|
result = original_method(instance, *args, **kwargs)
|
|
67
|
+
if result:
|
|
68
|
+
if span.is_recording():
|
|
69
|
+
set_query_response_attributes(span, result)
|
|
58
70
|
span.set_status(StatusCode.OK)
|
|
59
71
|
return result
|
|
60
72
|
except Exception as err:
|
|
@@ -67,4 +79,48 @@ def generic_patch(original_method, method, version, tracer):
|
|
|
67
79
|
# Reraise the exception to ensure it's not swallowed
|
|
68
80
|
raise
|
|
69
81
|
|
|
82
|
+
@silently_fail
|
|
83
|
+
def set_query_input_attributes(span, kwargs):
|
|
84
|
+
set_span_attribute(span, "db.query.top_k", kwargs.get("top_k"))
|
|
85
|
+
set_span_attribute(span, "db.query.namespace", kwargs.get("namespace"))
|
|
86
|
+
set_span_attribute(span, "db.query.id", kwargs.get("id"))
|
|
87
|
+
filter = (
|
|
88
|
+
json.dumps(kwargs.get("filter"))
|
|
89
|
+
if isinstance(kwargs.get("filter"), dict)
|
|
90
|
+
else kwargs.get("filter")
|
|
91
|
+
)
|
|
92
|
+
set_span_attribute(span, "db.query.filter", filter)
|
|
93
|
+
set_span_attribute(
|
|
94
|
+
span, "db.query.include_values", kwargs.get("include_values")
|
|
95
|
+
)
|
|
96
|
+
set_span_attribute(
|
|
97
|
+
span, "db.query.include_metadata", kwargs.get("include_metadata")
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
@silently_fail
|
|
101
|
+
def set_query_response_attributes(span, response):
|
|
102
|
+
matches = response.get("matches")
|
|
103
|
+
|
|
104
|
+
usage = response.get("usage")
|
|
105
|
+
for match in matches:
|
|
106
|
+
span.add_event(
|
|
107
|
+
name="db.query.match",
|
|
108
|
+
attributes={
|
|
109
|
+
"db.query.match.id": match.get("id"),
|
|
110
|
+
"db.query.match.score": match.get("score"),
|
|
111
|
+
"db.query.match.metadata": match.get("metadata"),
|
|
112
|
+
# "db.query.match.values": match.get("values"),
|
|
113
|
+
},
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
if "read_units" in usage:
|
|
117
|
+
set_span_attribute(
|
|
118
|
+
span, "db.query.usage.read_units", usage.get("read_units")
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
if "write_units" in usage:
|
|
122
|
+
set_span_attribute(
|
|
123
|
+
span, "db.query.usage.write_units", usage.get("write_units")
|
|
124
|
+
)
|
|
125
|
+
|
|
70
126
|
return traced_method
|
|
@@ -15,6 +15,8 @@ limitations under the License.
|
|
|
15
15
|
"""
|
|
16
16
|
|
|
17
17
|
from langtrace.trace_attributes import DatabaseSpanAttributes
|
|
18
|
+
from langtrace_python_sdk.utils.silently_fail import silently_fail
|
|
19
|
+
from langtrace_python_sdk.utils.llm import set_span_attributes
|
|
18
20
|
from opentelemetry import baggage
|
|
19
21
|
from opentelemetry.trace import SpanKind
|
|
20
22
|
from opentelemetry.trace.status import Status, StatusCode
|
|
@@ -47,12 +49,19 @@ def collection_patch(method, version, tracer):
|
|
|
47
49
|
**(extra_attributes if extra_attributes is not None else {}),
|
|
48
50
|
}
|
|
49
51
|
|
|
50
|
-
if hasattr(instance, "name") and instance.name is not None:
|
|
51
|
-
span_attributes["db.collection.name"] = instance.name
|
|
52
|
-
|
|
53
52
|
attributes = DatabaseSpanAttributes(**span_attributes)
|
|
54
53
|
|
|
55
54
|
with tracer.start_as_current_span(api["METHOD"], kind=SpanKind.CLIENT) as span:
|
|
55
|
+
collection_name = kwargs.get("collection_name") or args[0]
|
|
56
|
+
operation = api["OPERATION"]
|
|
57
|
+
set_span_attributes(span, "db.collection.name", collection_name)
|
|
58
|
+
if operation == "upsert":
|
|
59
|
+
_set_upsert_attributes(span, args, kwargs)
|
|
60
|
+
elif operation == "add":
|
|
61
|
+
_set_upload_attributes(span, args, kwargs, "documents")
|
|
62
|
+
|
|
63
|
+
# Todo: Add support for other operations here.
|
|
64
|
+
|
|
56
65
|
for field, value in attributes.model_dump(by_alias=True).items():
|
|
57
66
|
if value is not None:
|
|
58
67
|
span.set_attribute(field, value)
|
|
@@ -72,3 +81,26 @@ def collection_patch(method, version, tracer):
|
|
|
72
81
|
raise
|
|
73
82
|
|
|
74
83
|
return traced_method
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
@silently_fail
|
|
87
|
+
def _set_upsert_attributes(span, args, kwargs):
|
|
88
|
+
points = kwargs.get("points") or args[1]
|
|
89
|
+
if isinstance(points, list):
|
|
90
|
+
length = len(points)
|
|
91
|
+
else:
|
|
92
|
+
# In case of using Batch.
|
|
93
|
+
length = len(points.ids)
|
|
94
|
+
set_span_attributes(span, "db.upsert.points_count", length)
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
@silently_fail
|
|
98
|
+
def _set_upload_attributes(span, args, kwargs, field):
|
|
99
|
+
docs = kwargs.get(field) or args[0]
|
|
100
|
+
if isinstance(docs, list):
|
|
101
|
+
length = len(docs)
|
|
102
|
+
else:
|
|
103
|
+
# In case of using Batch.
|
|
104
|
+
length = len(docs.ids)
|
|
105
|
+
|
|
106
|
+
set_span_attributes(span, f"db.upload.{field}_count", length)
|
|
@@ -24,6 +24,8 @@ from opentelemetry.sdk.trace.export import (
|
|
|
24
24
|
ConsoleSpanExporter,
|
|
25
25
|
SimpleSpanProcessor,
|
|
26
26
|
)
|
|
27
|
+
import sys
|
|
28
|
+
from opentelemetry.sdk.resources import Resource
|
|
27
29
|
|
|
28
30
|
from langtrace_python_sdk.extensions.langtrace_exporter import LangTraceExporter
|
|
29
31
|
from langtrace_python_sdk.instrumentation.anthropic.instrumentation import (
|
|
@@ -72,7 +74,7 @@ def init(
|
|
|
72
74
|
api_host: Optional[str] = None,
|
|
73
75
|
disable_instrumentations: Optional[DisableInstrumentations] = None,
|
|
74
76
|
):
|
|
75
|
-
provider = TracerProvider()
|
|
77
|
+
provider = TracerProvider(resource=Resource.create({"service.name": sys.argv[0]}))
|
|
76
78
|
|
|
77
79
|
remote_write_exporter = (
|
|
78
80
|
LangTraceExporter(api_key=api_key, api_host=api_host)
|
|
@@ -58,3 +58,11 @@ def calculate_price_from_usage(model, usage):
|
|
|
58
58
|
+ cost_table["output"] * usage["completion_tokens"]
|
|
59
59
|
) / 1000
|
|
60
60
|
return 0
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def set_span_attributes(span, name, value):
|
|
64
|
+
if value is not None:
|
|
65
|
+
if value != "":
|
|
66
|
+
span.set_attribute(name, value)
|
|
67
|
+
return
|
|
68
|
+
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from langtrace_python_sdk.constants.exporter.langtrace_exporter import (
|
|
3
|
+
LANGTRACE_REMOTE_URL,
|
|
4
|
+
)
|
|
5
|
+
import requests
|
|
6
|
+
from urllib.parse import urlencode
|
|
7
|
+
from typing import Optional, TypedDict, Dict, List
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class LangtracePrompt(TypedDict):
|
|
11
|
+
id: str
|
|
12
|
+
value: str
|
|
13
|
+
variables: List[str]
|
|
14
|
+
model: str
|
|
15
|
+
modelSettings: Dict[str, object]
|
|
16
|
+
version: int
|
|
17
|
+
live: bool
|
|
18
|
+
tags: List[str]
|
|
19
|
+
note: str
|
|
20
|
+
promptsetId: str
|
|
21
|
+
createdAt: str
|
|
22
|
+
updatedAt: str
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class FetchOptions(TypedDict, total=False):
|
|
26
|
+
prompt_version: int
|
|
27
|
+
variables: Dict[str, str]
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def get_prompt_from_registry(
|
|
31
|
+
prompt_registry_id: str,
|
|
32
|
+
options: Optional[FetchOptions] = None,
|
|
33
|
+
) -> LangtracePrompt:
|
|
34
|
+
"""Fetches a prompt from the registry.
|
|
35
|
+
|
|
36
|
+
Args:
|
|
37
|
+
prompt_registry_id (str): The ID of the prompt registry.
|
|
38
|
+
options (dict, optional): Configuration options for fetching the prompt:
|
|
39
|
+
- prompt_version (int): Fetches the prompt with the specified version.
|
|
40
|
+
- variables (dict): Replaces variables in the prompt with provided values.
|
|
41
|
+
|
|
42
|
+
Returns:
|
|
43
|
+
dict: The fetched prompt with variables replaced as specified.
|
|
44
|
+
|
|
45
|
+
Raises:
|
|
46
|
+
Exception: If the fetch operation fails or returns an error.
|
|
47
|
+
"""
|
|
48
|
+
try:
|
|
49
|
+
query_params = {"promptset_id": prompt_registry_id}
|
|
50
|
+
if options:
|
|
51
|
+
if "prompt_version" in options:
|
|
52
|
+
query_params["version"] = options["prompt_version"]
|
|
53
|
+
if "variables" in options:
|
|
54
|
+
for key, value in options["variables"].items():
|
|
55
|
+
query_params[f"variables.{key}"] = value
|
|
56
|
+
# Encode the query parameters
|
|
57
|
+
query_string = urlencode(query_params, doseq=True)
|
|
58
|
+
headers = {"x-api-key": os.environ["LANGTRACE_API_KEY"]}
|
|
59
|
+
print(query_params)
|
|
60
|
+
# Make the GET request to the API
|
|
61
|
+
response = requests.get(
|
|
62
|
+
f"{LANGTRACE_REMOTE_URL}/api/promptset?{query_string}",
|
|
63
|
+
headers=headers,
|
|
64
|
+
timeout=None,
|
|
65
|
+
)
|
|
66
|
+
response.raise_for_status()
|
|
67
|
+
|
|
68
|
+
# Extract the prompt data from the response
|
|
69
|
+
prompt_data = response.json()["prompts"][0]
|
|
70
|
+
return prompt_data
|
|
71
|
+
|
|
72
|
+
except requests.RequestException as err:
|
|
73
|
+
# Handle specific HTTP errors or general request exceptions
|
|
74
|
+
error_msg = str(err)
|
|
75
|
+
if err.response:
|
|
76
|
+
try:
|
|
77
|
+
# Try to extract server-provided error message
|
|
78
|
+
error_msg = err.response.json().get("error", error_msg)
|
|
79
|
+
except ValueError:
|
|
80
|
+
# Fallback if response is not JSON
|
|
81
|
+
error_msg = err.response.text
|
|
82
|
+
raise Exception(f"API error: {error_msg}") from err
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def silently_fail(func):
|
|
5
|
+
"""
|
|
6
|
+
A decorator that catches exceptions thrown by the decorated function and logs them as warnings.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
logger = logging.getLogger(func.__module__)
|
|
10
|
+
|
|
11
|
+
def wrapper(*args, **kwargs):
|
|
12
|
+
try:
|
|
13
|
+
return func(*args, **kwargs)
|
|
14
|
+
except Exception as exception:
|
|
15
|
+
logger.warning(
|
|
16
|
+
"Failed to execute %s, error: %s", func.__name__, str(exception)
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
return wrapper
|
|
File without changes
|
langtrace_python_sdk/version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "2.0.
|
|
1
|
+
__version__ = "2.0.8"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: langtrace-python-sdk
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.8
|
|
4
4
|
Summary: Python SDK for LangTrace
|
|
5
5
|
Project-URL: Homepage, https://github.com/Scale3-Labs/langtrace-python-sdk
|
|
6
6
|
Author-email: Scale3 Labs <engineering@scale3labs.com>
|
|
@@ -25,7 +25,9 @@ Requires-Dist: langchain-openai; extra == 'dev'
|
|
|
25
25
|
Requires-Dist: llama-index; extra == 'dev'
|
|
26
26
|
Requires-Dist: openai; extra == 'dev'
|
|
27
27
|
Requires-Dist: python-dotenv; extra == 'dev'
|
|
28
|
+
Requires-Dist: qdrant-client; extra == 'dev'
|
|
28
29
|
Provides-Extra: test
|
|
30
|
+
Requires-Dist: protobuf==3.20.0; extra == 'test'
|
|
29
31
|
Requires-Dist: pytest; extra == 'test'
|
|
30
32
|
Requires-Dist: pytest-asyncio; extra == 'test'
|
|
31
33
|
Requires-Dist: pytest-vcr; extra == 'test'
|
|
@@ -217,6 +219,15 @@ def chat_completion():
|
|
|
217
219
|
api_call2()
|
|
218
220
|
```
|
|
219
221
|
|
|
222
|
+
- `get_prompt_from_registry` - this function is designed to fetch the desired prompt from the `Prompt Registry`. You can pass two options for filtering `prompt_version` & `variables`.
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
```python
|
|
226
|
+
from langtrace_python_sdk import get_prompt_from_registry
|
|
227
|
+
|
|
228
|
+
prompt = get_prompt_from_registry(<Registry ID>, options={"prompt_version": 1, "variables": {"foo": "bar"} })
|
|
229
|
+
```
|
|
230
|
+
|
|
220
231
|
## Supported integrations
|
|
221
232
|
|
|
222
233
|
Langtrace automatically captures traces from the following vendors:
|
|
@@ -32,12 +32,12 @@ examples/openai_example/tool_calling_nonstreaming.py,sha256=Yc848IooZRXNynHL6z0k
|
|
|
32
32
|
examples/openai_example/tool_calling_streaming.py,sha256=mV1RbyAoVhumGRPpqPWQ6PMhnJyeifrlELd2-K1qJ_w,7015
|
|
33
33
|
examples/perplexity_example/basic.py,sha256=bp7n27gaugJkaFVyt8pjaEfi66lYcqP6eFFjPewUShY,668
|
|
34
34
|
examples/pinecone_example/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
35
|
-
examples/pinecone_example/basic.py,sha256=
|
|
35
|
+
examples/pinecone_example/basic.py,sha256=uwWu_UFuDtthgs-x8gOPnsUGOeBDCVPEoiz9uwSEjfg,1007
|
|
36
36
|
examples/qdrant_example/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
37
37
|
examples/qdrant_example/basic.py,sha256=DCMjHSuBZKkhEjCkwy5d5La9WMyW0lCWqtcZWiFCEm4,1425
|
|
38
|
-
langtrace_python_sdk/__init__.py,sha256=
|
|
39
|
-
langtrace_python_sdk/langtrace.py,sha256=
|
|
40
|
-
langtrace_python_sdk/version.py,sha256=
|
|
38
|
+
langtrace_python_sdk/__init__.py,sha256=_r2S-lLZFTFFvWjf0lWBX4nzkJN5R7FHX0Dnmr76CEk,848
|
|
39
|
+
langtrace_python_sdk/langtrace.py,sha256=o0xJInE_dwNBkAfIQRqMKPz6glCAcGdRJxEG8kasq8I,6839
|
|
40
|
+
langtrace_python_sdk/version.py,sha256=oVbl6ILP5dyBZtm2iUzM_QTUhSy3C325aGgDThF7P_4,22
|
|
41
41
|
langtrace_python_sdk/constants/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
42
42
|
langtrace_python_sdk/constants/exporter/langtrace_exporter.py,sha256=5MNjnAOg-4am78J3gVMH6FSwq5N8TOj72ugkhsw4vi0,46
|
|
43
43
|
langtrace_python_sdk/constants/instrumentation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -84,13 +84,16 @@ langtrace_python_sdk/instrumentation/openai/instrumentation.py,sha256=G2HSZfr6Du
|
|
|
84
84
|
langtrace_python_sdk/instrumentation/openai/patch.py,sha256=kQxc_E1IlOgHZnlc0HbpGjM5rZCDR3YpNFChp2X9GbM,37263
|
|
85
85
|
langtrace_python_sdk/instrumentation/pinecone/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
86
86
|
langtrace_python_sdk/instrumentation/pinecone/instrumentation.py,sha256=52GbkfRK-sxXBXhHmHRRO2BGNd6zZVHDp8njLS1CQX0,2314
|
|
87
|
-
langtrace_python_sdk/instrumentation/pinecone/patch.py,sha256=
|
|
87
|
+
langtrace_python_sdk/instrumentation/pinecone/patch.py,sha256=hLgYWDKTytuvTORDd6dupMpKAp19vCgOAXDOdjvWme0,4832
|
|
88
88
|
langtrace_python_sdk/instrumentation/qdrant/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
89
89
|
langtrace_python_sdk/instrumentation/qdrant/instrumentation.py,sha256=vl2eKSP55aqDo1JiRlvOUBrr6kddvG9Z5dCYew2OG08,1816
|
|
90
|
-
langtrace_python_sdk/instrumentation/qdrant/patch.py,sha256=
|
|
90
|
+
langtrace_python_sdk/instrumentation/qdrant/patch.py,sha256=x95PXaJe_GrOG51zZCDuchVA-bzuA7s5LHqOoWrqSA0,3883
|
|
91
91
|
langtrace_python_sdk/types/__init__.py,sha256=QYK-kRkyfXDdzjjKmXVxi0vZ6Wpbxdf0CoZbTXO0JT8,787
|
|
92
|
-
langtrace_python_sdk/utils/__init__.py,sha256=
|
|
93
|
-
langtrace_python_sdk/utils/llm.py,sha256=
|
|
92
|
+
langtrace_python_sdk/utils/__init__.py,sha256=is6gOLiHcvrN9kPgYnUwyzkgz9vInVQ4jGe7k0zRHrA,150
|
|
93
|
+
langtrace_python_sdk/utils/llm.py,sha256=gnmJ6YWzzdOCaVFg1C-iyNcMGDyiJ623qZeOwDYUfIQ,2162
|
|
94
|
+
langtrace_python_sdk/utils/prompt_registry.py,sha256=7FFB4Pj0414qgf02h5zL5vXBZgNBf74g4Iq7GdFaIO0,2689
|
|
95
|
+
langtrace_python_sdk/utils/silently_fail.py,sha256=F_9EteXCO9Cyq-8MA1OT2Zy_dx8n06nt31I7t7ui24E,478
|
|
96
|
+
langtrace_python_sdk/utils/types.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
94
97
|
langtrace_python_sdk/utils/with_root_span.py,sha256=MXF-FmG47P0GtJQNffKM_3XGrJHVAC4hMB6GmwtnA4M,2454
|
|
95
98
|
tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
96
99
|
tests/conftest.py,sha256=0Jo6iCZTXbdvyJVhG9UpYGkLabL75378oauCzmt-Sa8,603
|
|
@@ -100,7 +103,8 @@ tests/anthropic/test_anthropic.py,sha256=p4WhcECJ_zctirtkAX6WejrlNfZzo90fSSxqQki
|
|
|
100
103
|
tests/anthropic/cassettes/test_anthropic.yaml,sha256=z7YAqA_BBgI-hw7uyVMdLoIZdBYhKwl9cuTzUu9nAZs,2332
|
|
101
104
|
tests/anthropic/cassettes/test_anthropic_streaming.yaml,sha256=D0w4-6dfsgrhbNLJEj8gZBV0yXfrAfA9u90Yu8Ac-TY,11675
|
|
102
105
|
tests/anthropic/cassettes/test_async_anthropic_streaming.yaml,sha256=hQZPY2vwBaW3BWllLd0lcGQ73DjA8C3Ips1Hx9pA-ao,8373
|
|
103
|
-
tests/chroma/
|
|
106
|
+
tests/chroma/conftest.py,sha256=kqb4VydCnlVpkvBX5Bu-pfnVS-ZZfju9cp6vq76tkJI,309
|
|
107
|
+
tests/chroma/test_chroma.py,sha256=-KJHunvvVi1OoKKOcKCeHO1s399Gm9vJfd-EzgllQmk,1220
|
|
104
108
|
tests/cohere/conftest.py,sha256=jBbyg-tut-ZJN5_5D64sGmaPIhT_nQQQAiW43kl5Rz4,621
|
|
105
109
|
tests/cohere/test_cohere_chat.py,sha256=MioEIXB5e-4t99Vt-KpLlxd4diPbp3S6eNfnPWjEDXM,4564
|
|
106
110
|
tests/cohere/test_cohere_embed.py,sha256=bFKDzUnypMyLefAOHR-6dEgvt0yys2Yw7-F0zc0uQyc,1250
|
|
@@ -121,8 +125,13 @@ tests/openai/cassettes/test_async_image_generation.yaml,sha256=_LYZcrqxrnSqcWVQn
|
|
|
121
125
|
tests/openai/cassettes/test_chat_completion.yaml,sha256=YkNFgK9VHAzNqGWuxFcTiE194GdEie8eDf1FSsffjd8,2944
|
|
122
126
|
tests/openai/cassettes/test_chat_completion_streaming.yaml,sha256=nkx_TemQMYSZxUF_b-LCEFwCRDm0AkQHLf4sdJVuZBw,2592394
|
|
123
127
|
tests/openai/cassettes/test_image_generation.yaml,sha256=gn5aSVp6V6_hb_rt2NnkAWd_idzDxo-7VzhZII0Wslw,3562
|
|
124
|
-
tests/pinecone/
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
128
|
+
tests/pinecone/conftest.py,sha256=EY1m5M6MKSOktbVEe__wYNjCW9A7H0xdC-aXhU8JEOg,916
|
|
129
|
+
tests/pinecone/test_pinecone.py,sha256=JMe3S15cfBWjTArC-FTCarRRYBFylkv4BwQgL2BmUfw,3614
|
|
130
|
+
tests/pinecone/cassettes/test_query.yaml,sha256=b5v9G3ssUy00oG63PlFUR3JErF2Js-5AIqHnMsvJM8w,103821
|
|
131
|
+
tests/pinecone/cassettes/test_upsert.yaml,sha256=neWmQ1v3d03V8WoLl8FoFeeCYImb8pxlJBWnFd_lITU,38607
|
|
132
|
+
tests/qdrant/conftest.py,sha256=9n0uHxxIjWk9fbYc4bx-uP8lSAgLBVx-cV9UjnsyCHM,381
|
|
133
|
+
tests/qdrant/test_qdrant.py,sha256=pzjAjVY2kmsmGfrI2Gs2xrolfuaNHz7l1fqGQCjp5_o,3353
|
|
134
|
+
langtrace_python_sdk-2.0.8.dist-info/METADATA,sha256=bUB2J9h4OXlPWUXjo-VhX2bqamXaImnC9_vbdxiH5Uw,10046
|
|
135
|
+
langtrace_python_sdk-2.0.8.dist-info/WHEEL,sha256=zEMcRr9Kr03x1ozGwg5v9NQBKn3kndp6LSoSlVg-jhU,87
|
|
136
|
+
langtrace_python_sdk-2.0.8.dist-info/licenses/LICENSE,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
|
|
137
|
+
langtrace_python_sdk-2.0.8.dist-info/RECORD,,
|
tests/chroma/conftest.py
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import chromadb
|
|
2
|
+
import pytest
|
|
3
|
+
from langtrace_python_sdk.instrumentation.chroma.instrumentation import (
|
|
4
|
+
ChromaInstrumentation,
|
|
5
|
+
)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@pytest.fixture
|
|
9
|
+
def chroma_client():
|
|
10
|
+
return chromadb.Client()
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@pytest.fixture(scope="session", autouse=True)
|
|
14
|
+
def instrument():
|
|
15
|
+
ChromaInstrumentation().instrument()
|
tests/chroma/test_chroma.py
CHANGED
|
@@ -1,70 +1,31 @@
|
|
|
1
|
-
|
|
1
|
+
import importlib
|
|
2
|
+
from chromadb.utils import embedding_functions
|
|
2
3
|
from langtrace_python_sdk.constants.instrumentation.common import SERVICE_PROVIDERS
|
|
3
|
-
from langtrace_python_sdk.constants.instrumentation.openai import APIS
|
|
4
|
-
from opentelemetry.trace.status import StatusCode, Status
|
|
5
|
-
from langtrace_python_sdk.instrumentation.chroma.patch import collection_patch
|
|
6
|
-
from opentelemetry.trace import SpanKind
|
|
7
|
-
from tests.utils import common_setup
|
|
8
|
-
import unittest
|
|
9
|
-
import json
|
|
10
4
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
# Assert the span is started with the correct parameters
|
|
40
|
-
self.assertTrue(
|
|
41
|
-
self.tracer.start_as_current_span.called_once_with(
|
|
42
|
-
"chromadb.Collection.add", kind=SpanKind.CLIENT
|
|
43
|
-
)
|
|
44
|
-
)
|
|
45
|
-
|
|
46
|
-
# Verify span attributes are set as expected
|
|
47
|
-
expected_attributes = {
|
|
48
|
-
"langtrace.sdk.name": "langtrace-python-sdk",
|
|
49
|
-
"langtrace.service.name": "Chroma",
|
|
50
|
-
"langtrace.service.type": "vectordb",
|
|
51
|
-
"langtrace.service.version": "1.2.3",
|
|
52
|
-
"langtrace.version": "1.0.0",
|
|
53
|
-
"db.system": "chromadb",
|
|
54
|
-
"db.operation": "add",
|
|
55
|
-
"db.collection.name": "aa",
|
|
56
|
-
}
|
|
57
|
-
for key, value in expected_attributes.items():
|
|
58
|
-
self.span.set_attribute.assert_has_calls([call(key, value)], any_order=True)
|
|
59
|
-
|
|
60
|
-
actual_calls = self.span.set_attribute.call_args_list
|
|
61
|
-
|
|
62
|
-
for key, value in expected_attributes.items():
|
|
63
|
-
self.assertIn(call(key, value), actual_calls)
|
|
64
|
-
|
|
65
|
-
# Assert the span status is set to OK
|
|
66
|
-
self.span.set_status.assert_called_with(StatusCode.OK)
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
if __name__ == "__main__":
|
|
70
|
-
unittest.main()
|
|
5
|
+
COLLECTION_NAME = "test_collection"
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def test_chroma_add(chroma_client, exporter):
|
|
9
|
+
embedder = embedding_functions.DefaultEmbeddingFunction()
|
|
10
|
+
collection = chroma_client.create_collection(
|
|
11
|
+
name=COLLECTION_NAME, embedding_function=embedder
|
|
12
|
+
)
|
|
13
|
+
collection.add(
|
|
14
|
+
documents=["This is a document", "This is another document"],
|
|
15
|
+
metadatas=[{"source": "my_source"}, {"source": "my_source"}],
|
|
16
|
+
ids=["id1", "id2"],
|
|
17
|
+
)
|
|
18
|
+
spans = exporter.get_finished_spans()
|
|
19
|
+
chroma_span = spans[-1]
|
|
20
|
+
|
|
21
|
+
attributes = chroma_span.attributes
|
|
22
|
+
|
|
23
|
+
assert attributes.get("db.collection.name") == COLLECTION_NAME
|
|
24
|
+
assert attributes.get("db.operation") == "add"
|
|
25
|
+
assert attributes.get("db.system") == "chromadb"
|
|
26
|
+
assert attributes.get("langtrace.sdk.name") == "langtrace-python-sdk"
|
|
27
|
+
assert attributes.get("langtrace.service.name") == SERVICE_PROVIDERS["CHROMA"]
|
|
28
|
+
assert attributes.get("langtrace.service.type") == "vectordb"
|
|
29
|
+
assert attributes.get("langtrace.service.version") == importlib.metadata.version(
|
|
30
|
+
"chromadb"
|
|
31
|
+
)
|