aiqa-client 0.1.0__py3-none-any.whl → 0.1.2__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.
- aiqa/__init__.py +44 -7
- aiqa/aiqa_exporter.py +286 -53
- aiqa/client.py +170 -0
- aiqa/experiment_runner.py +336 -0
- aiqa/object_serialiser.py +361 -0
- aiqa/test_experiment_runner.py +176 -0
- aiqa/test_tracing.py +230 -0
- aiqa/tracing.py +1102 -153
- {aiqa_client-0.1.0.dist-info → aiqa_client-0.1.2.dist-info}/METADATA +95 -4
- aiqa_client-0.1.2.dist-info/RECORD +14 -0
- aiqa_client-0.1.0.dist-info/RECORD +0 -9
- {aiqa_client-0.1.0.dist-info → aiqa_client-0.1.2.dist-info}/WHEEL +0 -0
- {aiqa_client-0.1.0.dist-info → aiqa_client-0.1.2.dist-info}/licenses/LICENSE +0 -0
- {aiqa_client-0.1.0.dist-info → aiqa_client-0.1.2.dist-info}/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: aiqa-client
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.2
|
|
4
4
|
Summary: OpenTelemetry-based Python client for tracing functions and sending traces to the AIQA server
|
|
5
5
|
Author-email: AIQA <info@aiqa.dev>
|
|
6
6
|
License: MIT
|
|
@@ -27,6 +27,7 @@ Requires-Dist: opentelemetry-api>=1.24.0
|
|
|
27
27
|
Requires-Dist: opentelemetry-sdk>=1.24.0
|
|
28
28
|
Requires-Dist: opentelemetry-semantic-conventions>=0.40b0
|
|
29
29
|
Requires-Dist: aiohttp>=3.9.0
|
|
30
|
+
Requires-Dist: requests>=2.31.0
|
|
30
31
|
Provides-Extra: dev
|
|
31
32
|
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
32
33
|
Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
|
|
@@ -71,7 +72,15 @@ export AIQA_API_KEY="your-api-key"
|
|
|
71
72
|
### Basic Usage
|
|
72
73
|
|
|
73
74
|
```python
|
|
74
|
-
from
|
|
75
|
+
from dotenv import load_dotenv
|
|
76
|
+
from aiqa import get_aiqa_client, WithTracing
|
|
77
|
+
|
|
78
|
+
# Load environment variables from .env file (if using one)
|
|
79
|
+
load_dotenv()
|
|
80
|
+
|
|
81
|
+
# Initialize client (must be called before using WithTracing)
|
|
82
|
+
# This loads environment variables and initializes the tracing system
|
|
83
|
+
get_aiqa_client()
|
|
75
84
|
|
|
76
85
|
@WithTracing
|
|
77
86
|
def my_function(x, y):
|
|
@@ -107,12 +116,12 @@ def my_function(data):
|
|
|
107
116
|
Spans are automatically flushed every 5 seconds. To flush immediately:
|
|
108
117
|
|
|
109
118
|
```python
|
|
110
|
-
from aiqa import
|
|
119
|
+
from aiqa import flush_tracing
|
|
111
120
|
import asyncio
|
|
112
121
|
|
|
113
122
|
async def main():
|
|
114
123
|
# Your code here
|
|
115
|
-
await
|
|
124
|
+
await flush_tracing()
|
|
116
125
|
|
|
117
126
|
asyncio.run(main())
|
|
118
127
|
```
|
|
@@ -143,6 +152,87 @@ def my_function():
|
|
|
143
152
|
# ... rest of function
|
|
144
153
|
```
|
|
145
154
|
|
|
155
|
+
### Grouping Traces by Conversation
|
|
156
|
+
|
|
157
|
+
To group multiple traces together that are part of the same conversation or session:
|
|
158
|
+
|
|
159
|
+
```python
|
|
160
|
+
from aiqa import WithTracing, set_conversation_id
|
|
161
|
+
|
|
162
|
+
@WithTracing
|
|
163
|
+
def handle_user_request(user_id: str, session_id: str):
|
|
164
|
+
# Set conversation ID to group all traces for this user session
|
|
165
|
+
set_conversation_id(f"user_{user_id}_session_{session_id}")
|
|
166
|
+
# All spans created in this function and its children will have this gen_ai.conversation.id
|
|
167
|
+
# ... rest of function
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
The `gen_ai.conversation.id` attribute allows you to filter and group traces in the AIQA server by conversation, making it easier to analyze multi-step interactions or user sessions. See the [OpenTelemetry GenAI Events specification](https://opentelemetry.io/docs/specs/semconv/gen-ai/gen-ai-events/) for more details.
|
|
171
|
+
|
|
172
|
+
### Trace ID Propagation Across Services/Agents
|
|
173
|
+
|
|
174
|
+
To link traces across different services or agents, you can extract and propagate trace IDs:
|
|
175
|
+
|
|
176
|
+
#### Getting Current Trace ID
|
|
177
|
+
|
|
178
|
+
```python
|
|
179
|
+
from aiqa import get_trace_id, get_span_id
|
|
180
|
+
|
|
181
|
+
# Get the current trace ID and span ID
|
|
182
|
+
trace_id = get_trace_id() # Returns hex string (32 chars) or None
|
|
183
|
+
span_id = get_span_id() # Returns hex string (16 chars) or None
|
|
184
|
+
|
|
185
|
+
# Pass these to another service (e.g., in HTTP headers, message queue, etc.)
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
#### Continuing a Trace in Another Service
|
|
189
|
+
|
|
190
|
+
```python
|
|
191
|
+
from aiqa import create_span_from_trace_id
|
|
192
|
+
|
|
193
|
+
# Continue a trace from another service/agent
|
|
194
|
+
# trace_id and parent_span_id come from the other service
|
|
195
|
+
with create_span_from_trace_id(
|
|
196
|
+
trace_id="abc123...",
|
|
197
|
+
parent_span_id="def456...",
|
|
198
|
+
span_name="service_b_operation"
|
|
199
|
+
):
|
|
200
|
+
# Your code here - this span will be linked to the original trace
|
|
201
|
+
pass
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
#### Using OpenTelemetry Context Propagation (Recommended)
|
|
205
|
+
|
|
206
|
+
For HTTP requests, use the built-in context propagation:
|
|
207
|
+
|
|
208
|
+
```python
|
|
209
|
+
from aiqa import inject_trace_context, extract_trace_context
|
|
210
|
+
import requests
|
|
211
|
+
from opentelemetry.trace import use_span
|
|
212
|
+
|
|
213
|
+
# In the sending service:
|
|
214
|
+
headers = {}
|
|
215
|
+
inject_trace_context(headers) # Adds trace context to headers
|
|
216
|
+
response = requests.get("http://other-service/api", headers=headers)
|
|
217
|
+
|
|
218
|
+
# In the receiving service:
|
|
219
|
+
# Extract context from incoming request headers
|
|
220
|
+
ctx = extract_trace_context(request.headers)
|
|
221
|
+
|
|
222
|
+
# Use the context to create a span
|
|
223
|
+
from opentelemetry.trace import use_span
|
|
224
|
+
with use_span(ctx):
|
|
225
|
+
# Your code here
|
|
226
|
+
pass
|
|
227
|
+
|
|
228
|
+
# Or create a span with the context
|
|
229
|
+
from opentelemetry import trace
|
|
230
|
+
tracer = trace.get_tracer("aiqa-tracer")
|
|
231
|
+
with tracer.start_as_current_span("operation", context=ctx):
|
|
232
|
+
# Your code here
|
|
233
|
+
pass
|
|
234
|
+
```
|
|
235
|
+
|
|
146
236
|
## Features
|
|
147
237
|
|
|
148
238
|
- Automatic tracing of function calls (sync and async)
|
|
@@ -150,6 +240,7 @@ def my_function():
|
|
|
150
240
|
- Automatic error tracking and exception recording
|
|
151
241
|
- Thread-safe span buffering and auto-flushing
|
|
152
242
|
- OpenTelemetry context propagation for nested spans
|
|
243
|
+
- Trace ID propagation utilities for distributed tracing
|
|
153
244
|
|
|
154
245
|
## Example
|
|
155
246
|
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
aiqa/__init__.py,sha256=0K19ymS_pZEi_3Uc9wKX4tcNZmpJs_NV9O8vhEN8Lvc,1563
|
|
2
|
+
aiqa/aiqa_exporter.py,sha256=Gf1gtVEEAMNrbWhlLp0mn7CdXntqqx-zlruBfB7tS7o,22104
|
|
3
|
+
aiqa/client.py,sha256=wE6EsypbTfp3Cz39IhEycEVT0IZGdJz7yQvtZ15qKJo,6364
|
|
4
|
+
aiqa/experiment_runner.py,sha256=ZEDwECstAv4lWXpcdB9WSxfDQj43iqkGzB_YzoY933M,12053
|
|
5
|
+
aiqa/object_serialiser.py,sha256=iFxVGw-liOFyrkmTWuD5Bm0zCLPTN4QbynR6IPDSVwI,12993
|
|
6
|
+
aiqa/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
|
+
aiqa/test_experiment_runner.py,sha256=LM8BuCrzBZL0Wyu_ierK0tNLsOUxxMTAHbAGW2G0qp0,5562
|
|
8
|
+
aiqa/test_tracing.py,sha256=mSVrhRQ6Dz5djlSUkCt097sIr84562w6E0BnuQDpMrI,8347
|
|
9
|
+
aiqa/tracing.py,sha256=akilXthvAz8NfJKl3293cHsdJU_P3z4kpdTDfwHipZ0,50014
|
|
10
|
+
aiqa_client-0.1.2.dist-info/licenses/LICENSE,sha256=kIzkzLuzG0HHaWYm4F4W5FeJ1Yxut3Ec6bhLWyw798A,1062
|
|
11
|
+
aiqa_client-0.1.2.dist-info/METADATA,sha256=MKGA1o2e8eUIviK8NT6cYGTVfrYWuR9zvc2FSJY9MNM,6712
|
|
12
|
+
aiqa_client-0.1.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
13
|
+
aiqa_client-0.1.2.dist-info/top_level.txt,sha256=nwcsuVVSuWu27iLxZd4n1evVzv1W6FVTrSnCXCc-NQs,5
|
|
14
|
+
aiqa_client-0.1.2.dist-info/RECORD,,
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
aiqa/__init__.py,sha256=FMWyKfD9ZiEd1LtgIPaTSU1LTcvCFqHCw8oth2aO5js,470
|
|
2
|
-
aiqa/aiqa_exporter.py,sha256=hxnvdjCIebVFAqpeb9nXLYEi8A1oDysp7DebXcHA4po,9396
|
|
3
|
-
aiqa/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
-
aiqa/tracing.py,sha256=Rk_XLVbBZqxiQRZVVi3Sedo9mkDTLUn9rZiUPdC7PTw,11325
|
|
5
|
-
aiqa_client-0.1.0.dist-info/licenses/LICENSE,sha256=kIzkzLuzG0HHaWYm4F4W5FeJ1Yxut3Ec6bhLWyw798A,1062
|
|
6
|
-
aiqa_client-0.1.0.dist-info/METADATA,sha256=gQgQZ6-LLbWucsVxSKQgR856JSgJWWtdUZA064pr-T0,3740
|
|
7
|
-
aiqa_client-0.1.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
8
|
-
aiqa_client-0.1.0.dist-info/top_level.txt,sha256=nwcsuVVSuWu27iLxZd4n1evVzv1W6FVTrSnCXCc-NQs,5
|
|
9
|
-
aiqa_client-0.1.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|