langtrace-python-sdk 2.1.16__py3-none-any.whl → 2.1.17__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,28 @@
1
+ # langtrace.init(write_spans_to_console=True)
2
+ import fsspec
3
+ from inspect_ai import Task, task
4
+ from inspect_ai.dataset import csv_dataset
5
+ from inspect_ai.scorer import model_graded_qa
6
+ from inspect_ai.solver import chain_of_thought, generate, self_critique
7
+
8
+ from langtrace_python_sdk.extensions.langtrace_filesystem import \
9
+ LangTraceFileSystem
10
+
11
+ # from langtrace_python_sdk import langtrace
12
+
13
+
14
+ # Manually register the filesystem with fsspec
15
+ # Note: This is only necessary because the filesystem is not registered.
16
+ fsspec.register_implementation(LangTraceFileSystem.protocol, LangTraceFileSystem)
17
+
18
+
19
+ @task
20
+ def security_guide():
21
+ return Task(
22
+ dataset=csv_dataset("langtracefs://clxc2mxu6000lpc7ntsvcjvp9"),
23
+ plan=[
24
+ chain_of_thought(),
25
+ self_critique()
26
+ ],
27
+ scorer=model_graded_qa()
28
+ )
@@ -15,16 +15,12 @@ limitations under the License.
15
15
  """
16
16
 
17
17
  from langtrace_python_sdk import langtrace
18
- from langtrace_python_sdk.utils.with_root_span import (
19
- with_langtrace_root_span,
20
- with_additional_attributes,
21
- )
22
-
18
+ from langtrace_python_sdk.extensions.langtrace_filesystem import \
19
+ LangTraceFileSystem
23
20
  from langtrace_python_sdk.utils.prompt_registry import get_prompt_from_registry
24
21
  from langtrace_python_sdk.utils.with_root_span import (
25
- SendUserFeedback,
26
- inject_additional_attributes,
27
- )
22
+ SendUserFeedback, inject_additional_attributes, with_additional_attributes,
23
+ with_langtrace_root_span)
28
24
 
29
25
  __all__ = [
30
26
  "langtrace",
@@ -33,4 +29,5 @@ __all__ = [
33
29
  "inject_additional_attributes",
34
30
  "get_prompt_from_registry",
35
31
  "SendUserFeedback",
32
+ "LangTraceFileSystem",
36
33
  ]
@@ -0,0 +1,178 @@
1
+ import json
2
+ import io
3
+ import os
4
+ import requests
5
+ from typing import Iterator, Literal, Union
6
+ from colorama import Fore
7
+ from langtrace_python_sdk.constants.exporter.langtrace_exporter import (
8
+ LANGTRACE_REMOTE_URL,
9
+ )
10
+ from fsspec.spec import AbstractFileSystem
11
+
12
+ OpenTextMode = Literal["r", "a", "w"]
13
+ OpenBinaryMode = Literal["rb", "ab", "wb"]
14
+
15
+
16
+ class OpenMode(str):
17
+ def __init_subclass__(cls, **kwargs):
18
+ allowed_values = set(OpenTextMode.__args__) | set(OpenBinaryMode.__args__)
19
+ super().__init_subclass__(**kwargs)
20
+
21
+ def __new__(cls, value):
22
+ if value not in allowed_values:
23
+ raise ValueError(f"Invalid value for OpenMode: {value}")
24
+ return super().__new__(cls, value)
25
+
26
+ cls.__new__ = __new__
27
+
28
+
29
+ class LangTraceFile(io.BytesIO):
30
+ def __init__(self, fs: "LangTraceFileSystem", path: str, mode: OpenMode):
31
+ super().__init__()
32
+ self.fs = fs
33
+ self.path = path
34
+ self.mode = mode
35
+
36
+ def close(self) -> None:
37
+ if not self.closed:
38
+ self.seek(0)
39
+ file_data = self.getvalue()
40
+ self.fs.files[self.path] = file_data
41
+
42
+ # Upload the file to the remote server
43
+ self.upload_to_server(file_data)
44
+
45
+ super().close()
46
+
47
+ def upload_to_server(self, file_data: bytes) -> None:
48
+ try:
49
+ # Parse the log file and upload it to the server
50
+ log = file_data.decode("utf-8")
51
+ eval_log = json.loads(log)
52
+ data = {
53
+ "runId": eval_log['eval']['run_id'],
54
+ "taskId": eval_log['eval']['task_id'],
55
+ "log": log,
56
+ }
57
+ if self.path is not None:
58
+ dataset_id = self.path.split("/")[0]
59
+ print(Fore.GREEN + f"Sending results to Langtrace for dataset: {dataset_id}" + Fore.RESET)
60
+ data["datasetId"] = dataset_id
61
+ else:
62
+ print(Fore.GREEN + "Sending results to Langtrace" + Fore.RESET)
63
+ response = requests.post(
64
+ url=f"{LANGTRACE_REMOTE_URL}/api/run",
65
+ data=json.dumps(data),
66
+ headers={
67
+ "Content-Type": "application/json",
68
+ "x-api-key": os.environ.get("LANGTRACE_API_KEY")
69
+ },
70
+ timeout=20,
71
+ )
72
+ response.raise_for_status()
73
+ print(
74
+ Fore.GREEN + "Results sent to Langtrace successfully." + Fore.RESET
75
+ )
76
+ except requests.exceptions.RequestException as error:
77
+ print(Fore.RED + f"Error reporting results: {error}" + Fore.RESET)
78
+
79
+
80
+ class LangTraceFileSystem(AbstractFileSystem):
81
+ protocol = "langtracefs"
82
+ sep = "/"
83
+
84
+ def __init__(self, *args, **kwargs):
85
+ super().__init__(*args, **kwargs)
86
+ self.files = {}
87
+ self.dirs = set()
88
+
89
+ def open(
90
+ self,
91
+ path: str,
92
+ mode: OpenTextMode | OpenBinaryMode = "rb",
93
+ **kwargs,
94
+ ) -> Iterator[LangTraceFile | io.BytesIO]:
95
+ if "r" in mode:
96
+ dataset_id = path
97
+ # Fetch file from API and return a BytesIO object
98
+ file_data = self.fetch_file_from_api(dataset_id)
99
+ return io.BytesIO(file_data)
100
+ elif "w" in mode or "a" in mode:
101
+ return LangTraceFile(self, path, mode)
102
+ else:
103
+ raise ValueError(f"Unsupported mode: {mode}")
104
+
105
+ def fetch_file_from_api(self, dataset_id: str) -> bytes:
106
+ try:
107
+ print(Fore.GREEN + f"Fetching dataset with id: {dataset_id} from Langtrace" + Fore.RESET)
108
+ response = requests.get(
109
+ url=f"{LANGTRACE_REMOTE_URL}/api/dataset/download?id={dataset_id}",
110
+ headers={
111
+ "Content-Type": "application/json",
112
+ "x-api-key": os.environ.get("LANGTRACE_API_KEY")
113
+ },
114
+ timeout=20,
115
+ )
116
+ print(Fore.GREEN + f"Successfully fetched dataset with id: {dataset_id} from Langtrace" + Fore.RESET)
117
+ response.raise_for_status()
118
+ file_data = response.content
119
+ return file_data
120
+ except requests.exceptions.RequestException as error:
121
+ print(Fore.RED + f"Error fetching dataset with id: {dataset_id} from Langtrace: {error}" + Fore.RESET)
122
+ return b""
123
+
124
+ def makedirs(self, path: str, exist_ok: bool = False) -> None:
125
+ if not exist_ok and path in self.dirs:
126
+ raise FileExistsError(f"Directory {path} already exists")
127
+ self.dirs.add(path)
128
+
129
+ def info(self, path: str, **kwargs):
130
+ if path in self.files:
131
+ return {"name": path, "size": len(self.files[path]), "type": "file"}
132
+ elif path in self.dirs:
133
+ return {"name": path, "type": "directory"}
134
+ else:
135
+ raise FileNotFoundError(f"No such file or directory: {path}")
136
+
137
+ def created(self, path: str) -> float:
138
+ # Return a dummy creation time
139
+ return 0.0
140
+
141
+ def exists(self, path: str) -> bool:
142
+ return path in self.files or path in self.dirs
143
+
144
+ def ls(self, path: str, detail: bool = False, **kwargs):
145
+ if path not in self.dirs:
146
+ raise FileNotFoundError(f"No such directory: {path}")
147
+ entries = []
148
+ for file_path in self.files:
149
+ if file_path.startswith(path + self.sep):
150
+ if detail:
151
+ entries.append(self.info(file_path))
152
+ else:
153
+ entries.append(file_path)
154
+ for dir_path in self.dirs:
155
+ if dir_path.startswith(path + self.sep):
156
+ if detail:
157
+ entries.append(self.info(dir_path))
158
+ else:
159
+ entries.append(dir_path)
160
+ return entries
161
+
162
+ def walk(self, path: str, maxdepth: int = None, **kwargs):
163
+ for root, dirs, files in self._walk(path):
164
+ yield root, dirs, [self.sep.join([root, f]) for f in files]
165
+
166
+ def _walk(self, path: str):
167
+ if path in self.dirs:
168
+ dirs = [d for d in self.dirs if d.startswith(path + self.sep)]
169
+ files = [f for f in self.files if f.startswith(path + self.sep)]
170
+ yield path, [d.split(self.sep)[-1] for d in dirs], [f.split(self.sep)[-1] for f in files]
171
+ for d in dirs:
172
+ yield from self._walk(d)
173
+
174
+ def unstrip_protocol(self, path: str) -> str:
175
+ return path
176
+
177
+ def invalidate_cache(self, path: str = None) -> None:
178
+ pass
@@ -1 +1 @@
1
- __version__ = "2.1.16"
1
+ __version__ = "2.1.17"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: langtrace-python-sdk
3
- Version: 2.1.16
3
+ Version: 2.1.17
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>
@@ -11,6 +11,7 @@ Classifier: Operating System :: OS Independent
11
11
  Classifier: Programming Language :: Python :: 3
12
12
  Requires-Python: >=3.9
13
13
  Requires-Dist: colorama>=0.4.6
14
+ Requires-Dist: fsspec>=2024.6.0
14
15
  Requires-Dist: opentelemetry-api>=1.25.0
15
16
  Requires-Dist: opentelemetry-exporter-otlp-proto-grpc>=1.25.0
16
17
  Requires-Dist: opentelemetry-exporter-otlp-proto-http>=1.25.0
@@ -12,6 +12,7 @@ examples/cohere_example/tools.py,sha256=a5uvS058tcwU6PJbF9EDO6LPVmPj2LoW4Vn8Web3
12
12
  examples/fastapi_example/__init__.py,sha256=INIfvJP7zC_KkJCtulS1qbh61-MJTPAHnzAgzeKi0yU,87
13
13
  examples/fastapi_example/basic_route.py,sha256=_IRXjkOtJQ-bTIGa1WbvUF_2LF4bjghjyXt4YrHaRvw,1170
14
14
  examples/hiveagent_example/basic.py,sha256=Sd7I5w8w5Xx7ODaydTY30yiq9HwJDMKHQywrZjgehP0,441
15
+ examples/inspect_ai_example/basic_eval.py,sha256=IpuZGXsCLgHvQN7BlNDaCr_BEqZ56H9BgrPAHCQRE3c,841
15
16
  examples/langchain_example/__init__.py,sha256=t28923ZDDejZabsvINnYwpLyb63WFwPde-Nmzdg-kH4,254
16
17
  examples/langchain_example/basic.py,sha256=8ppNBptB0x3vjD5wUF5qP7ghp1vk-OJBBKk-PJPVD5I,2504
17
18
  examples/langchain_example/groq_example.py,sha256=9dBbOWZCVJ29PpB1NbJhc9MThmtwrlOpdNIxPl7d8f8,787
@@ -41,9 +42,9 @@ examples/qdrant_example/__init__.py,sha256=Ze9xEzW8FiHUO58YBa8JeHNOwcmo3dpYH77Ak
41
42
  examples/qdrant_example/basic.py,sha256=DCMjHSuBZKkhEjCkwy5d5La9WMyW0lCWqtcZWiFCEm4,1425
42
43
  examples/weaviate_example/__init__.py,sha256=8JMDBsRSEV10HfTd-YC7xb4txBjD3la56snk-Bbg2Kw,618
43
44
  examples/weaviate_example/query_text.py,sha256=qz9o-fTDzX5AW5m8BJF-TfmBdokxh492NfnmnPUMU3s,64814
44
- langtrace_python_sdk/__init__.py,sha256=j7EX7oY783Nmh6dQQO9VQVtirVnz4ajr7sBkw-y6rRk,1113
45
+ langtrace_python_sdk/__init__.py,sha256=hUX84VxREzgdjXOc3ysDzQWkqnrPm0kevW6Mb9lc2vc,1162
45
46
  langtrace_python_sdk/langtrace.py,sha256=pN-xJRXrtvJIenMOH0-xlNXcnqL9qMjg28SrW-PMRU0,6978
46
- langtrace_python_sdk/version.py,sha256=PUbyHN5ixal0BffZXLS2fU7ojPZOahFVrPT578Lb1Sg,23
47
+ langtrace_python_sdk/version.py,sha256=ybQ-f3O4pW9SYci30ZzNDlbiqsMBjSInaZ-GHWegI1I,23
47
48
  langtrace_python_sdk/constants/__init__.py,sha256=P8QvYwt5czUNDZsKS64vxm9Dc41ptGbuF1TFtAF6nv4,44
48
49
  langtrace_python_sdk/constants/exporter/langtrace_exporter.py,sha256=5MNjnAOg-4am78J3gVMH6FSwq5N8TOj72ugkhsw4vi0,46
49
50
  langtrace_python_sdk/constants/instrumentation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -58,6 +59,7 @@ langtrace_python_sdk/constants/instrumentation/qdrant.py,sha256=yL7BopNQTXW7L7Z-
58
59
  langtrace_python_sdk/constants/instrumentation/weaviate.py,sha256=Iytf2OpB_irZYEmvOQ7Pf483EdG5Bh59GxaBlXck0yY,1501
59
60
  langtrace_python_sdk/extensions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
60
61
  langtrace_python_sdk/extensions/langtrace_exporter.py,sha256=gWVRU2DlB4xjZ4ww7M63DaLiAN5zQ2k1HPrythmjEdo,4202
62
+ langtrace_python_sdk/extensions/langtrace_filesystem.py,sha256=sqsiw0PhD1mlvwYTk4Bg9MlXt8CXUZ00vtRU3nYgktE,6492
61
63
  langtrace_python_sdk/instrumentation/__init__.py,sha256=htP583cfv32IUvWeck6edRiPQxhk0uzUa1l1vgbtjtY,1042
62
64
  langtrace_python_sdk/instrumentation/anthropic/__init__.py,sha256=donrurJAGYlxrSRA3BIf76jGeUcAx9Tq8CVpah68S0Y,101
63
65
  langtrace_python_sdk/instrumentation/anthropic/instrumentation.py,sha256=-srgE8qumAn0ulQYZxMa8ch-9IBH0XgBW_rfEnGk6LI,1684
@@ -143,7 +145,8 @@ tests/pinecone/cassettes/test_query.yaml,sha256=b5v9G3ssUy00oG63PlFUR3JErF2Js-5A
143
145
  tests/pinecone/cassettes/test_upsert.yaml,sha256=neWmQ1v3d03V8WoLl8FoFeeCYImb8pxlJBWnFd_lITU,38607
144
146
  tests/qdrant/conftest.py,sha256=9n0uHxxIjWk9fbYc4bx-uP8lSAgLBVx-cV9UjnsyCHM,381
145
147
  tests/qdrant/test_qdrant.py,sha256=pzjAjVY2kmsmGfrI2Gs2xrolfuaNHz7l1fqGQCjp5_o,3353
146
- langtrace_python_sdk-2.1.16.dist-info/METADATA,sha256=yXtCuRrFTuyr_ITt87NfKTmJS4y1yflOGcq3iozYNCM,13091
147
- langtrace_python_sdk-2.1.16.dist-info/WHEEL,sha256=zEMcRr9Kr03x1ozGwg5v9NQBKn3kndp6LSoSlVg-jhU,87
148
- langtrace_python_sdk-2.1.16.dist-info/licenses/LICENSE,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
149
- langtrace_python_sdk-2.1.16.dist-info/RECORD,,
148
+ langtrace_python_sdk-2.1.17.dist-info/METADATA,sha256=4Q1qZDw4DfVGKtM6ka2kZNEYJJkdC-b3OHZZdwMvTK4,13123
149
+ langtrace_python_sdk-2.1.17.dist-info/WHEEL,sha256=zEMcRr9Kr03x1ozGwg5v9NQBKn3kndp6LSoSlVg-jhU,87
150
+ langtrace_python_sdk-2.1.17.dist-info/entry_points.txt,sha256=1_b9-qvf2fE7uQNZcbUei9vLpFZBbbh9LrtGw95ssAo,70
151
+ langtrace_python_sdk-2.1.17.dist-info/licenses/LICENSE,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
152
+ langtrace_python_sdk-2.1.17.dist-info/RECORD,,
@@ -0,0 +1,2 @@
1
+ [fsspec.specs]
2
+ langtracefs = langtrace_python_sdk:LangTraceFileSystem