langtrace-python-sdk 2.1.19__py3-none-any.whl → 2.1.21__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.
@@ -0,0 +1,42 @@
1
+ import dspy
2
+ from dspy.datasets.gsm8k import GSM8K, gsm8k_metric
3
+ from dspy.teleprompt import BootstrapFewShot
4
+
5
+ # flake8: noqa
6
+ from langtrace_python_sdk import langtrace, with_langtrace_root_span
7
+
8
+ langtrace.init()
9
+
10
+ turbo = dspy.OpenAI(model="gpt-3.5-turbo", max_tokens=250)
11
+ dspy.settings.configure(lm=turbo)
12
+
13
+ # Load math questions from the GSM8K dataset
14
+ gsm8k = GSM8K()
15
+ gsm8k_trainset, gsm8k_devset = gsm8k.train[:10], gsm8k.dev[:10]
16
+
17
+
18
+ class CoT(dspy.Module):
19
+ def __init__(self):
20
+ super().__init__()
21
+ self.prog = dspy.ChainOfThought("question -> answer")
22
+
23
+ def forward(self, question):
24
+ return self.prog(question=question)
25
+
26
+
27
+ @with_langtrace_root_span(name="math_problems_cot_example")
28
+ def example():
29
+
30
+ # Set up the optimizer: we want to "bootstrap" (i.e., self-generate) 4-shot examples of our CoT program.
31
+ config = dict(max_bootstrapped_demos=4, max_labeled_demos=4)
32
+
33
+ # Optimize! Use the `gsm8k_metric` here. In general, the metric is going to tell the optimizer how well it's doing.
34
+ teleprompter = BootstrapFewShot(metric=gsm8k_metric, **config)
35
+ optimized_cot = teleprompter.compile(CoT(), trainset=gsm8k_trainset)
36
+
37
+ ans = optimized_cot(question="What is the sqrt of 345?")
38
+ print(ans)
39
+
40
+
41
+ if __name__ == "__main__":
42
+ example()
@@ -0,0 +1,35 @@
1
+ import dspy
2
+
3
+ # flake8: noqa
4
+ from langtrace_python_sdk import langtrace, with_langtrace_root_span
5
+
6
+ langtrace.init()
7
+
8
+ turbo = dspy.OpenAI(model="gpt-3.5-turbo", max_tokens=250)
9
+ dspy.settings.configure(lm=turbo)
10
+
11
+
12
+ # Define a simple signature for basic question answering
13
+ class BasicQA(dspy.Signature):
14
+ """Answer questions with short factoid answers."""
15
+
16
+ question = dspy.InputField()
17
+ answer = dspy.OutputField(desc="often between 1 and 5 words")
18
+
19
+
20
+ @with_langtrace_root_span(name="pot_example")
21
+ def example():
22
+
23
+ # Pass signature to ProgramOfThought Module
24
+ pot = dspy.ProgramOfThought(BasicQA)
25
+
26
+ # Call the ProgramOfThought module on a particular input
27
+ question = "Sarah has 5 apples. She buys 7 more apples from the store. How many apples does Sarah have now?"
28
+ result = pot(question=question)
29
+
30
+ print(f"Question: {question}")
31
+ print(f"Final Predicted Answer (after ProgramOfThought process): {result.answer}")
32
+
33
+
34
+ if __name__ == "__main__":
35
+ example()
@@ -0,0 +1,113 @@
1
+ import dspy
2
+ import json
3
+ from dspy.datasets import HotPotQA
4
+ from dspy.teleprompt import BootstrapFewShot
5
+ from dspy.evaluate.evaluate import Evaluate
6
+
7
+ # flake8: noqa
8
+ from langtrace_python_sdk import langtrace, with_langtrace_root_span
9
+
10
+ langtrace.init()
11
+
12
+
13
+ colbertv2_wiki17_abstracts = dspy.ColBERTv2(
14
+ url="http://20.102.90.50:2017/wiki17_abstracts"
15
+ )
16
+ dspy.settings.configure(rm=colbertv2_wiki17_abstracts)
17
+ turbo = dspy.OpenAI(model="gpt-3.5-turbo-0613", max_tokens=500)
18
+ dspy.settings.configure(lm=turbo, trace=[], temperature=0.7)
19
+
20
+ dataset = HotPotQA(
21
+ train_seed=1,
22
+ train_size=300,
23
+ eval_seed=2023,
24
+ dev_size=300,
25
+ test_size=0,
26
+ keep_details=True,
27
+ )
28
+ trainset = [x.with_inputs("question", "answer") for x in dataset.train]
29
+ devset = [x.with_inputs("question", "answer") for x in dataset.dev]
30
+
31
+
32
+ class GenerateAnswerChoices(dspy.Signature):
33
+ """Generate answer choices in JSON format that include the correct answer and plausible distractors for the specified question."""
34
+
35
+ question = dspy.InputField()
36
+ correct_answer = dspy.InputField()
37
+ number_of_choices = dspy.InputField()
38
+ answer_choices = dspy.OutputField(desc="JSON key-value pairs")
39
+
40
+
41
+ class QuizAnswerGenerator(dspy.Module):
42
+ def __init__(self):
43
+ super().__init__()
44
+ self.prog = dspy.ChainOfThought(GenerateAnswerChoices)
45
+
46
+ def forward(self, question, answer):
47
+ choices = self.prog(
48
+ question=question, correct_answer=answer, number_of_choices="4"
49
+ ).answer_choices
50
+ # dspy.Suggest(
51
+ # format_checker(choices),
52
+ # "The format of the answer choices should be in JSON format. Please revise accordingly.",
53
+ # target_module=GenerateAnswerChoices,
54
+ # )
55
+ return dspy.Prediction(choices=choices)
56
+
57
+
58
+ def format_checker(choice_string):
59
+ try:
60
+ choices = json.loads(choice_string)
61
+ if isinstance(choices, dict) and all(
62
+ isinstance(key, str) and isinstance(value, str)
63
+ for key, value in choices.items()
64
+ ):
65
+ return True
66
+ except json.JSONDecodeError:
67
+ return False
68
+
69
+ return False
70
+
71
+
72
+ def format_valid_metric(gold, pred, trace=None):
73
+ generated_choices = pred.choices
74
+ format_valid = format_checker(generated_choices)
75
+ score = format_valid
76
+ return score
77
+
78
+
79
+ @with_langtrace_root_span(name="quiz_generator_1")
80
+ def quiz_generator_1():
81
+ quiz_generator = QuizAnswerGenerator()
82
+
83
+ example = devset[67]
84
+ print("Example Question: ", example.question)
85
+ print("Example Answer: ", example.answer)
86
+ # quiz_choices = quiz_generator(question=example.question, answer=example.answer)
87
+ # print("Generated Quiz Choices: ", quiz_choices.choices)
88
+
89
+ optimizer = BootstrapFewShot(
90
+ metric=format_valid_metric, max_bootstrapped_demos=4, max_labeled_demos=4
91
+ )
92
+ compiled_quiz_generator = optimizer.compile(
93
+ quiz_generator,
94
+ trainset=trainset,
95
+ )
96
+ quiz_choices = compiled_quiz_generator(
97
+ question=example.question, answer=example.answer
98
+ )
99
+ print("Generated Quiz Choices: ", quiz_choices.choices)
100
+
101
+ # Evaluate
102
+ evaluate = Evaluate(
103
+ metric=format_valid_metric,
104
+ devset=devset[67:70],
105
+ num_threads=1,
106
+ display_progress=True,
107
+ display_table=5,
108
+ )
109
+ evaluate(quiz_generator)
110
+
111
+
112
+ if __name__ == "__main__":
113
+ quiz_generator_1()
@@ -0,0 +1,39 @@
1
+ import sys
2
+ import os
3
+ import dspy
4
+
5
+ # Add the local src folder to the Python path
6
+ sys.path.insert(0, os.path.abspath('/Users/karthikkalyanaraman/work/langtrace/langtrace-python-sdk/src'))
7
+
8
+ # flake8: noqa
9
+ from langtrace_python_sdk import langtrace, with_langtrace_root_span
10
+ langtrace.init()
11
+
12
+ turbo = dspy.OpenAI(model='gpt-3.5-turbo', max_tokens=250)
13
+ dspy.settings.configure(lm=turbo)
14
+
15
+ colbertv2_wiki17_abstracts = dspy.ColBERTv2(url='http://20.102.90.50:2017/wiki17_abstracts')
16
+ dspy.settings.configure(rm=colbertv2_wiki17_abstracts)
17
+ retriever = dspy.Retrieve(k=3)
18
+
19
+ # Define a simple signature for basic question answering
20
+ class BasicQA(dspy.Signature):
21
+ """Answer questions with short factoid answers."""
22
+ question = dspy.InputField()
23
+ answer = dspy.OutputField(desc="often between 1 and 5 words")
24
+
25
+ @with_langtrace_root_span(name="react_example")
26
+ def example():
27
+
28
+ # Pass signature to ReAct module
29
+ react_module = dspy.ReAct(BasicQA)
30
+
31
+ # Call the ReAct module on a particular input
32
+ question = 'Aside from the Apple Remote, what other devices can control the program Apple Remote was originally designed to interact with?'
33
+ result = react_module(question=question)
34
+
35
+ print(f"Question: {question}")
36
+ print(f"Final Predicted Answer (after ReAct process): {result.answer}")
37
+
38
+ if __name__ == '__main__':
39
+ example()
@@ -11,6 +11,7 @@ SERVICE_PROVIDERS = {
11
11
  "ANTHROPIC": "Anthropic",
12
12
  "AZURE": "Azure",
13
13
  "CHROMA": "Chroma",
14
+ "DSPY": "DSPy",
14
15
  "GROQ": "Groq",
15
16
  "LANGCHAIN": "Langchain",
16
17
  "LANGCHAIN_COMMUNITY": "Langchain Community",
@@ -27,6 +27,8 @@ class OpenMode(str):
27
27
 
28
28
 
29
29
  class LangTraceFile(io.BytesIO):
30
+ _host: str = os.environ.get("LANGTRACE_API_HOST", None) or LANGTRACE_REMOTE_URL
31
+
30
32
  def __init__(self, fs: "LangTraceFileSystem", path: str, mode: OpenMode):
31
33
  super().__init__()
32
34
  self.fs = fs
@@ -65,7 +67,7 @@ class LangTraceFile(io.BytesIO):
65
67
  else:
66
68
  print(Fore.GREEN + "Sending results to Langtrace" + Fore.RESET)
67
69
  response = requests.post(
68
- url=f"{LANGTRACE_REMOTE_URL}/api/run",
70
+ url=f"{self._host}/api/run",
69
71
  data=json.dumps(data),
70
72
  headers={
71
73
  "Content-Type": "application/json",
@@ -80,6 +82,7 @@ class LangTraceFile(io.BytesIO):
80
82
 
81
83
 
82
84
  class LangTraceFileSystem(AbstractFileSystem):
85
+ _host: str = os.environ.get("LANGTRACE_API_HOST", None) or LANGTRACE_REMOTE_URL
83
86
  protocol = "langtracefs"
84
87
  sep = "/"
85
88
 
@@ -112,7 +115,7 @@ class LangTraceFileSystem(AbstractFileSystem):
112
115
  + Fore.RESET
113
116
  )
114
117
  response = requests.get(
115
- url=f"{LANGTRACE_REMOTE_URL}/api/dataset/download?id={dataset_id}",
118
+ url=f"{self._host}/api/dataset/download?id={dataset_id}",
116
119
  headers={
117
120
  "Content-Type": "application/json",
118
121
  "x-api-key": os.environ.get("LANGTRACE_API_KEY"),
@@ -12,6 +12,7 @@ from .pinecone import PineconeInstrumentation
12
12
  from .qdrant import QdrantInstrumentation
13
13
  from .weaviate import WeaviateInstrumentation
14
14
  from .ollama import OllamaInstrumentor
15
+ from .dspy import DspyInstrumentor
15
16
 
16
17
  __all__ = [
17
18
  "AnthropicInstrumentation",
@@ -28,4 +29,5 @@ __all__ = [
28
29
  "QdrantInstrumentation",
29
30
  "WeaviateInstrumentation",
30
31
  "OllamaInstrumentor",
32
+ "DspyInstrumentor",
31
33
  ]
@@ -0,0 +1,3 @@
1
+ from .instrumentation import DspyInstrumentor
2
+
3
+ __all__ = ["DspyInstrumentor"]
@@ -0,0 +1,85 @@
1
+ """
2
+ Copyright (c) 2024 Scale3 Labs
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ """
16
+
17
+ from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
18
+ from opentelemetry.trace import get_tracer
19
+ from wrapt import wrap_function_wrapper as _W
20
+ from typing import Collection
21
+ from importlib_metadata import version as v
22
+ from .patch import patch_bootstrapfewshot_optimizer, patch_signature, patch_evaluate
23
+
24
+
25
+ class DspyInstrumentor(BaseInstrumentor):
26
+ """
27
+ The DspyInstrumentor class represents the DSPy instrumentation"""
28
+
29
+ def instrumentation_dependencies(self) -> Collection[str]:
30
+ return ["dspy >= 0.1.5"]
31
+
32
+ def _instrument(self, **kwargs):
33
+ tracer_provider = kwargs.get("tracer_provider")
34
+ tracer = get_tracer(__name__, "", tracer_provider)
35
+ version = v("dspy")
36
+ _W(
37
+ "dspy.teleprompt.bootstrap",
38
+ "BootstrapFewShot.compile",
39
+ patch_bootstrapfewshot_optimizer(
40
+ "BootstrapFewShot.compile", version, tracer
41
+ ),
42
+ )
43
+ _W(
44
+ "dspy.predict.predict",
45
+ "Predict.forward",
46
+ patch_signature("Predict.forward", version, tracer),
47
+ )
48
+ _W(
49
+ "dspy.predict.chain_of_thought",
50
+ "ChainOfThought.forward",
51
+ patch_signature("ChainOfThought.forward", version, tracer),
52
+ )
53
+ _W(
54
+ "dspy.predict.chain_of_thought_with_hint",
55
+ "ChainOfThoughtWithHint.forward",
56
+ patch_signature("ChainOfThoughtWithHint.forward", version, tracer),
57
+ )
58
+ _W(
59
+ "dspy.predict.react",
60
+ "ReAct.forward",
61
+ patch_signature("ReAct.forward", version, tracer),
62
+ )
63
+ _W(
64
+ "dspy.predict.program_of_thought",
65
+ "ProgramOfThought.forward",
66
+ patch_signature("ProgramOfThought.forward", version, tracer),
67
+ )
68
+ _W(
69
+ "dspy.predict.multi_chain_comparison",
70
+ "MultiChainComparison.forward",
71
+ patch_signature("MultiChainComparison.forward", version, tracer),
72
+ )
73
+ _W(
74
+ "dspy.predict.retry",
75
+ "Retry.forward",
76
+ patch_signature("Retry.forward", version, tracer),
77
+ )
78
+ _W(
79
+ "dspy.evaluate.evaluate",
80
+ "Evaluate.__call__",
81
+ patch_evaluate("Evaluate", version, tracer),
82
+ )
83
+
84
+ def _uninstrument(self, **kwargs):
85
+ pass
@@ -0,0 +1,206 @@
1
+ import json
2
+ from importlib_metadata import version as v
3
+ from langtrace_python_sdk.constants import LANGTRACE_SDK_NAME
4
+ from langtrace_python_sdk.utils import set_span_attribute
5
+ from langtrace_python_sdk.utils.silently_fail import silently_fail
6
+ from langtrace_python_sdk.constants.instrumentation.common import (
7
+ LANGTRACE_ADDITIONAL_SPAN_ATTRIBUTES_KEY,
8
+ SERVICE_PROVIDERS,
9
+ )
10
+ from opentelemetry import baggage
11
+ from langtrace.trace_attributes import FrameworkSpanAttributes
12
+ from opentelemetry.trace import SpanKind
13
+ from opentelemetry.trace.status import Status, StatusCode
14
+
15
+
16
+ def patch_bootstrapfewshot_optimizer(operation_name, version, tracer):
17
+ def traced_method(wrapped, instance, args, kwargs):
18
+
19
+ service_provider = SERVICE_PROVIDERS["DSPY"]
20
+ extra_attributes = baggage.get_baggage(LANGTRACE_ADDITIONAL_SPAN_ATTRIBUTES_KEY)
21
+ span_attributes = {
22
+ "langtrace.sdk.name": "langtrace-python-sdk",
23
+ "langtrace.service.name": service_provider,
24
+ "langtrace.service.type": "framework",
25
+ "langtrace.service.version": version,
26
+ "langtrace.version": v(LANGTRACE_SDK_NAME),
27
+ **(extra_attributes if extra_attributes is not None else {}),
28
+ }
29
+
30
+ if instance.__class__.__name__:
31
+ span_attributes["dspy.optimizer"] = instance.__class__.__name__
32
+ if len(args) > 0:
33
+ span_attributes["dspy.optimizer.module"] = args[0].__class__.__name__
34
+ if args[0].prog:
35
+ prog = {
36
+ "name": args[0].prog.__class__.__name__,
37
+ "signature": str(args[0].prog.signature) if args[0].prog.signature else None,
38
+ }
39
+ span_attributes["dspy.optimizer.module.prog"] = json.dumps(prog)
40
+ if instance.metric:
41
+ span_attributes["dspy.optimizer.metric"] = instance.metric.__name__
42
+ if kwargs.get("trainset") and len(kwargs.get("trainset")) > 0:
43
+ span_attributes["dspy.optimizer.trainset"] = str(kwargs.get("trainset"))
44
+ config = {}
45
+ if instance.metric_threshold:
46
+ config["metric_threshold"] = instance.metric_threshold
47
+ if instance.teacher_settings:
48
+ config["teacher_settings"] = instance.teacher_settings
49
+ if instance.max_bootstrapped_demos:
50
+ config["max_bootstrapped_demos"] = instance.max_bootstrapped_demos
51
+ if instance.max_labeled_demos:
52
+ config["max_labeled_demos"] = instance.max_labeled_demos
53
+ if instance.max_rounds:
54
+ config["max_rounds"] = instance.max_rounds
55
+ if instance.max_errors:
56
+ config["max_errors"] = instance.max_errors
57
+ if instance.error_count:
58
+ config["error_count"] = instance.error_count
59
+ if config and len(config) > 0:
60
+ span_attributes["dspy.optimizer.config"] = json.dumps(config)
61
+
62
+ attributes = FrameworkSpanAttributes(**span_attributes)
63
+ with tracer.start_as_current_span(
64
+ operation_name, kind=SpanKind.CLIENT
65
+ ) as span:
66
+ _set_input_attributes(span, kwargs, attributes)
67
+
68
+ try:
69
+ result = wrapped(*args, **kwargs)
70
+ if result:
71
+ span.set_status(Status(StatusCode.OK))
72
+
73
+ span.end()
74
+ return result
75
+
76
+ except Exception as err:
77
+ # Record the exception in the span
78
+ span.record_exception(err)
79
+
80
+ # Set the span status to indicate an error
81
+ span.set_status(Status(StatusCode.ERROR, str(err)))
82
+
83
+ # Reraise the exception to ensure it's not swallowed
84
+ raise
85
+
86
+ return traced_method
87
+
88
+
89
+ def patch_signature(operation_name, version, tracer):
90
+ def traced_method(wrapped, instance, args, kwargs):
91
+
92
+ service_provider = SERVICE_PROVIDERS["DSPY"]
93
+ extra_attributes = baggage.get_baggage(LANGTRACE_ADDITIONAL_SPAN_ATTRIBUTES_KEY)
94
+ span_attributes = {
95
+ "langtrace.sdk.name": "langtrace-python-sdk",
96
+ "langtrace.service.name": service_provider,
97
+ "langtrace.service.type": "framework",
98
+ "langtrace.service.version": version,
99
+ "langtrace.version": v(LANGTRACE_SDK_NAME),
100
+ **(extra_attributes if extra_attributes is not None else {}),
101
+ }
102
+
103
+ if instance.__class__.__name__:
104
+ span_attributes["dspy.signature.name"] = instance.__class__.__name__
105
+ span_attributes["dspy.signature"] = str(instance)
106
+
107
+ if kwargs and len(kwargs) > 0:
108
+ span_attributes["dspy.signature.args"] = str(kwargs)
109
+
110
+ attributes = FrameworkSpanAttributes(**span_attributes)
111
+ with tracer.start_as_current_span(
112
+ operation_name, kind=SpanKind.CLIENT
113
+ ) as span:
114
+ _set_input_attributes(span, kwargs, attributes)
115
+
116
+ try:
117
+ result = wrapped(*args, **kwargs)
118
+ if result:
119
+ set_span_attribute(span, "dspy.signature.result", str(result))
120
+ span.set_status(Status(StatusCode.OK))
121
+
122
+ span.end()
123
+ return result
124
+
125
+ except Exception as err:
126
+ # Record the exception in the span
127
+ span.record_exception(err)
128
+
129
+ # Set the span status to indicate an error
130
+ span.set_status(Status(StatusCode.ERROR, str(err)))
131
+
132
+ # Reraise the exception to ensure it's not swallowed
133
+ raise
134
+
135
+ return traced_method
136
+
137
+
138
+ def patch_evaluate(operation_name, version, tracer):
139
+ def traced_method(wrapped, instance, args, kwargs):
140
+
141
+ service_provider = SERVICE_PROVIDERS["DSPY"]
142
+ extra_attributes = baggage.get_baggage(LANGTRACE_ADDITIONAL_SPAN_ATTRIBUTES_KEY)
143
+ span_attributes = {
144
+ "langtrace.sdk.name": "langtrace-python-sdk",
145
+ "langtrace.service.name": service_provider,
146
+ "langtrace.service.type": "framework",
147
+ "langtrace.service.version": version,
148
+ "langtrace.version": v(LANGTRACE_SDK_NAME),
149
+ **(extra_attributes if extra_attributes is not None else {}),
150
+ }
151
+
152
+ if instance.devset is not None:
153
+ span_attributes["dspy.evaluate.devset"] = str(instance.devset)
154
+ if instance.display is not None:
155
+ span_attributes["dspy.evaluate.display"] = str(instance.display)
156
+ if instance.num_threads is not None:
157
+ span_attributes["dspy.evaluate.num_threads"] = str(instance.num_threads)
158
+ if instance.return_outputs is not None:
159
+ span_attributes["dspy.evaluate.return_outputs"] = str(instance.return_outputs)
160
+ if instance.display_table is not None:
161
+ span_attributes["dspy.evaluate.display_table"] = str(instance.display_table)
162
+ if instance.display_progress is not None:
163
+ span_attributes["dspy.evaluate.display_progress"] = str(instance.display_progress)
164
+ if instance.metric is not None:
165
+ span_attributes["dspy.evaluate.metric"] = instance.metric.__name__
166
+ if instance.error_count is not None:
167
+ span_attributes["dspy.evaluate.error_count"] = str(instance.error_count)
168
+ if instance.error_lock is not None:
169
+ span_attributes["dspy.evaluate.error_lock"] = str(instance.error_lock)
170
+ if instance.max_errors is not None:
171
+ span_attributes["dspy.evaluate.max_errors"] = str(instance.max_errors)
172
+ if args and len(args) > 0:
173
+ span_attributes["dspy.evaluate.args"] = str(args)
174
+
175
+ attributes = FrameworkSpanAttributes(**span_attributes)
176
+ with tracer.start_as_current_span(
177
+ operation_name, kind=SpanKind.CLIENT
178
+ ) as span:
179
+ _set_input_attributes(span, kwargs, attributes)
180
+
181
+ try:
182
+ result = wrapped(*args, **kwargs)
183
+ if result is not None:
184
+ set_span_attribute(span, "dspy.evaluate.result", str(result))
185
+ span.set_status(Status(StatusCode.OK))
186
+
187
+ span.end()
188
+ return result
189
+
190
+ except Exception as err:
191
+ # Record the exception in the span
192
+ span.record_exception(err)
193
+
194
+ # Set the span status to indicate an error
195
+ span.set_status(Status(StatusCode.ERROR, str(err)))
196
+
197
+ # Reraise the exception to ensure it's not swallowed
198
+ raise
199
+
200
+ return traced_method
201
+
202
+
203
+ @silently_fail
204
+ def _set_input_attributes(span, kwargs, attributes):
205
+ for field, value in attributes.model_dump(by_alias=True).items():
206
+ set_span_attribute(span, field, value)
@@ -51,6 +51,7 @@ from langtrace_python_sdk.instrumentation import (
51
51
  QdrantInstrumentation,
52
52
  WeaviateInstrumentation,
53
53
  OllamaInstrumentor,
54
+ DspyInstrumentor,
54
55
  )
55
56
  from opentelemetry.instrumentation.sqlalchemy import SQLAlchemyInstrumentor
56
57
  from colorama import Fore
@@ -108,6 +109,7 @@ def init(
108
109
  "weaviate": WeaviateInstrumentation(),
109
110
  "sqlalchemy": SQLAlchemyInstrumentor(),
110
111
  "ollama": OllamaInstrumentor(),
112
+ "dspy": DspyInstrumentor(),
111
113
  }
112
114
 
113
115
  init_instrumentations(disable_instrumentations, all_instrumentations)
@@ -1 +1 @@
1
- __version__ = "2.1.19"
1
+ __version__ = "2.1.21"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: langtrace-python-sdk
3
- Version: 2.1.19
3
+ Version: 2.1.21
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>
@@ -9,6 +9,10 @@ examples/cohere_example/chat_stream.py,sha256=daWGrj2yucN9sWKGiPzTw18clh23Grv-MI
9
9
  examples/cohere_example/embed.py,sha256=p9BJvOg09JVb8BfTCb63v3uh_wOsi_OyrCAJdXXrE6E,496
10
10
  examples/cohere_example/rerank.py,sha256=e7OU0A2FzfiQDuOmCy3Kg5LLNYGRmRIK5LqeLnTWlP4,1118
11
11
  examples/cohere_example/tools.py,sha256=a5uvS058tcwU6PJbF9EDO6LPVmPj2LoW4Vn8Web3Iq8,1656
12
+ examples/dspy_example/math_problems_cot.py,sha256=Z98nB6myt8WJse2dWS6Ap7CFUhC27lBNb37R1Gg80VQ,1282
13
+ examples/dspy_example/program_of_thought_basic.py,sha256=oEbtJdeKENMUbex25-zyStWwurRWW6OdP0KDs-jUkko,984
14
+ examples/dspy_example/quiz_gen.py,sha256=OyGhepeX8meKOtLdmlYUjMD2ECk-ZQuQXUZif1hFQY4,3371
15
+ examples/dspy_example/react.py,sha256=dmhO6AyO5K3w0WNkwe-Usd2cIgVmEPoWzusrLxXIfPo,1340
12
16
  examples/fastapi_example/__init__.py,sha256=INIfvJP7zC_KkJCtulS1qbh61-MJTPAHnzAgzeKi0yU,87
13
17
  examples/fastapi_example/basic_route.py,sha256=_IRXjkOtJQ-bTIGa1WbvUF_2LF4bjghjyXt4YrHaRvw,1170
14
18
  examples/hiveagent_example/basic.py,sha256=Sd7I5w8w5Xx7ODaydTY30yiq9HwJDMKHQywrZjgehP0,441
@@ -45,15 +49,15 @@ examples/qdrant_example/basic.py,sha256=DCMjHSuBZKkhEjCkwy5d5La9WMyW0lCWqtcZWiFC
45
49
  examples/weaviate_example/__init__.py,sha256=8JMDBsRSEV10HfTd-YC7xb4txBjD3la56snk-Bbg2Kw,618
46
50
  examples/weaviate_example/query_text.py,sha256=qz9o-fTDzX5AW5m8BJF-TfmBdokxh492NfnmnPUMU3s,64814
47
51
  langtrace_python_sdk/__init__.py,sha256=VZM6i71NR7pBQK6XvJWRelknuTYUhqwqE7PlicKa5Wg,1166
48
- langtrace_python_sdk/langtrace.py,sha256=WRgbBS7T1q3ZELvVZLVCKdqa00m64lozgeiCp6MOQn8,7352
49
- langtrace_python_sdk/version.py,sha256=ORNtksaL65IiKUhkJEaS3s0gzZq5HMSHSwIKtUEfCBA,23
52
+ langtrace_python_sdk/langtrace.py,sha256=enOnfpDPoFibbUzUEY2vV8S3No0dySdXxo3E76rZ8mA,7410
53
+ langtrace_python_sdk/version.py,sha256=msdDHhj5VY39vNBuQYgH15DYZ-b9Z3koedzF3TN1kW8,23
50
54
  langtrace_python_sdk/constants/__init__.py,sha256=P8QvYwt5czUNDZsKS64vxm9Dc41ptGbuF1TFtAF6nv4,44
51
55
  langtrace_python_sdk/constants/exporter/langtrace_exporter.py,sha256=5MNjnAOg-4am78J3gVMH6FSwq5N8TOj72ugkhsw4vi0,46
52
56
  langtrace_python_sdk/constants/instrumentation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
53
57
  langtrace_python_sdk/constants/instrumentation/anthropic.py,sha256=YX3llt3zwDY6XrYk3CB8WEVqgrzRXEw_ffyk56JoF3k,126
54
58
  langtrace_python_sdk/constants/instrumentation/chroma.py,sha256=hiPGYdHS0Yj4Kh3eaYBbuCAl_swqIygu80yFqkOgdak,955
55
59
  langtrace_python_sdk/constants/instrumentation/cohere.py,sha256=tf9sDfb5K3qOAHChEE5o8eYWPZ1io58VsOjZDCZPxfw,577
56
- langtrace_python_sdk/constants/instrumentation/common.py,sha256=UyYObokJpNPOPft_TPmhP00WONV0KqKOkX6mvN3AH5w,806
60
+ langtrace_python_sdk/constants/instrumentation/common.py,sha256=kqs3ST0RTcXpQKPSQ6R6hoBabQsLGPNB_rvHlQXsn80,826
57
61
  langtrace_python_sdk/constants/instrumentation/groq.py,sha256=VFXmIl4aqGY_fS0PAmjPj_Qm7Tibxbx7Ur_e7rQpqXc,134
58
62
  langtrace_python_sdk/constants/instrumentation/ollama.py,sha256=zFfSUKX5v1c612doKSxsmIwQeeQxSPkFp_ZzjWQSPNE,142
59
63
  langtrace_python_sdk/constants/instrumentation/openai.py,sha256=uEOH5UXapU2DSf2AdgXTRhhJEHGWXUNFkUGD5QafflM,1164
@@ -62,8 +66,8 @@ langtrace_python_sdk/constants/instrumentation/qdrant.py,sha256=yL7BopNQTXW7L7Z-
62
66
  langtrace_python_sdk/constants/instrumentation/weaviate.py,sha256=Iytf2OpB_irZYEmvOQ7Pf483EdG5Bh59GxaBlXck0yY,1501
63
67
  langtrace_python_sdk/extensions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
64
68
  langtrace_python_sdk/extensions/langtrace_exporter.py,sha256=gWVRU2DlB4xjZ4ww7M63DaLiAN5zQ2k1HPrythmjEdo,4202
65
- langtrace_python_sdk/extensions/langtrace_filesystem.py,sha256=lQlFgKM5sRrNHvaKMioxEdIvoY6V-cG2tnEyddT3lPM,6776
66
- langtrace_python_sdk/instrumentation/__init__.py,sha256=18E7qZOIKmSm59ij7n-ytCv3qenjkDlNz9xPjapOLtY,1107
69
+ langtrace_python_sdk/extensions/langtrace_filesystem.py,sha256=qpnkpkuTZ2yhGgpBK64QJLt0T1iL-1zpEMPz4quJ_ng,6925
70
+ langtrace_python_sdk/instrumentation/__init__.py,sha256=y5ftlcrAjSHvoQ_v8ffDlsP5la3SG-B4PKpPZIeoTds,1166
67
71
  langtrace_python_sdk/instrumentation/anthropic/__init__.py,sha256=donrurJAGYlxrSRA3BIf76jGeUcAx9Tq8CVpah68S0Y,101
68
72
  langtrace_python_sdk/instrumentation/anthropic/instrumentation.py,sha256=-srgE8qumAn0ulQYZxMa8ch-9IBH0XgBW_rfEnGk6LI,1684
69
73
  langtrace_python_sdk/instrumentation/anthropic/patch.py,sha256=52GRkW7fhF2VB9JvYGMaPwOvWH3Q5rsIEaVlnFm_Zz0,8548
@@ -73,6 +77,9 @@ langtrace_python_sdk/instrumentation/chroma/patch.py,sha256=HhIkXGbVfzpEB4edxzlG
73
77
  langtrace_python_sdk/instrumentation/cohere/__init__.py,sha256=sGUSLdTUyYf36Tm6L5jQflhzCqvmWrhnBOMYHjvp6Hs,95
74
78
  langtrace_python_sdk/instrumentation/cohere/instrumentation.py,sha256=YQFHZIBd7SSPD4b6Va-ZR0thf_AuBCqj5yzHLHJVWnM,2121
75
79
  langtrace_python_sdk/instrumentation/cohere/patch.py,sha256=uGjZm_c1-xpZilHD8ljGr4AqQB3UNU04SKl9s2alGzs,26726
80
+ langtrace_python_sdk/instrumentation/dspy/__init__.py,sha256=qTdAqLOuLX7dsiD_pdqe23pz9Ehit4aC5771WJe2Q8I,78
81
+ langtrace_python_sdk/instrumentation/dspy/instrumentation.py,sha256=fvnTpDoMlCzpUyhlZefUgUO1yd50dH27UPDQ6EBcrJA,2920
82
+ langtrace_python_sdk/instrumentation/dspy/patch.py,sha256=8VrY3Et0zQRagYkSU6jIv6tvY6PpvVTDRRcWtgz3QEw,8662
76
83
  langtrace_python_sdk/instrumentation/groq/__init__.py,sha256=ZXeq_nrej6Lm_uoMFEg8wbSejhjB2UJ5IoHQBPc2-C0,91
77
84
  langtrace_python_sdk/instrumentation/groq/instrumentation.py,sha256=Ttf07XVKhdYY1_fqJc7QWiSdmgEhEVyQB_3Az2_wqYo,1832
78
85
  langtrace_python_sdk/instrumentation/groq/patch.py,sha256=EKH9tjoDbwWavIAwUadaR5tFiy-S69h1IxxzH_1SSRg,26354
@@ -152,8 +159,8 @@ tests/pinecone/cassettes/test_query.yaml,sha256=b5v9G3ssUy00oG63PlFUR3JErF2Js-5A
152
159
  tests/pinecone/cassettes/test_upsert.yaml,sha256=neWmQ1v3d03V8WoLl8FoFeeCYImb8pxlJBWnFd_lITU,38607
153
160
  tests/qdrant/conftest.py,sha256=9n0uHxxIjWk9fbYc4bx-uP8lSAgLBVx-cV9UjnsyCHM,381
154
161
  tests/qdrant/test_qdrant.py,sha256=pzjAjVY2kmsmGfrI2Gs2xrolfuaNHz7l1fqGQCjp5_o,3353
155
- langtrace_python_sdk-2.1.19.dist-info/METADATA,sha256=Ll01P8FwZ7OwKOnM2UajEWZsLj7EXGTKhcZvWKLS2Dk,13161
156
- langtrace_python_sdk-2.1.19.dist-info/WHEEL,sha256=zEMcRr9Kr03x1ozGwg5v9NQBKn3kndp6LSoSlVg-jhU,87
157
- langtrace_python_sdk-2.1.19.dist-info/entry_points.txt,sha256=1_b9-qvf2fE7uQNZcbUei9vLpFZBbbh9LrtGw95ssAo,70
158
- langtrace_python_sdk-2.1.19.dist-info/licenses/LICENSE,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
159
- langtrace_python_sdk-2.1.19.dist-info/RECORD,,
162
+ langtrace_python_sdk-2.1.21.dist-info/METADATA,sha256=y6OnKJCGYcnpezk9jVMO1Y-EBummvLJ92jRUOa1M4hE,13161
163
+ langtrace_python_sdk-2.1.21.dist-info/WHEEL,sha256=zEMcRr9Kr03x1ozGwg5v9NQBKn3kndp6LSoSlVg-jhU,87
164
+ langtrace_python_sdk-2.1.21.dist-info/entry_points.txt,sha256=1_b9-qvf2fE7uQNZcbUei9vLpFZBbbh9LrtGw95ssAo,70
165
+ langtrace_python_sdk-2.1.21.dist-info/licenses/LICENSE,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
166
+ langtrace_python_sdk-2.1.21.dist-info/RECORD,,