langtrace-python-sdk 2.1.2__py3-none-any.whl → 2.1.5__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.
Files changed (30) hide show
  1. examples/pinecone_example/basic.py +2 -4
  2. examples/weaviate_example/query_text.py +3 -3
  3. langtrace_python_sdk/extensions/langtrace_exporter.py +22 -7
  4. langtrace_python_sdk/instrumentation/__init__.py +29 -0
  5. langtrace_python_sdk/instrumentation/anthropic/__init__.py +5 -0
  6. langtrace_python_sdk/instrumentation/chroma/__init__.py +5 -0
  7. langtrace_python_sdk/instrumentation/cohere/__init__.py +5 -0
  8. langtrace_python_sdk/instrumentation/groq/__init__.py +5 -0
  9. langtrace_python_sdk/instrumentation/langchain/__init__.py +5 -0
  10. langtrace_python_sdk/instrumentation/langchain_community/__init__.py +5 -0
  11. langtrace_python_sdk/instrumentation/langchain_core/__init__.py +6 -0
  12. langtrace_python_sdk/instrumentation/langgraph/__init__.py +5 -0
  13. langtrace_python_sdk/instrumentation/llamaindex/__init__.py +5 -0
  14. langtrace_python_sdk/instrumentation/openai/__init__.py +5 -0
  15. langtrace_python_sdk/instrumentation/pinecone/__init__.py +5 -0
  16. langtrace_python_sdk/instrumentation/qdrant/__init__.py +5 -0
  17. langtrace_python_sdk/instrumentation/weaviate/__init__.py +5 -0
  18. langtrace_python_sdk/instrumentation/weaviate/instrumentation.py +14 -12
  19. langtrace_python_sdk/langtrace.py +9 -25
  20. langtrace_python_sdk/utils/with_root_span.py +0 -2
  21. langtrace_python_sdk/version.py +1 -1
  22. {langtrace_python_sdk-2.1.2.dist-info → langtrace_python_sdk-2.1.5.dist-info}/METADATA +3 -1
  23. {langtrace_python_sdk-2.1.2.dist-info → langtrace_python_sdk-2.1.5.dist-info}/RECORD +28 -28
  24. tests/langchain/cassettes/test_langchain.yaml +106 -0
  25. tests/langchain/conftest.py +42 -0
  26. tests/langchain/test_langchain.py +28 -82
  27. tests/langchain/test_langchain_community.py +0 -82
  28. tests/langchain/test_langchain_core.py +0 -141
  29. {langtrace_python_sdk-2.1.2.dist-info → langtrace_python_sdk-2.1.5.dist-info}/WHEEL +0 -0
  30. {langtrace_python_sdk-2.1.2.dist-info → langtrace_python_sdk-2.1.5.dist-info}/licenses/LICENSE +0 -0
@@ -29,7 +29,7 @@ def create_index():
29
29
 
30
30
 
31
31
  @with_langtrace_root_span()
32
- def basic(span_id, trace_id):
32
+ def basic(span_id=None, trace_id=None):
33
33
 
34
34
  result = client.embeddings.create(
35
35
  model="text-embedding-ada-002",
@@ -44,7 +44,6 @@ def basic(span_id, trace_id):
44
44
 
45
45
  index = pinecone.Index(PINECONE_INDEX_NAME)
46
46
  res = index.upsert(vectors=[data_to_upsert], namespace="test-namespace")
47
- print("res", res)
48
47
 
49
48
  resp = index.query(
50
49
  vector=embedding, top_k=1, include_values=False, namespace="test-namespace"
@@ -52,8 +51,7 @@ def basic(span_id, trace_id):
52
51
  send_user_feedback(
53
52
  {"spanId": span_id, "traceId": trace_id, "userScore": 1, "userId": "123"}
54
53
  )
55
- print(resp)
54
+ return [res, resp]
56
55
 
57
56
 
58
57
  # create_index()
59
- basic("span_id", "trace_id")
@@ -19,8 +19,8 @@ import langtrace_python_sdk.langtrace as langtrace
19
19
  from langtrace_python_sdk import with_langtrace_root_span
20
20
 
21
21
  # Set these environment variables
22
- WCS_DEMO_URL = "WEVIATE CLUSTER URL"
23
- WCS_DEMO_RO_KEY = "<WEAVIATE API KEY>"
22
+ WCS_DEMO_URL = os.environ["WCS_DEMO_URL"]
23
+ WCS_DEMO_RO_KEY = os.environ["WCS_DEMO_RO_KEY"]
24
24
 
25
25
  # Connect to a WCS instance
26
26
  client = weaviate.connect_to_wcs(
@@ -30,7 +30,7 @@ client = weaviate.connect_to_wcs(
30
30
  headers={"X-OpenAI-Api-Key": os.environ["OPENAI_APIKEY"]},
31
31
  )
32
32
 
33
- langtrace.init(api_key="asdf", write_spans_to_console=True, batch=False)
33
+ langtrace.init()
34
34
 
35
35
 
36
36
  @with_langtrace_root_span()
@@ -9,6 +9,8 @@ from opentelemetry.trace.span import format_trace_id
9
9
  from langtrace_python_sdk.constants.exporter.langtrace_exporter import (
10
10
  LANGTRACE_REMOTE_URL,
11
11
  )
12
+ from colorama import Fore
13
+ from requests.exceptions import RequestException
12
14
 
13
15
 
14
16
  class LangTraceExporter(SpanExporter):
@@ -55,9 +57,6 @@ class LangTraceExporter(SpanExporter):
55
57
  self.api_key = api_key or os.environ.get("LANGTRACE_API_KEY")
56
58
  self.api_host: str = api_host or LANGTRACE_REMOTE_URL
57
59
 
58
- if not self.api_key:
59
- raise ValueError("No API key provided")
60
-
61
60
  def export(self, spans: typing.Sequence[ReadableSpan]) -> SpanExportResult:
62
61
  """
63
62
  Exports a batch of telemetry data.
@@ -68,10 +67,17 @@ class LangTraceExporter(SpanExporter):
68
67
  Returns:
69
68
  The result of the export SUCCESS or FAILURE
70
69
  """
70
+ if not self.api_key:
71
+ print(Fore.RED)
72
+ print(
73
+ "Missing Langtrace API key, proceed to https://langtrace.ai to create one"
74
+ )
75
+ print("Set the API key as an environment variable LANGTRACE_API_KEY")
76
+ print(Fore.RESET)
77
+ return
71
78
  data = [
72
79
  {
73
80
  "traceId": format_trace_id(span.get_span_context().trace_id),
74
- "instrumentationLibrary": span.instrumentation_info.__repr__(),
75
81
  "droppedEventsCount": span.dropped_events,
76
82
  "droppedAttributesCount": span.dropped_attributes,
77
83
  "droppedLinksCount": span.dropped_links,
@@ -83,14 +89,23 @@ class LangTraceExporter(SpanExporter):
83
89
 
84
90
  # Send data to remote URL
85
91
  try:
86
- requests.post(
92
+ response = requests.post(
87
93
  url=f"{self.api_host}/api/trace",
88
94
  data=json.dumps(data),
89
95
  headers={"Content-Type": "application/json", "x-api-key": self.api_key},
96
+ timeout=20,
97
+ )
98
+
99
+ if not response.ok:
100
+ raise RequestException(response.text)
101
+
102
+ print(
103
+ Fore.GREEN + f"Exported {len(spans)} spans successfully." + Fore.RESET
90
104
  )
91
- print(f"sent to {self.api_host}/api/trace with {len(data)} spans")
92
105
  return SpanExportResult.SUCCESS
93
- except Exception as e:
106
+ except RequestException as err:
107
+ print(Fore.RED + "Failed to export spans.")
108
+ print(Fore.RED + f"Error: {err}" + Fore.RESET)
94
109
  return SpanExportResult.FAILURE
95
110
 
96
111
  def shutdown(self) -> None:
@@ -0,0 +1,29 @@
1
+ from .anthropic import AnthropicInstrumentation
2
+ from .chroma import ChromaInstrumentation
3
+ from .cohere import CohereInstrumentation
4
+ from .groq import GroqInstrumentation
5
+ from .langchain import LangchainInstrumentation
6
+ from .langchain_community import LangchainCommunityInstrumentation
7
+ from .langchain_core import LangchainCoreInstrumentation
8
+ from .langgraph import LanggraphInstrumentation
9
+ from .llamaindex import LlamaindexInstrumentation
10
+ from .openai import OpenAIInstrumentation
11
+ from .pinecone import PineconeInstrumentation
12
+ from .qdrant import QdrantInstrumentation
13
+ from .weaviate import WeaviateInstrumentation
14
+
15
+ __all__ = [
16
+ "AnthropicInstrumentation",
17
+ "ChromaInstrumentation",
18
+ "CohereInstrumentation",
19
+ "GroqInstrumentation",
20
+ "LangchainInstrumentation",
21
+ "LangchainCommunityInstrumentation",
22
+ "LangchainCoreInstrumentation",
23
+ "LanggraphInstrumentation",
24
+ "LlamaindexInstrumentation",
25
+ "OpenAIInstrumentation",
26
+ "PineconeInstrumentation",
27
+ "QdrantInstrumentation",
28
+ "WeaviateInstrumentation",
29
+ ]
@@ -0,0 +1,5 @@
1
+ from .instrumentation import AnthropicInstrumentation
2
+
3
+ __all__ = [
4
+ "AnthropicInstrumentation",
5
+ ]
@@ -0,0 +1,5 @@
1
+ from .instrumentation import ChromaInstrumentation
2
+
3
+ __all__ = [
4
+ "ChromaInstrumentation",
5
+ ]
@@ -0,0 +1,5 @@
1
+ from .instrumentation import CohereInstrumentation
2
+
3
+ __all__ = [
4
+ "CohereInstrumentation",
5
+ ]
@@ -0,0 +1,5 @@
1
+ from .instrumentation import GroqInstrumentation
2
+
3
+ __all__ = [
4
+ "GroqInstrumentation",
5
+ ]
@@ -0,0 +1,5 @@
1
+ from .instrumentation import LangchainInstrumentation
2
+
3
+ __all__ = [
4
+ "LangchainInstrumentation",
5
+ ]
@@ -0,0 +1,5 @@
1
+ from .instrumentation import LangchainCommunityInstrumentation
2
+
3
+ __all__ = [
4
+ "LangchainCommunityInstrumentation",
5
+ ]
@@ -0,0 +1,6 @@
1
+ from .instrumentation import LangchainCoreInstrumentation
2
+
3
+
4
+ __all__ = [
5
+ "LangchainCoreInstrumentation",
6
+ ]
@@ -0,0 +1,5 @@
1
+ from .instrumentation import LanggraphInstrumentation
2
+
3
+ __all__ = [
4
+ "LanggraphInstrumentation",
5
+ ]
@@ -0,0 +1,5 @@
1
+ from .instrumentation import LlamaindexInstrumentation
2
+
3
+ __all__ = [
4
+ "LlamaindexInstrumentation",
5
+ ]
@@ -0,0 +1,5 @@
1
+ from .instrumentation import OpenAIInstrumentation
2
+
3
+ __all__ = [
4
+ "OpenAIInstrumentation",
5
+ ]
@@ -0,0 +1,5 @@
1
+ from .instrumentation import PineconeInstrumentation
2
+
3
+ __all__ = [
4
+ "PineconeInstrumentation",
5
+ ]
@@ -0,0 +1,5 @@
1
+ from .instrumentation import QdrantInstrumentation
2
+
3
+ __all__ = [
4
+ "QdrantInstrumentation",
5
+ ]
@@ -0,0 +1,5 @@
1
+ from .instrumentation import WeaviateInstrumentation
2
+
3
+ __all__ = [
4
+ "WeaviateInstrumentation",
5
+ ]
@@ -17,7 +17,7 @@ limitations under the License.
17
17
  import importlib.metadata
18
18
  import logging
19
19
  from typing import Collection
20
-
20
+ from opentelemetry.instrumentation.utils import unwrap
21
21
  from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
22
22
  from opentelemetry.trace import get_tracer
23
23
  from wrapt import wrap_function_wrapper
@@ -28,7 +28,7 @@ from langtrace_python_sdk.instrumentation.weaviate.patch import (
28
28
  )
29
29
  from langtrace_python_sdk.constants.instrumentation.weaviate import APIS
30
30
 
31
- logging.basicConfig(level=logging.FATAL)
31
+ logging.basicConfig(level=logging.DEBUG) # Set to DEBUG for detailed logging
32
32
 
33
33
 
34
34
  class WeaviateInstrumentation(BaseInstrumentor):
@@ -47,17 +47,19 @@ class WeaviateInstrumentation(BaseInstrumentor):
47
47
  for api_name, api_config in APIS.items():
48
48
  module_path, function_name = api_name.rsplit(".", 1)
49
49
  if api_config.get("OPERATION") == "query":
50
- wrap_function_wrapper(
51
- api_config["MODULE"],
52
- api_config["METHOD"],
53
- generic_query_patch(api_name, version, tracer),
54
- )
50
+ if getattr(api_config["MODULE"], api_config["METHOD"], None):
51
+ wrap_function_wrapper(
52
+ api_config["MODULE"],
53
+ api_config["METHOD"],
54
+ generic_query_patch(api_name, version, tracer),
55
+ )
55
56
  elif api_config.get("OPERATION") == "create":
56
- wrap_function_wrapper(
57
- api_config["MODULE"],
58
- api_config["METHOD"],
59
- generic_collection_patch(api_name, version, tracer),
60
- )
57
+ if getattr(api_config["MODULE"], api_config["METHOD"], None):
58
+ wrap_function_wrapper(
59
+ api_config["MODULE"],
60
+ api_config["METHOD"],
61
+ generic_collection_patch(api_name, version, tracer),
62
+ )
61
63
 
62
64
  def _instrument_module(self, module_name):
63
65
  pass
@@ -28,45 +28,23 @@ import sys
28
28
  from opentelemetry.sdk.resources import Resource
29
29
 
30
30
  from langtrace_python_sdk.extensions.langtrace_exporter import LangTraceExporter
31
- from langtrace_python_sdk.instrumentation.anthropic.instrumentation import (
31
+ from langtrace_python_sdk.instrumentation import (
32
32
  AnthropicInstrumentation,
33
- )
34
- from langtrace_python_sdk.instrumentation.chroma.instrumentation import (
35
33
  ChromaInstrumentation,
36
- )
37
- from langtrace_python_sdk.instrumentation.cohere.instrumentation import (
38
34
  CohereInstrumentation,
39
- )
40
- from langtrace_python_sdk.instrumentation.groq.instrumentation import (
41
35
  GroqInstrumentation,
42
- )
43
- from langtrace_python_sdk.instrumentation.langchain.instrumentation import (
44
36
  LangchainInstrumentation,
45
- )
46
- from langtrace_python_sdk.instrumentation.langchain_community.instrumentation import (
47
37
  LangchainCommunityInstrumentation,
48
- )
49
- from langtrace_python_sdk.instrumentation.langchain_core.instrumentation import (
50
38
  LangchainCoreInstrumentation,
51
- )
52
- from langtrace_python_sdk.instrumentation.langgraph.instrumentation import (
53
39
  LanggraphInstrumentation,
54
- )
55
- from langtrace_python_sdk.instrumentation.llamaindex.instrumentation import (
56
40
  LlamaindexInstrumentation,
57
- )
58
- from langtrace_python_sdk.instrumentation.openai.instrumentation import (
59
41
  OpenAIInstrumentation,
60
- )
61
- from langtrace_python_sdk.instrumentation.pinecone.instrumentation import (
62
42
  PineconeInstrumentation,
63
- )
64
- from langtrace_python_sdk.instrumentation.qdrant.instrumentation import (
65
43
  QdrantInstrumentation,
66
- )
67
- from langtrace_python_sdk.instrumentation.weaviate.instrumentation import (
68
44
  WeaviateInstrumentation,
69
45
  )
46
+ from opentelemetry.instrumentation.sqlalchemy import SQLAlchemyInstrumentor
47
+ from colorama import Fore
70
48
 
71
49
 
72
50
  def init(
@@ -77,6 +55,7 @@ def init(
77
55
  api_host: Optional[str] = None,
78
56
  disable_instrumentations: Optional[DisableInstrumentations] = None,
79
57
  ):
58
+ print(Fore.GREEN + "Initializing Langtrace SDK.." + Fore.RESET)
80
59
  provider = TracerProvider(resource=Resource.create({"service.name": sys.argv[0]}))
81
60
 
82
61
  remote_write_exporter = (
@@ -90,20 +69,24 @@ def init(
90
69
  simple_processor_console = SimpleSpanProcessor(console_exporter)
91
70
 
92
71
  if write_spans_to_console:
72
+ print(Fore.BLUE + "Writing spans to console" + Fore.RESET)
93
73
  provider.add_span_processor(simple_processor_console)
94
74
 
95
75
  elif custom_remote_exporter is not None:
76
+ print(Fore.BLUE + "Exporting spans to custom remote exporter.." + Fore.RESET)
96
77
  if batch:
97
78
  provider.add_span_processor(batch_processor_remote)
98
79
  else:
99
80
  provider.add_span_processor(simple_processor_remote)
100
81
 
101
82
  elif api_host is not None:
83
+ print(Fore.BLUE + f"Exporting spans to custom host: {api_host}.." + Fore.RESET)
102
84
  if batch:
103
85
  provider.add_span_processor(batch_processor_remote)
104
86
  else:
105
87
  provider.add_span_processor(simple_processor_remote)
106
88
  else:
89
+ print(Fore.BLUE + "Exporting spans to Langtrace cloud.." + Fore.RESET)
107
90
  provider.add_span_processor(batch_processor_remote)
108
91
 
109
92
  # Initialize tracer
@@ -123,6 +106,7 @@ def init(
123
106
  "anthropic": AnthropicInstrumentation(),
124
107
  "cohere": CohereInstrumentation(),
125
108
  "weaviate": WeaviateInstrumentation(),
109
+ "sqlalchemy": SQLAlchemyInstrumentor(),
126
110
  }
127
111
 
128
112
  init_instrumentations(disable_instrumentations, all_instrumentations)
@@ -126,7 +126,6 @@ def send_user_feedback(data: EvaluationAPIData) -> None:
126
126
  timeout=None,
127
127
  )
128
128
  response.raise_for_status()
129
- print("SENDING FEEDBACK PUT", response.status_code, response.text)
130
129
 
131
130
  else:
132
131
  # Make a POST request to create a new evaluation
@@ -137,7 +136,6 @@ def send_user_feedback(data: EvaluationAPIData) -> None:
137
136
  headers=headers,
138
137
  timeout=None,
139
138
  )
140
- print("Response", response.status_code, response.text)
141
139
  response.raise_for_status()
142
140
 
143
141
  except requests.RequestException as err:
@@ -1 +1 @@
1
- __version__ = "2.1.2"
1
+ __version__ = "2.1.5"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: langtrace-python-sdk
3
- Version: 2.1.2
3
+ Version: 2.1.5
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>
@@ -10,9 +10,11 @@ Classifier: License :: OSI Approved :: Apache Software License
10
10
  Classifier: Operating System :: OS Independent
11
11
  Classifier: Programming Language :: Python :: 3
12
12
  Requires-Python: >=3.9
13
+ Requires-Dist: colorama>=0.4.6
13
14
  Requires-Dist: opentelemetry-api>=1.24.0
14
15
  Requires-Dist: opentelemetry-exporter-otlp-proto-grpc>=1.24.0
15
16
  Requires-Dist: opentelemetry-exporter-otlp-proto-http>=1.24.0
17
+ Requires-Dist: opentelemetry-instrumentation-sqlalchemy>=0.45b0
16
18
  Requires-Dist: opentelemetry-instrumentation>=0.45b0
17
19
  Requires-Dist: opentelemetry-sdk>=1.24.0
18
20
  Requires-Dist: tiktoken>=0.1.1
@@ -32,13 +32,13 @@ 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=9iG5Tk8QExe4cFFI6_mt1pgd5BLCZh64tsU1oPBFXTg,1464
35
+ examples/pinecone_example/basic.py,sha256=b-5-cSf3_N6Gk4zGVecGF47mBcFY9ZrC5ztrIZVgTQo,1430
36
36
  examples/qdrant_example/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
37
37
  examples/qdrant_example/basic.py,sha256=DCMjHSuBZKkhEjCkwy5d5La9WMyW0lCWqtcZWiFCEm4,1425
38
- examples/weaviate_example/query_text.py,sha256=s3f0hYYi-xdbh_LlTBDHegQiVi-4bW_eACb2EnEj8J4,64533
38
+ examples/weaviate_example/query_text.py,sha256=yhBCmJ61llKL5T92s1_R7yihS6koys2AJQWZXSYIT9w,64491
39
39
  langtrace_python_sdk/__init__.py,sha256=R4dv73QARUw4WRfCdSKkKzZTLDumF9jcSdwtVrzWhb4,962
40
- langtrace_python_sdk/langtrace.py,sha256=2VVVeWX3b20jwDY9iqDTxeE-Zunfgt2gfgRs3SreZLU,6993
41
- langtrace_python_sdk/version.py,sha256=UiuBcRXPtXxPUBDdp0ZDvWl0U9Db1kMNfT3oAfhxqLg,22
40
+ langtrace_python_sdk/langtrace.py,sha256=h168V4kyqSezozDnMVar2Xgbi764WvVA_PpSgVuBzz0,6560
41
+ langtrace_python_sdk/version.py,sha256=Ol8KeLnnX1kAXAFgJsZj4d_cZMypHQtaiyICJpuzp64,22
42
42
  langtrace_python_sdk/constants/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
43
43
  langtrace_python_sdk/constants/exporter/langtrace_exporter.py,sha256=5MNjnAOg-4am78J3gVMH6FSwq5N8TOj72ugkhsw4vi0,46
44
44
  langtrace_python_sdk/constants/instrumentation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -52,46 +52,46 @@ langtrace_python_sdk/constants/instrumentation/pinecone.py,sha256=Xaqqw-xBO0JJLG
52
52
  langtrace_python_sdk/constants/instrumentation/qdrant.py,sha256=yL7BopNQTXW7L7Z-gVM2PdusKD7r9qqcATvczFd7NtQ,1999
53
53
  langtrace_python_sdk/constants/instrumentation/weaviate.py,sha256=Iytf2OpB_irZYEmvOQ7Pf483EdG5Bh59GxaBlXck0yY,1501
54
54
  langtrace_python_sdk/extensions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
55
- langtrace_python_sdk/extensions/langtrace_exporter.py,sha256=s-4zc7lba1va_JUReFdLgyBKlvwV1KmBt_OzVmWReQg,3610
56
- langtrace_python_sdk/instrumentation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
57
- langtrace_python_sdk/instrumentation/anthropic/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
55
+ langtrace_python_sdk/extensions/langtrace_exporter.py,sha256=Fj--DzBr4AwTM_iS3lRz0NhqESEyTOZ3SBCA4OevFkE,4127
56
+ langtrace_python_sdk/instrumentation/__init__.py,sha256=htP583cfv32IUvWeck6edRiPQxhk0uzUa1l1vgbtjtY,1042
57
+ langtrace_python_sdk/instrumentation/anthropic/__init__.py,sha256=donrurJAGYlxrSRA3BIf76jGeUcAx9Tq8CVpah68S0Y,101
58
58
  langtrace_python_sdk/instrumentation/anthropic/instrumentation.py,sha256=-srgE8qumAn0ulQYZxMa8ch-9IBH0XgBW_rfEnGk6LI,1684
59
59
  langtrace_python_sdk/instrumentation/anthropic/patch.py,sha256=koAo6bA6nnRDk01fcrArqnyAmgzjxV20ofITMQyKVws,8427
60
- langtrace_python_sdk/instrumentation/chroma/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
60
+ langtrace_python_sdk/instrumentation/chroma/__init__.py,sha256=pNZ5UO8Q-d5VkXSobBf79reB6AmEl_usnnTp5Itv818,95
61
61
  langtrace_python_sdk/instrumentation/chroma/instrumentation.py,sha256=nT6PS6bsrIOO9kLV5GuUeRjMe6THHHAZGvqWBP1dYog,1807
62
62
  langtrace_python_sdk/instrumentation/chroma/patch.py,sha256=1FvA4YvGw9temfBC2g33xGEzIcL1rVdABXwMVTPm3aM,8750
63
- langtrace_python_sdk/instrumentation/cohere/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
63
+ langtrace_python_sdk/instrumentation/cohere/__init__.py,sha256=sGUSLdTUyYf36Tm6L5jQflhzCqvmWrhnBOMYHjvp6Hs,95
64
64
  langtrace_python_sdk/instrumentation/cohere/instrumentation.py,sha256=YQFHZIBd7SSPD4b6Va-ZR0thf_AuBCqj5yzHLHJVWnM,2121
65
65
  langtrace_python_sdk/instrumentation/cohere/patch.py,sha256=hdSWArP0cdfGs0Q5KhkaowkwrYQIzxvF8NpY4sg8p2Q,26563
66
- langtrace_python_sdk/instrumentation/groq/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
66
+ langtrace_python_sdk/instrumentation/groq/__init__.py,sha256=ZXeq_nrej6Lm_uoMFEg8wbSejhjB2UJ5IoHQBPc2-C0,91
67
67
  langtrace_python_sdk/instrumentation/groq/instrumentation.py,sha256=Ttf07XVKhdYY1_fqJc7QWiSdmgEhEVyQB_3Az2_wqYo,1832
68
68
  langtrace_python_sdk/instrumentation/groq/patch.py,sha256=Fo5QbNwScFwhvmXZQezbjF0AdajsHQ8a0f8nKsVFjF8,26068
69
- langtrace_python_sdk/instrumentation/langchain/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
69
+ langtrace_python_sdk/instrumentation/langchain/__init__.py,sha256=-7ZkqQFu64F-cxSFd1ZPrciODKqmUIyUbQQ-eHuQPyM,101
70
70
  langtrace_python_sdk/instrumentation/langchain/instrumentation.py,sha256=_Z4AeNb2hBPSCvMRxE-mUfmkUO_wP_tGGtu-jppWPiI,3462
71
71
  langtrace_python_sdk/instrumentation/langchain/patch.py,sha256=2BT_-DjfSPTmyHDqnpj-gVrMFxRSZugVC-YRPXnuupU,3796
72
- langtrace_python_sdk/instrumentation/langchain_community/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
72
+ langtrace_python_sdk/instrumentation/langchain_community/__init__.py,sha256=mj5RR_cfkjMql7W9OyyhmviT2GZ-4Pv9XJfGwJufp_E,119
73
73
  langtrace_python_sdk/instrumentation/langchain_community/instrumentation.py,sha256=-9E2-8-XR5PQ5ON-_ib53p5Tp0uD4MT4Ioh4MlWlF2k,5192
74
74
  langtrace_python_sdk/instrumentation/langchain_community/patch.py,sha256=uyRUp02M9mYjLsr36ZBCvJC7s40AGry3R_EcjvXaoWk,3751
75
- langtrace_python_sdk/instrumentation/langchain_core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
75
+ langtrace_python_sdk/instrumentation/langchain_core/__init__.py,sha256=kumE_reeqgM-ZvEZ6-XxyT-F-HAdKq_v_PKvsLb4EZQ,110
76
76
  langtrace_python_sdk/instrumentation/langchain_core/instrumentation.py,sha256=KNXHtlnq80akLACF-vbPCo9oVXhnVjYIM1Lo7kNRwEg,5937
77
77
  langtrace_python_sdk/instrumentation/langchain_core/patch.py,sha256=Kqpv77ZKrZ4QMit36JtN59ubtWE8pX6t8gg6OOmIii0,8458
78
- langtrace_python_sdk/instrumentation/langgraph/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
78
+ langtrace_python_sdk/instrumentation/langgraph/__init__.py,sha256=eitlHloY-aZ4ZuIEJx61AadEA3G7siyecP-V-lziAr8,101
79
79
  langtrace_python_sdk/instrumentation/langgraph/instrumentation.py,sha256=SUZZhWSIbcfsF1S5NtEqW8QzkRM_pKAuXB7pwk5tsOU,2526
80
80
  langtrace_python_sdk/instrumentation/langgraph/patch.py,sha256=fr90kuPokwxP2BGP2tU793ReDOp2FtehKMcsxS9tS_0,4589
81
- langtrace_python_sdk/instrumentation/llamaindex/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
81
+ langtrace_python_sdk/instrumentation/llamaindex/__init__.py,sha256=rHvuqpuQKLj57Ow7vuKRqxAN5jT0b5NBeHwhXbbnRa4,103
82
82
  langtrace_python_sdk/instrumentation/llamaindex/instrumentation.py,sha256=8iAg-Oxwf2W4S60qRfO5mvzORYxublgq7FdGWqUB4q8,2965
83
83
  langtrace_python_sdk/instrumentation/llamaindex/patch.py,sha256=q99qmEBNH54Oi_sHCIGBQFpIE4zaNKVjIWARlX8fJ-M,4189
84
- langtrace_python_sdk/instrumentation/openai/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
84
+ langtrace_python_sdk/instrumentation/openai/__init__.py,sha256=VPHRNCQEdkizIVP2d0Uw_a7t8XOTSTprEIB8oboJFbs,95
85
85
  langtrace_python_sdk/instrumentation/openai/instrumentation.py,sha256=G2HSZfr6DuP2n-8v0h91M60m0DJWFBcru4-1FQJl-5A,2726
86
86
  langtrace_python_sdk/instrumentation/openai/patch.py,sha256=xi87lLHoj81xSx6MiqTAKWr3MLxXpMf84NzJ5uDm134,37288
87
- langtrace_python_sdk/instrumentation/pinecone/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
87
+ langtrace_python_sdk/instrumentation/pinecone/__init__.py,sha256=DzXyGh9_MGWveJvXULkFwdkf7PbG2s3bAWtT1Dmz7Ok,99
88
88
  langtrace_python_sdk/instrumentation/pinecone/instrumentation.py,sha256=mxQXe3oAOPLsMJGlEzAe6zpgK7RtWfqmcNmGW_gQXX4,1900
89
89
  langtrace_python_sdk/instrumentation/pinecone/patch.py,sha256=8uenVh4TCTJVuBGepm7nhTZBuW7HyjlZS4wPx7zi9cg,4879
90
- langtrace_python_sdk/instrumentation/qdrant/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
90
+ langtrace_python_sdk/instrumentation/qdrant/__init__.py,sha256=TaIGSAEPysrL23KJ5FcEL1tfQogrKCtEQ75_u62eqso,95
91
91
  langtrace_python_sdk/instrumentation/qdrant/instrumentation.py,sha256=vl2eKSP55aqDo1JiRlvOUBrr6kddvG9Z5dCYew2OG08,1816
92
92
  langtrace_python_sdk/instrumentation/qdrant/patch.py,sha256=KcUWmvnS3PgPStzs1oWmlZsyomKBl3dmg8nXuR0T1C0,4654
93
- langtrace_python_sdk/instrumentation/weaviate/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
94
- langtrace_python_sdk/instrumentation/weaviate/instrumentation.py,sha256=i5xi0uWY1pPvGWyedFEvOtbRVT7ybFnMia-9TYFigOA,2309
93
+ langtrace_python_sdk/instrumentation/weaviate/__init__.py,sha256=Mc-Je6evPo-kKQzerTG7bd1XO5JOh4YGTE3wBxaUBwg,99
94
+ langtrace_python_sdk/instrumentation/weaviate/instrumentation.py,sha256=4BnHRzXOKEauy2TNTZwpIagDFUp03CUyBZCdE2vinxk,2596
95
95
  langtrace_python_sdk/instrumentation/weaviate/patch.py,sha256=ig2fc33hNydEcH5cJWRycFnMXiXiJr731J-Vg5Ze4No,5634
96
96
  langtrace_python_sdk/types/__init__.py,sha256=-j8cuz3bhUdOqj7N2c0w5y-j3UmcxwEgNh8BWeXwHoI,813
97
97
  langtrace_python_sdk/utils/__init__.py,sha256=MbBqT4NpDCNTqqvZ0lG4tRiFFZ-tlM8Dwophg4xyrRw,148
@@ -100,7 +100,7 @@ langtrace_python_sdk/utils/misc.py,sha256=CD9NWRLxLpFd0YwlHJqzlpFNedXVWtAKGOjQWn
100
100
  langtrace_python_sdk/utils/prompt_registry.py,sha256=7FFB4Pj0414qgf02h5zL5vXBZgNBf74g4Iq7GdFaIO0,2689
101
101
  langtrace_python_sdk/utils/silently_fail.py,sha256=F_9EteXCO9Cyq-8MA1OT2Zy_dx8n06nt31I7t7ui24E,478
102
102
  langtrace_python_sdk/utils/types.py,sha256=l-N6o7cnWUyrD6dBvW7W3Pf5CkPo5QaoT__k1XLbrQg,383
103
- langtrace_python_sdk/utils/with_root_span.py,sha256=H20e-LeRFHHSmdXlZhkWas33ImgEKihlVqAtoYi4iNA,6103
103
+ langtrace_python_sdk/utils/with_root_span.py,sha256=rSPrTnKndJo6cFUWL4907IkJFbtLwqMS87paADUxD6A,5957
104
104
  tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
105
105
  tests/conftest.py,sha256=0Jo6iCZTXbdvyJVhG9UpYGkLabL75378oauCzmt-Sa8,603
106
106
  tests/utils.py,sha256=hP8sTH-M8WO6zlLkSFHPf6483ZcKEcnxul6JIIb1pLM,1396
@@ -119,9 +119,9 @@ tests/cohere/cassettes/test_cohere_chat.yaml,sha256=iQIhJwmWe2AQDmdguL6L0SZOPMD6
119
119
  tests/cohere/cassettes/test_cohere_chat_streaming.yaml,sha256=tMlz7IPZYRCJUeMCwyXrA4O4zpcqIPpQ5hU9I5f352Q,8174
120
120
  tests/cohere/cassettes/test_cohere_embed.yaml,sha256=Svcyw8WkVMVw4cocWQzGOdUVmWi5AM6Gb9t9VLlyOjM,27320
121
121
  tests/cohere/cassettes/test_cohere_rerank.yaml,sha256=RsJ8804lTktI0FKEFCw0M4ztStZbCxb_z_VRmrw8ooQ,2393
122
- tests/langchain/test_langchain.py,sha256=p1YkeL1U23b0E3vhEcXonwMa3QGUswQjKNReMbV0ndA,2576
123
- tests/langchain/test_langchain_community.py,sha256=B7Z7YRx7v9507wEyDnXV1NKVYo4r2XU0YplugfYVsJ0,2615
124
- tests/langchain/test_langchain_core.py,sha256=LBeoK27-uDethSvBGykYAlCVfEwljQrN7sZL91TVCPw,4467
122
+ tests/langchain/conftest.py,sha256=f29apdevxg7AM0mPQ1LoEd-yStGruqGLTQUp29heLJo,1116
123
+ tests/langchain/test_langchain.py,sha256=QP11RdNDX_ztF1ppPnUiui3SsxYYdzVsDgtI-1OGH48,893
124
+ tests/langchain/cassettes/test_langchain.yaml,sha256=KPBTVIYMUPFaSNpwrTDgWzsu4p3hHj_yNDoudDa-Jis,3755
125
125
  tests/openai/conftest.py,sha256=BkehS6heg-O91Nzoc4546OSiAzy8KgSgk7VCO3A11zM,700
126
126
  tests/openai/test_chat_completion.py,sha256=-TwCAF2czsiGZqETQvMOgmIJgdFWycJ9nOeO5q65AJs,5804
127
127
  tests/openai/test_embeddings.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -137,7 +137,7 @@ tests/pinecone/cassettes/test_query.yaml,sha256=b5v9G3ssUy00oG63PlFUR3JErF2Js-5A
137
137
  tests/pinecone/cassettes/test_upsert.yaml,sha256=neWmQ1v3d03V8WoLl8FoFeeCYImb8pxlJBWnFd_lITU,38607
138
138
  tests/qdrant/conftest.py,sha256=9n0uHxxIjWk9fbYc4bx-uP8lSAgLBVx-cV9UjnsyCHM,381
139
139
  tests/qdrant/test_qdrant.py,sha256=pzjAjVY2kmsmGfrI2Gs2xrolfuaNHz7l1fqGQCjp5_o,3353
140
- langtrace_python_sdk-2.1.2.dist-info/METADATA,sha256=4kaLgCo0f7qBqUWa7gRKBEj-_Sl57Iw-MuN1lqCTwAY,11738
141
- langtrace_python_sdk-2.1.2.dist-info/WHEEL,sha256=zEMcRr9Kr03x1ozGwg5v9NQBKn3kndp6LSoSlVg-jhU,87
142
- langtrace_python_sdk-2.1.2.dist-info/licenses/LICENSE,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
143
- langtrace_python_sdk-2.1.2.dist-info/RECORD,,
140
+ langtrace_python_sdk-2.1.5.dist-info/METADATA,sha256=YMAZgu-2MfYrXYBr3CWOi7FMHV2OOmcyuKknp4Za7Nc,11833
141
+ langtrace_python_sdk-2.1.5.dist-info/WHEEL,sha256=zEMcRr9Kr03x1ozGwg5v9NQBKn3kndp6LSoSlVg-jhU,87
142
+ langtrace_python_sdk-2.1.5.dist-info/licenses/LICENSE,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
143
+ langtrace_python_sdk-2.1.5.dist-info/RECORD,,
@@ -0,0 +1,106 @@
1
+ interactions:
2
+ - request:
3
+ body: '{"messages": [{"content": "You are world class technical documentation
4
+ writer.", "role": "system"}, {"content": "how can langsmith help with testing?",
5
+ "role": "user"}], "model": "gpt-3.5-turbo", "n": 1, "stream": false, "temperature":
6
+ 0.7}'
7
+ headers:
8
+ accept:
9
+ - application/json
10
+ accept-encoding:
11
+ - gzip, deflate
12
+ connection:
13
+ - keep-alive
14
+ content-length:
15
+ - '240'
16
+ content-type:
17
+ - application/json
18
+ host:
19
+ - api.openai.com
20
+ user-agent:
21
+ - OpenAI/Python 1.30.5
22
+ x-stainless-arch:
23
+ - arm64
24
+ x-stainless-async:
25
+ - 'false'
26
+ x-stainless-lang:
27
+ - python
28
+ x-stainless-os:
29
+ - MacOS
30
+ x-stainless-package-version:
31
+ - 1.30.5
32
+ x-stainless-runtime:
33
+ - CPython
34
+ x-stainless-runtime-version:
35
+ - 3.12.3
36
+ method: POST
37
+ uri: https://api.openai.com/v1/chat/completions
38
+ response:
39
+ body:
40
+ string: !!binary |
41
+ H4sIAAAAAAAAA3xVTW8bOQy9+1cQc7aNfLR16tv2A4tFt9hL9rRdBLSGnlGikVSSsuMt8t8X1Iwd
42
+ pwh6MWxRfHp8fKR/zAAa3zZraFyP6oYcFu//br/s3+271XUeVvfb+0f6cvv4x8MHyjf4tZlbRtrc
43
+ k9Nj1tKlIQdSn+IYdkyoZKiXq8vVxc3NxeqmBobUUrC0Luvievl2oYU3aXFxefV2yuyTdyTNGv6Z
44
+ AQD8qJ/GMbb02KzhYn48GUgEO2rWp0sADadgJw2KeFGM2syfgy5FpVhp/4mxk8FrD14AIac98bYE
45
+ 0JQCaI8KDiP0FDLs7ZaSqI8d+Ag7ZJ+KwB4Psv4Wv8XLJfxWNA1WMtyOF9fw/IIhbQiKUAuaYM9e
46
+ CfCUYdAgjn1WgW1iOKTCIGmre2QCzDl4hyauLOHDAQLtiLGrbFQgohbGAAFjV7AjyJwciVjcYcaN
47
+ D149ydxwK5eRQH3WoZBYUTmgj/A5dsFLP4cBH0Z8IBRPXHnFFBdKro/eYQAlHGCgYUMsVpaJy35T
48
+ DDqB9nTSbCK0NK2ullUh+ISK8DtF4lrZz3J1Y2Ri2drlDZp+KUJmamnrI7XAJZAAxhYyqhJHmdee
49
+ 2atW7ffi3UM4wOjHZzChc6lfKnzbezm2LCOrdyUgh4P1zxxiacfKxFE0N8hoGabvxVvLICB3BDik
50
+ EhXSFlq/Ixaqj1cdricdPqIQfMWIHQ0U9Re2Sdxh9P9RLXeoGWc9fKVl1gVG91B7kTl1TCJG5sge
51
+ nfpd9UbFpCiFCWyWmXqK4nf2q5qNLO8XvrSS3izhU3LFyni1pxgknU1UO901Jud11O9MUoLKvBJL
52
+ 2tNJ8wVTqGPj4zbxUF+qYzENlHkzHI4GMvD2nJR5HUGUi9PC1MII8jwcJxWiLRCK7lA5uIDs9WDp
53
+ VYajhi/Aqwx/mWAhzH+qXpQJh+AjvTYbc/BD5rQ7tnRSfT41psfojFMIuEnjxJi5qnJnU+jjLoVd
54
+ 1eaVJi+baRM+nVZoSF3mtLF1G0sIp/Otj176OyaUFG1diqY8pj/NAP6tq7q82L5N5jRkvdP0QNEA
55
+ r1YjXPP853AWvHw/RTUphrPAm3eziWEjB1Ea7rY+dsSZfd3cxnP2NPsfAAD//wMAt4ZeGbgGAAA=
56
+ headers:
57
+ CF-Cache-Status:
58
+ - DYNAMIC
59
+ CF-RAY:
60
+ - 88c03f46bf3b23c5-LHR
61
+ Connection:
62
+ - keep-alive
63
+ Content-Encoding:
64
+ - gzip
65
+ Content-Type:
66
+ - application/json
67
+ Date:
68
+ - Thu, 30 May 2024 16:54:42 GMT
69
+ Server:
70
+ - cloudflare
71
+ Set-Cookie:
72
+ - __cf_bm=9en.DN2CPQUgM8CubXIqqiVZkm43q.oBCL4n7bXxViw-1717088082-1.0.1.1-nl9dbPbwwGsUORjX1Y8Ta7S2v.MBG3o1JWUgYQU98tFUNcY9hFcmfcXWFu_bcohUX1nun6S55Wg2rg3MX7PHPQ;
73
+ path=/; expires=Thu, 30-May-24 17:24:42 GMT; domain=.api.openai.com; HttpOnly;
74
+ Secure; SameSite=None
75
+ - _cfuvid=bJ_po6.pyb_9JWu27O8yfh1AX1atGjC5_sFN497eMI8-1717088082420-0.0.1.1-604800000;
76
+ path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None
77
+ Transfer-Encoding:
78
+ - chunked
79
+ alt-svc:
80
+ - h3=":443"; ma=86400
81
+ openai-organization:
82
+ - scale3-1
83
+ openai-processing-ms:
84
+ - '4295'
85
+ openai-version:
86
+ - '2020-10-01'
87
+ strict-transport-security:
88
+ - max-age=15724800; includeSubDomains
89
+ x-ratelimit-limit-requests:
90
+ - '10000'
91
+ x-ratelimit-limit-tokens:
92
+ - '2000000'
93
+ x-ratelimit-remaining-requests:
94
+ - '9999'
95
+ x-ratelimit-remaining-tokens:
96
+ - '1999960'
97
+ x-ratelimit-reset-requests:
98
+ - 6ms
99
+ x-ratelimit-reset-tokens:
100
+ - 1ms
101
+ x-request-id:
102
+ - req_4b43c2d3cf0dc839647c8b775b75d6f5
103
+ status:
104
+ code: 200
105
+ message: OK
106
+ version: 1
@@ -0,0 +1,42 @@
1
+ """Unit tests configuration module."""
2
+
3
+ import os
4
+ import pytest
5
+
6
+ from langtrace_python_sdk.instrumentation.openai.instrumentation import (
7
+ OpenAIInstrumentation,
8
+ )
9
+ from langtrace_python_sdk.instrumentation.langchain.instrumentation import (
10
+ LangchainInstrumentation,
11
+ )
12
+ from langtrace_python_sdk.instrumentation.langchain_core.instrumentation import (
13
+ LangchainCoreInstrumentation,
14
+ )
15
+
16
+ from langtrace_python_sdk.instrumentation.langchain_community.instrumentation import (
17
+ LangchainCommunityInstrumentation,
18
+ )
19
+
20
+
21
+ @pytest.fixture(autouse=True)
22
+ def clear_exporter(exporter):
23
+ exporter.clear()
24
+
25
+
26
+ @pytest.fixture(autouse=True)
27
+ def environment():
28
+ if not os.environ.get("OPENAI_API_KEY"):
29
+ os.environ["OPENAI_API_KEY"] = "test"
30
+
31
+
32
+ @pytest.fixture(scope="module")
33
+ def vcr_config():
34
+ return {"filter_headers": ["authorization", "x-api-key"]}
35
+
36
+
37
+ @pytest.fixture(scope="session", autouse=True)
38
+ def instrument():
39
+ OpenAIInstrumentation().instrument()
40
+ LangchainInstrumentation().instrument()
41
+ LangchainCoreInstrumentation().instrument()
42
+ LangchainCommunityInstrumentation().instrument()
@@ -1,82 +1,28 @@
1
- import unittest
2
- from unittest.mock import MagicMock, call
3
- from langtrace_python_sdk.instrumentation.langchain.patch import generic_patch
4
- from opentelemetry.trace import SpanKind
5
- from opentelemetry.trace import get_tracer
6
- import importlib.metadata
7
- from langtrace_python_sdk.constants.instrumentation.openai import APIS
8
- from opentelemetry.trace.status import Status, StatusCode
9
- from tests.utils import common_setup
10
- import json
11
-
12
-
13
- class TestGenericPatch(unittest.TestCase):
14
- data = {"key": "value"}
15
-
16
- def setUp(self):
17
- self.langchain_mock, self.tracer, self.span = common_setup(self.data, None)
18
-
19
- def tearDown(self):
20
- # Clean up after each test case
21
- pass
22
-
23
- def test_generic_patch(self):
24
- # Arrange
25
- method_name = "example_method"
26
- trace_output = False
27
- trace_input = False # Change as per your requirement
28
- args = (1, 2, 3)
29
- task = "split_text"
30
- kwargs = {"key": "value"}
31
- version = importlib.metadata.version("langchain")
32
-
33
- # Act
34
- wrapped_function = generic_patch(
35
- "langchain.text_splitter",
36
- task,
37
- self.tracer,
38
- version,
39
- trace_output,
40
- trace_input,
41
- )
42
- result = wrapped_function(self.langchain_mock, MagicMock(), args, kwargs)
43
-
44
- # Assert
45
- self.assertTrue(
46
- self.tracer.start_as_current_span.called_once_with(
47
- method_name, kind=SpanKind.CLIENT
48
- )
49
- )
50
-
51
- service_provider = "Langchain"
52
- expected_attributes = {
53
- "langtrace.sdk.name": "langtrace-python-sdk",
54
- "langtrace.service.name": service_provider,
55
- "langtrace.service.type": "framework",
56
- "langtrace.service.version": version,
57
- "langtrace.version": "1.0.0",
58
- "langchain.task.name": task,
59
- }
60
-
61
- self.assertTrue(
62
- self.span.set_attribute.has_calls(
63
- [call(key, value) for key, value in expected_attributes.items()],
64
- any_order=True,
65
- )
66
- )
67
-
68
- actual_calls = self.span.set_attribute.call_args_list
69
-
70
- for key, value in expected_attributes.items():
71
- self.assertIn(call(key, value), actual_calls)
72
-
73
- self.assertEqual(self.span.set_status.call_count, 1)
74
- self.assertTrue(self.span.set_status.has_calls([call(Status(StatusCode.OK))]))
75
-
76
- expected_result_data = {"key": "value"}
77
-
78
- self.assertEqual(result.key, expected_result_data["key"])
79
-
80
-
81
- if __name__ == "__main__":
82
- unittest.main()
1
+ import pytest
2
+ from langchain_openai import ChatOpenAI
3
+ from langchain_core.prompts.chat import ChatPromptTemplate
4
+ from langchain_core.output_parsers import StrOutputParser
5
+
6
+
7
+ @pytest.mark.vcr()
8
+ def test_langchain(exporter):
9
+ llm = ChatOpenAI()
10
+ prompt = ChatPromptTemplate.from_messages(
11
+ [
12
+ ("system", "You are world class technical documentation writer."),
13
+ ("user", "{input}"),
14
+ ]
15
+ )
16
+ output_parser = StrOutputParser()
17
+ chain = prompt | llm | output_parser
18
+ chain.invoke({"input": "how can langsmith help with testing?"})
19
+ spans = exporter.get_finished_spans()
20
+
21
+ assert [
22
+ "ChatPromptTemplate.invoke",
23
+ "openai.chat.completions.create",
24
+ "StrOutputParser.parse",
25
+ "StrOutputParser.parse_result",
26
+ "StrOutputParser.invoke",
27
+ "RunnableSequence.invoke",
28
+ ] == [span.name for span in spans]
@@ -1,82 +0,0 @@
1
- import unittest
2
- from unittest.mock import MagicMock, Mock, patch, call
3
- from langtrace_python_sdk.instrumentation.langchain_community.patch import generic_patch
4
- from opentelemetry.trace import SpanKind
5
- from opentelemetry.trace import get_tracer
6
- import importlib.metadata
7
- import openai
8
- from langtrace_python_sdk.constants.instrumentation.openai import APIS
9
- from opentelemetry.trace.status import Status, StatusCode
10
- import json
11
- from tests.utils import common_setup
12
-
13
-
14
- class TestGenericPatch(unittest.TestCase):
15
- data = {"key": "value"}
16
-
17
- def setUp(self):
18
- self.langchain_mock, self.tracer, self.span = common_setup(self.data, None)
19
-
20
- def tearDown(self):
21
- # Clean up after each test case
22
- pass
23
-
24
- def test_generic_patch(self):
25
- # Arrange
26
- method_name = "example_method"
27
- trace_output = False
28
- trace_input = False
29
- args = (1, 2, 3)
30
- task = "vector_store"
31
- kwargs = {"key": "value"}
32
- version = importlib.metadata.version("langchain-community")
33
-
34
- # Act
35
- wrapped_function = generic_patch(
36
- "langchain_community.vectorstores.faiss",
37
- task,
38
- self.tracer,
39
- version,
40
- trace_output,
41
- trace_input,
42
- )
43
- result = wrapped_function(self.langchain_mock, MagicMock(), args, kwargs)
44
-
45
- # Assert
46
- self.assertTrue(
47
- self.tracer.start_as_current_span.called_once_with(
48
- method_name, kind=SpanKind.CLIENT
49
- )
50
- )
51
-
52
- service_provider = "Langchain Community"
53
- expected_attributes = {
54
- "langtrace.sdk.name": "langtrace-python-sdk",
55
- "langtrace.service.name": service_provider,
56
- "langtrace.service.type": "framework",
57
- "langtrace.service.version": version,
58
- "langtrace.version": "1.0.0",
59
- "langchain.task.name": task,
60
- }
61
-
62
- self.assertTrue(
63
- self.span.set_attribute.has_calls(
64
- [call(key, value) for key, value in expected_attributes.items()],
65
- any_order=True,
66
- )
67
- )
68
-
69
- actual_calls = self.span.set_attribute.call_args_list
70
-
71
- for key, value in expected_attributes.items():
72
- self.assertIn(call(key, value), actual_calls)
73
-
74
- self.assertEqual(self.span.set_status.call_count, 1)
75
- self.assertTrue(self.span.set_status.has_calls([call(Status(StatusCode.OK))]))
76
-
77
- expected_result_data = {"key": "value"}
78
- self.assertEqual(result.key, expected_result_data["key"])
79
-
80
-
81
- if __name__ == "__main__":
82
- unittest.main()
@@ -1,141 +0,0 @@
1
- import unittest
2
- from unittest.mock import MagicMock, Mock, patch, call
3
- from langtrace_python_sdk.instrumentation.langchain_core.patch import (
4
- generic_patch,
5
- runnable_patch,
6
- )
7
- from opentelemetry.trace import SpanKind
8
- from opentelemetry.trace import get_tracer
9
- import importlib.metadata
10
- import openai
11
- from langtrace_python_sdk.constants.instrumentation.openai import APIS
12
- from opentelemetry.trace.status import Status, StatusCode
13
- import json
14
- from tests.utils import common_setup
15
-
16
-
17
- class TestGenericPatch(unittest.TestCase):
18
- data = {"items": "value"}
19
-
20
- def setUp(self):
21
- self.langchain_mock, self.tracer, self.span = common_setup(self.data, None)
22
-
23
- def tearDown(self):
24
- # Clean up after each test case
25
- pass
26
-
27
- def test_generic_patch(self):
28
- # Arrange
29
- method_name = "example_method"
30
- trace_output = False
31
- trace_input = True
32
- task = "retriever"
33
- args = (1, 2, 3)
34
- kwargs = {"key": "value"}
35
- version = importlib.metadata.version("langchain-core")
36
-
37
- # Act
38
- wrapped_function = generic_patch(
39
- "langchain_core.retrievers",
40
- task,
41
- self.tracer,
42
- version,
43
- trace_output,
44
- trace_input,
45
- )
46
- result = wrapped_function(self.langchain_mock, MagicMock(), args, kwargs)
47
-
48
- # Assert
49
- self.assertTrue(
50
- self.tracer.start_as_current_span.called_once_with(
51
- method_name, kind=SpanKind.CLIENT
52
- )
53
- )
54
-
55
- service_provider = "Langchain Core"
56
- expected_attributes = {
57
- "langtrace.sdk.name": "langtrace-python-sdk",
58
- "langtrace.service.name": service_provider,
59
- "langtrace.service.type": "framework",
60
- "langtrace.service.version": version,
61
- "langtrace.version": "1.0.0",
62
- "langchain.task.name": task,
63
- }
64
-
65
- self.assertTrue(
66
- self.span.set_attribute.has_calls(
67
- [call(key, value) for key, value in expected_attributes.items()],
68
- any_order=True,
69
- )
70
- )
71
-
72
- actual_calls = self.span.set_attribute.call_args_list
73
- for key, value in expected_attributes.items():
74
- self.assertIn(call(key, value), actual_calls)
75
-
76
- self.assertEqual(self.span.set_status.call_count, 1)
77
- self.assertTrue(self.span.set_status.has_calls([call(Status(StatusCode.OK))]))
78
-
79
- expected_result_data = {"items": "value"}
80
- self.assertEqual(result.items, expected_result_data["items"])
81
-
82
- def test_runnable_patch(self):
83
- # Arrange
84
- method_name = "example_method"
85
- trace_output = False
86
- trace_input = True
87
- args = (1, 2, 3)
88
- kwargs = {"key": "value"}
89
- version = importlib.metadata.version("langchain-core")
90
-
91
- # Act
92
- wrapped_function = runnable_patch(
93
- "langchain_core.runnables.passthrough",
94
- "runnablepassthrough",
95
- self.tracer,
96
- version,
97
- trace_output,
98
- trace_input,
99
- )
100
-
101
- result = wrapped_function(self.langchain_mock, MagicMock(), args, kwargs)
102
-
103
- # Assert
104
- self.assertTrue(
105
- self.tracer.start_as_current_span.called_once_with(
106
- method_name, kind=SpanKind.CLIENT
107
- )
108
- )
109
-
110
- service_provider = "Langchain Core"
111
- expected_attributes = {
112
- "langtrace.sdk.name": "langtrace-python-sdk",
113
- "langtrace.service.name": service_provider,
114
- "langtrace.service.type": "framework",
115
- "langtrace.service.version": version,
116
- "langtrace.version": "1.0.0",
117
- "langchain.task.name": "runnablepassthrough",
118
- }
119
-
120
- self.assertTrue(
121
- self.span.set_attribute.has_calls(
122
- [call(key, value) for key, value in expected_attributes.items()],
123
- any_order=True,
124
- )
125
- )
126
-
127
- actual_calls = self.span.set_attribute.call_args_list
128
-
129
- for key, value in expected_attributes.items():
130
- self.assertIn(call(key, value), actual_calls)
131
-
132
- self.assertEqual(self.span.set_status.call_count, 1)
133
- self.assertTrue(self.span.set_status.has_calls([call(Status(StatusCode.OK))]))
134
-
135
- expected_result_data = {"items": "value"}
136
-
137
- self.assertEqual(result.items, expected_result_data["items"])
138
-
139
-
140
- if __name__ == "__main__":
141
- unittest.main()