netra-sdk 0.1.34__py3-none-any.whl → 0.1.35__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.
Potentially problematic release.
This version of netra-sdk might be problematic. Click here for more details.
- netra/decorators.py +252 -29
- netra/session_manager.py +50 -7
- netra/version.py +1 -1
- {netra_sdk-0.1.34.dist-info → netra_sdk-0.1.35.dist-info}/METADATA +1 -1
- {netra_sdk-0.1.34.dist-info → netra_sdk-0.1.35.dist-info}/RECORD +7 -7
- {netra_sdk-0.1.34.dist-info → netra_sdk-0.1.35.dist-info}/LICENCE +0 -0
- {netra_sdk-0.1.34.dist-info → netra_sdk-0.1.35.dist-info}/WHEEL +0 -0
netra/decorators.py
CHANGED
|
@@ -8,7 +8,26 @@ import functools
|
|
|
8
8
|
import inspect
|
|
9
9
|
import json
|
|
10
10
|
import logging
|
|
11
|
-
from typing import
|
|
11
|
+
from typing import (
|
|
12
|
+
Any,
|
|
13
|
+
AsyncGenerator,
|
|
14
|
+
Awaitable,
|
|
15
|
+
Callable,
|
|
16
|
+
Dict,
|
|
17
|
+
Generator,
|
|
18
|
+
Optional,
|
|
19
|
+
ParamSpec,
|
|
20
|
+
Tuple,
|
|
21
|
+
TypeVar,
|
|
22
|
+
Union,
|
|
23
|
+
cast,
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
try:
|
|
27
|
+
# Optional import: only present in FastAPI/Starlette environments
|
|
28
|
+
from starlette.responses import StreamingResponse
|
|
29
|
+
except Exception: # pragma: no cover - starlette may not be installed in some environments
|
|
30
|
+
StreamingResponse = None
|
|
12
31
|
|
|
13
32
|
from opentelemetry import trace
|
|
14
33
|
|
|
@@ -73,6 +92,176 @@ def _add_output_attributes(span: trace.Span, result: Any) -> None:
|
|
|
73
92
|
span.set_attribute(f"{Config.LIBRARY_NAME}.entity.output_error", str(e))
|
|
74
93
|
|
|
75
94
|
|
|
95
|
+
def _is_streaming_response(obj: Any) -> bool:
|
|
96
|
+
"""Return True if obj is a Starlette StreamingResponse instance."""
|
|
97
|
+
if StreamingResponse is None:
|
|
98
|
+
return False
|
|
99
|
+
try:
|
|
100
|
+
return isinstance(obj, StreamingResponse)
|
|
101
|
+
except Exception:
|
|
102
|
+
return False
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def _is_async_generator(obj: Any) -> bool:
|
|
106
|
+
return inspect.isasyncgen(obj)
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def _is_sync_generator(obj: Any) -> bool:
|
|
110
|
+
return inspect.isgenerator(obj)
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def _wrap_async_generator_with_span(
|
|
114
|
+
span: trace.Span,
|
|
115
|
+
agen: AsyncGenerator[Any, None],
|
|
116
|
+
span_name: str,
|
|
117
|
+
entity_type: str,
|
|
118
|
+
) -> AsyncGenerator[Any, None]:
|
|
119
|
+
"""Wrap an async generator so the span remains current for the full iteration and ends afterwards."""
|
|
120
|
+
|
|
121
|
+
async def _wrapped() -> AsyncGenerator[Any, None]:
|
|
122
|
+
# Activate span for the entire iteration
|
|
123
|
+
with trace.use_span(span, end_on_exit=False):
|
|
124
|
+
try:
|
|
125
|
+
async for item in agen:
|
|
126
|
+
yield item
|
|
127
|
+
except Exception as e:
|
|
128
|
+
try:
|
|
129
|
+
span.set_attribute(f"{Config.LIBRARY_NAME}.entity.error", str(e))
|
|
130
|
+
span.record_exception(e)
|
|
131
|
+
finally:
|
|
132
|
+
span.end()
|
|
133
|
+
# De-register and pop entity at the very end for streaming lifecycle
|
|
134
|
+
try:
|
|
135
|
+
SessionManager.unregister_span(span_name, span)
|
|
136
|
+
except Exception:
|
|
137
|
+
logger.exception("Failed to unregister span '%s' from SessionManager", span_name)
|
|
138
|
+
SessionManager.pop_entity(entity_type)
|
|
139
|
+
raise
|
|
140
|
+
else:
|
|
141
|
+
# Normal completion
|
|
142
|
+
span.end()
|
|
143
|
+
try:
|
|
144
|
+
SessionManager.unregister_span(span_name, span)
|
|
145
|
+
except Exception:
|
|
146
|
+
logger.exception("Failed to unregister span '%s' from SessionManager", span_name)
|
|
147
|
+
SessionManager.pop_entity(entity_type)
|
|
148
|
+
|
|
149
|
+
return _wrapped()
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
def _wrap_sync_generator_with_span(
|
|
153
|
+
span: trace.Span,
|
|
154
|
+
gen: Generator[Any, None, None],
|
|
155
|
+
span_name: str,
|
|
156
|
+
entity_type: str,
|
|
157
|
+
) -> Generator[Any, None, None]:
|
|
158
|
+
"""Wrap a sync generator so the span remains current for the full iteration and ends afterwards."""
|
|
159
|
+
|
|
160
|
+
def _wrapped() -> Generator[Any, None, None]:
|
|
161
|
+
with trace.use_span(span, end_on_exit=False):
|
|
162
|
+
try:
|
|
163
|
+
for item in gen:
|
|
164
|
+
yield item
|
|
165
|
+
except Exception as e:
|
|
166
|
+
try:
|
|
167
|
+
span.set_attribute(f"{Config.LIBRARY_NAME}.entity.error", str(e))
|
|
168
|
+
span.record_exception(e)
|
|
169
|
+
finally:
|
|
170
|
+
span.end()
|
|
171
|
+
try:
|
|
172
|
+
SessionManager.unregister_span(span_name, span)
|
|
173
|
+
except Exception:
|
|
174
|
+
logger.exception("Failed to unregister span '%s' from SessionManager", span_name)
|
|
175
|
+
SessionManager.pop_entity(entity_type)
|
|
176
|
+
raise
|
|
177
|
+
else:
|
|
178
|
+
span.end()
|
|
179
|
+
try:
|
|
180
|
+
SessionManager.unregister_span(span_name, span)
|
|
181
|
+
except Exception:
|
|
182
|
+
logger.exception("Failed to unregister span '%s' from SessionManager", span_name)
|
|
183
|
+
SessionManager.pop_entity(entity_type)
|
|
184
|
+
|
|
185
|
+
return _wrapped()
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
def _wrap_streaming_response_with_span(
|
|
189
|
+
span: trace.Span,
|
|
190
|
+
resp: Any,
|
|
191
|
+
span_name: str,
|
|
192
|
+
entity_type: str,
|
|
193
|
+
) -> Any:
|
|
194
|
+
"""Wrap StreamingResponse.body_iterator with a generator that keeps span current and ends it afterwards."""
|
|
195
|
+
try:
|
|
196
|
+
body_iter = getattr(resp, "body_iterator", None)
|
|
197
|
+
if body_iter is None:
|
|
198
|
+
return resp
|
|
199
|
+
# Async iterator
|
|
200
|
+
if inspect.isasyncgen(body_iter) or hasattr(body_iter, "__aiter__"):
|
|
201
|
+
|
|
202
|
+
async def _aiter_wrapper(): # type: ignore[no-untyped-def]
|
|
203
|
+
with trace.use_span(span, end_on_exit=False):
|
|
204
|
+
try:
|
|
205
|
+
async for chunk in body_iter:
|
|
206
|
+
yield chunk
|
|
207
|
+
except Exception as e:
|
|
208
|
+
try:
|
|
209
|
+
span.set_attribute(f"{Config.LIBRARY_NAME}.entity.error", str(e))
|
|
210
|
+
span.record_exception(e)
|
|
211
|
+
finally:
|
|
212
|
+
span.end()
|
|
213
|
+
try:
|
|
214
|
+
SessionManager.unregister_span(span_name, span)
|
|
215
|
+
except Exception:
|
|
216
|
+
logger.exception("Failed to unregister span '%s' from SessionManager", span_name)
|
|
217
|
+
SessionManager.pop_entity(entity_type)
|
|
218
|
+
raise
|
|
219
|
+
else:
|
|
220
|
+
span.end()
|
|
221
|
+
try:
|
|
222
|
+
SessionManager.unregister_span(span_name, span)
|
|
223
|
+
except Exception:
|
|
224
|
+
logger.exception("Failed to unregister span '%s' from SessionManager", span_name)
|
|
225
|
+
SessionManager.pop_entity(entity_type)
|
|
226
|
+
|
|
227
|
+
resp.body_iterator = _aiter_wrapper() # type: ignore[no-untyped-call]
|
|
228
|
+
return resp
|
|
229
|
+
|
|
230
|
+
# Sync iterator
|
|
231
|
+
if inspect.isgenerator(body_iter) or hasattr(body_iter, "__iter__"):
|
|
232
|
+
|
|
233
|
+
def _iter_wrapper(): # type: ignore[no-untyped-def]
|
|
234
|
+
with trace.use_span(span, end_on_exit=False):
|
|
235
|
+
try:
|
|
236
|
+
for chunk in body_iter:
|
|
237
|
+
yield chunk
|
|
238
|
+
except Exception as e:
|
|
239
|
+
try:
|
|
240
|
+
span.set_attribute(f"{Config.LIBRARY_NAME}.entity.error", str(e))
|
|
241
|
+
span.record_exception(e)
|
|
242
|
+
finally:
|
|
243
|
+
span.end()
|
|
244
|
+
try:
|
|
245
|
+
SessionManager.unregister_span(span_name, span)
|
|
246
|
+
except Exception:
|
|
247
|
+
logger.exception("Failed to unregister span '%s' from SessionManager", span_name)
|
|
248
|
+
SessionManager.pop_entity(entity_type)
|
|
249
|
+
raise
|
|
250
|
+
else:
|
|
251
|
+
span.end()
|
|
252
|
+
try:
|
|
253
|
+
SessionManager.unregister_span(span_name, span)
|
|
254
|
+
except Exception:
|
|
255
|
+
logger.exception("Failed to unregister span '%s' from SessionManager", span_name)
|
|
256
|
+
SessionManager.pop_entity(entity_type)
|
|
257
|
+
|
|
258
|
+
resp.body_iterator = _iter_wrapper() # type: ignore[no-untyped-call]
|
|
259
|
+
return resp
|
|
260
|
+
except Exception:
|
|
261
|
+
logger.exception("Failed to wrap StreamingResponse with span '%s'", span_name)
|
|
262
|
+
return resp
|
|
263
|
+
|
|
264
|
+
|
|
76
265
|
def _create_function_wrapper(func: Callable[P, R], entity_type: str, name: Optional[str] = None) -> Callable[P, R]:
|
|
77
266
|
module_name = func.__name__
|
|
78
267
|
is_async = inspect.iscoroutinefunction(func)
|
|
@@ -82,33 +271,50 @@ def _create_function_wrapper(func: Callable[P, R], entity_type: str, name: Optio
|
|
|
82
271
|
|
|
83
272
|
@functools.wraps(func)
|
|
84
273
|
async def async_wrapper(*args: Any, **kwargs: Any) -> Any:
|
|
85
|
-
# Push entity
|
|
274
|
+
# Push entity before span starts so processors can capture it
|
|
86
275
|
SessionManager.push_entity(entity_type, span_name)
|
|
87
276
|
|
|
88
277
|
tracer = trace.get_tracer(module_name)
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
278
|
+
span = tracer.start_span(span_name)
|
|
279
|
+
# Register and activate span
|
|
280
|
+
try:
|
|
281
|
+
SessionManager.register_span(span_name, span)
|
|
282
|
+
SessionManager.set_current_span(span)
|
|
283
|
+
except Exception:
|
|
284
|
+
logger.exception("Failed to register span '%s' with SessionManager", span_name)
|
|
285
|
+
|
|
286
|
+
with trace.use_span(span, end_on_exit=False):
|
|
97
287
|
_add_span_attributes(span, func, args, kwargs, entity_type)
|
|
98
288
|
try:
|
|
99
289
|
result = await cast(Awaitable[Any], func(*args, **kwargs))
|
|
100
|
-
_add_output_attributes(span, result)
|
|
101
|
-
return result
|
|
102
290
|
except Exception as e:
|
|
103
291
|
span.set_attribute(f"{Config.LIBRARY_NAME}.entity.error", str(e))
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
# Unregister and pop entity from stack after function call is done
|
|
292
|
+
span.record_exception(e)
|
|
293
|
+
span.end()
|
|
107
294
|
try:
|
|
108
295
|
SessionManager.unregister_span(span_name, span)
|
|
109
296
|
except Exception:
|
|
110
297
|
logger.exception("Failed to unregister span '%s' from SessionManager", span_name)
|
|
111
298
|
SessionManager.pop_entity(entity_type)
|
|
299
|
+
raise
|
|
300
|
+
|
|
301
|
+
# If result is streaming, defer span end to when stream completes
|
|
302
|
+
if _is_streaming_response(result):
|
|
303
|
+
return _wrap_streaming_response_with_span(span, result, span_name, entity_type)
|
|
304
|
+
if _is_async_generator(result):
|
|
305
|
+
return _wrap_async_generator_with_span(span, result, span_name, entity_type)
|
|
306
|
+
if _is_sync_generator(result):
|
|
307
|
+
return _wrap_sync_generator_with_span(span, result, span_name, entity_type)
|
|
308
|
+
|
|
309
|
+
# Non-streaming: finalize now
|
|
310
|
+
_add_output_attributes(span, result)
|
|
311
|
+
span.end()
|
|
312
|
+
try:
|
|
313
|
+
SessionManager.unregister_span(span_name, span)
|
|
314
|
+
except Exception:
|
|
315
|
+
logger.exception("Failed to unregister span '%s' from SessionManager", span_name)
|
|
316
|
+
SessionManager.pop_entity(entity_type)
|
|
317
|
+
return result
|
|
112
318
|
|
|
113
319
|
return cast(Callable[P, R], async_wrapper)
|
|
114
320
|
|
|
@@ -116,33 +322,50 @@ def _create_function_wrapper(func: Callable[P, R], entity_type: str, name: Optio
|
|
|
116
322
|
|
|
117
323
|
@functools.wraps(func)
|
|
118
324
|
def sync_wrapper(*args: Any, **kwargs: Any) -> Any:
|
|
119
|
-
# Push entity
|
|
325
|
+
# Push entity before span starts so processors can capture it
|
|
120
326
|
SessionManager.push_entity(entity_type, span_name)
|
|
121
327
|
|
|
122
328
|
tracer = trace.get_tracer(module_name)
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
329
|
+
span = tracer.start_span(span_name)
|
|
330
|
+
# Register and activate span
|
|
331
|
+
try:
|
|
332
|
+
SessionManager.register_span(span_name, span)
|
|
333
|
+
SessionManager.set_current_span(span)
|
|
334
|
+
except Exception:
|
|
335
|
+
logger.exception("Failed to register span '%s' with SessionManager", span_name)
|
|
336
|
+
|
|
337
|
+
with trace.use_span(span, end_on_exit=False):
|
|
131
338
|
_add_span_attributes(span, func, args, kwargs, entity_type)
|
|
132
339
|
try:
|
|
133
340
|
result = func(*args, **kwargs)
|
|
134
|
-
_add_output_attributes(span, result)
|
|
135
|
-
return result
|
|
136
341
|
except Exception as e:
|
|
137
342
|
span.set_attribute(f"{Config.LIBRARY_NAME}.entity.error", str(e))
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
# Unregister and pop entity from stack after function call is done
|
|
343
|
+
span.record_exception(e)
|
|
344
|
+
span.end()
|
|
141
345
|
try:
|
|
142
346
|
SessionManager.unregister_span(span_name, span)
|
|
143
347
|
except Exception:
|
|
144
348
|
logger.exception("Failed to unregister span '%s' from SessionManager", span_name)
|
|
145
349
|
SessionManager.pop_entity(entity_type)
|
|
350
|
+
raise
|
|
351
|
+
|
|
352
|
+
# If result is streaming, defer span end to when stream completes
|
|
353
|
+
if _is_streaming_response(result):
|
|
354
|
+
return _wrap_streaming_response_with_span(span, result, span_name, entity_type)
|
|
355
|
+
if _is_async_generator(result):
|
|
356
|
+
return _wrap_async_generator_with_span(span, result, span_name, entity_type) # type: ignore[arg-type]
|
|
357
|
+
if _is_sync_generator(result):
|
|
358
|
+
return _wrap_sync_generator_with_span(span, result, span_name, entity_type) # type: ignore[arg-type]
|
|
359
|
+
|
|
360
|
+
# Non-streaming: finalize now
|
|
361
|
+
_add_output_attributes(span, result)
|
|
362
|
+
span.end()
|
|
363
|
+
try:
|
|
364
|
+
SessionManager.unregister_span(span_name, span)
|
|
365
|
+
except Exception:
|
|
366
|
+
logger.exception("Failed to unregister span '%s' from SessionManager", span_name)
|
|
367
|
+
SessionManager.pop_entity(entity_type)
|
|
368
|
+
return result
|
|
146
369
|
|
|
147
370
|
return cast(Callable[P, R], sync_wrapper)
|
|
148
371
|
|
netra/session_manager.py
CHANGED
|
@@ -31,6 +31,10 @@ class SessionManager:
|
|
|
31
31
|
# Span registry: name -> stack of spans (most-recent last)
|
|
32
32
|
_spans_by_name: Dict[str, List[trace.Span]] = {}
|
|
33
33
|
|
|
34
|
+
# Global stack of active spans in creation order (oldest first, newest last)
|
|
35
|
+
# Maintained for spans registered via SessionManager (e.g., SpanWrapper)
|
|
36
|
+
_active_spans: List[trace.Span] = []
|
|
37
|
+
|
|
34
38
|
@classmethod
|
|
35
39
|
def set_current_span(cls, span: Optional[trace.Span]) -> None:
|
|
36
40
|
"""
|
|
@@ -62,6 +66,8 @@ class SessionManager:
|
|
|
62
66
|
cls._spans_by_name[name] = [span]
|
|
63
67
|
else:
|
|
64
68
|
stack.append(span)
|
|
69
|
+
# Track globally as active
|
|
70
|
+
cls._active_spans.append(span)
|
|
65
71
|
except Exception:
|
|
66
72
|
logger.exception("Failed to register span '%s'", name)
|
|
67
73
|
|
|
@@ -81,6 +87,11 @@ class SessionManager:
|
|
|
81
87
|
break
|
|
82
88
|
if not stack:
|
|
83
89
|
cls._spans_by_name.pop(name, None)
|
|
90
|
+
# Also remove from global active list (remove last matching instance)
|
|
91
|
+
for i in range(len(cls._active_spans) - 1, -1, -1):
|
|
92
|
+
if cls._active_spans[i] is span:
|
|
93
|
+
cls._active_spans.pop(i)
|
|
94
|
+
break
|
|
84
95
|
except Exception:
|
|
85
96
|
logger.exception("Failed to unregister span '%s'", name)
|
|
86
97
|
|
|
@@ -240,12 +251,13 @@ class SessionManager:
|
|
|
240
251
|
@classmethod
|
|
241
252
|
def set_attribute_on_target_span(cls, attr_key: str, attr_value: Any, span_name: Optional[str] = None) -> None:
|
|
242
253
|
"""
|
|
243
|
-
Best-effort setter to annotate
|
|
254
|
+
Best-effort setter to annotate a target span with the provided attribute.
|
|
244
255
|
|
|
245
|
-
|
|
246
|
-
the attribute on
|
|
247
|
-
|
|
248
|
-
|
|
256
|
+
Behavior:
|
|
257
|
+
- If span_name is provided, set the attribute on the span registered with that name.
|
|
258
|
+
- If no span_name is provided, attempt to set the attribute on the SDK root span
|
|
259
|
+
(created when Netra.init(enable_root_span=True)). If the root span is unavailable,
|
|
260
|
+
fall back to the currently active span (OTel current span or SDK-managed current span).
|
|
249
261
|
"""
|
|
250
262
|
try:
|
|
251
263
|
# Convert attribute value to a JSON-safe string representation
|
|
@@ -268,10 +280,41 @@ class SessionManager:
|
|
|
268
280
|
target.set_attribute(attr_key, attr_str)
|
|
269
281
|
return
|
|
270
282
|
|
|
271
|
-
# Otherwise
|
|
283
|
+
# Otherwise, attempt to set on the root-most span in the current trace
|
|
284
|
+
candidate = None
|
|
285
|
+
|
|
286
|
+
# Determine current trace_id from the active/current span
|
|
272
287
|
current_span = trace.get_current_span()
|
|
273
288
|
has_valid_current = getattr(current_span, "is_recording", None) is not None and current_span.is_recording()
|
|
274
|
-
|
|
289
|
+
base_span = current_span if has_valid_current else cls.get_current_span()
|
|
290
|
+
trace_id: Optional[int] = None
|
|
291
|
+
try:
|
|
292
|
+
if base_span is not None and hasattr(base_span, "get_span_context"):
|
|
293
|
+
sc = base_span.get_span_context()
|
|
294
|
+
trace_id = getattr(sc, "trace_id", None)
|
|
295
|
+
except Exception:
|
|
296
|
+
trace_id = None
|
|
297
|
+
|
|
298
|
+
# Find the earliest active span in this process that belongs to the same trace
|
|
299
|
+
if trace_id is not None:
|
|
300
|
+
try:
|
|
301
|
+
for s in cls._active_spans:
|
|
302
|
+
if s is None:
|
|
303
|
+
continue
|
|
304
|
+
if not getattr(s, "is_recording", lambda: False)():
|
|
305
|
+
continue
|
|
306
|
+
sc = getattr(s, "get_span_context", lambda: None)()
|
|
307
|
+
if sc is None:
|
|
308
|
+
continue
|
|
309
|
+
if getattr(sc, "trace_id", None) == trace_id:
|
|
310
|
+
candidate = s
|
|
311
|
+
break
|
|
312
|
+
except Exception:
|
|
313
|
+
candidate = None
|
|
314
|
+
|
|
315
|
+
# Fallback to the current active span if no root-most could be found
|
|
316
|
+
if candidate is None:
|
|
317
|
+
candidate = base_span
|
|
275
318
|
if candidate is None:
|
|
276
319
|
logger.debug("No active span found to set attribute %s", attr_key)
|
|
277
320
|
return
|
netra/version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "0.1.
|
|
1
|
+
__version__ = "0.1.35"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: netra-sdk
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.35
|
|
4
4
|
Summary: A Python SDK for AI application observability that provides OpenTelemetry-based monitoring, tracing, and PII protection for LLM and vector database applications. Enables easy instrumentation, session tracking, and privacy-focused data collection for AI systems in production environments.
|
|
5
5
|
License: Apache-2.0
|
|
6
6
|
Keywords: netra,tracing,observability,sdk,ai,llm,vector,database
|
|
@@ -4,7 +4,7 @@ netra/anonymizer/anonymizer.py,sha256=IcrYkdwWrFauGWUeAW-0RwrSUM8VSZCFNtoywZhvIq
|
|
|
4
4
|
netra/anonymizer/base.py,sha256=ytPxHCUD2OXlEY6fNTuMmwImNdIjgj294I41FIgoXpU,5946
|
|
5
5
|
netra/anonymizer/fp_anonymizer.py,sha256=_6svIYmE0eejdIMkhKBUWCNjGtGimtrGtbLvPSOp8W4,6493
|
|
6
6
|
netra/config.py,sha256=51m8R0NoOrw58gMV7arOniEuFdJ7EIu3PNdFtIQ5xfg,6893
|
|
7
|
-
netra/decorators.py,sha256=
|
|
7
|
+
netra/decorators.py,sha256=qZFHrwdj10FsTFqggo3XjdGB12aMxsrrDMMmslDqZ-0,17424
|
|
8
8
|
netra/exceptions/__init__.py,sha256=uDgcBxmC4WhdS7HRYQk_TtJyxH1s1o6wZmcsnSHLAcM,174
|
|
9
9
|
netra/exceptions/injection.py,sha256=ke4eUXRYUFJkMZgdSyPPkPt5PdxToTI6xLEBI0hTWUQ,1332
|
|
10
10
|
netra/exceptions/pii.py,sha256=MT4p_x-zH3VtYudTSxw1Z9qQZADJDspq64WrYqSWlZc,2438
|
|
@@ -45,11 +45,11 @@ netra/processors/instrumentation_span_processor.py,sha256=Ef5FTr8O5FLHcIkBAW3ueU
|
|
|
45
45
|
netra/processors/scrubbing_span_processor.py,sha256=dJ86Ncmjvmrhm_uAdGTwcGvRpZbVVWqD9AOFwEMWHZY,6701
|
|
46
46
|
netra/processors/session_span_processor.py,sha256=qcsBl-LnILWefsftI8NQhXDGb94OWPc8LvzhVA0JS_c,2432
|
|
47
47
|
netra/scanner.py,sha256=kyDpeZiscCPb6pjuhS-sfsVj-dviBFRepdUWh0sLoEY,11554
|
|
48
|
-
netra/session_manager.py,sha256=
|
|
48
|
+
netra/session_manager.py,sha256=pyhtWYwFkrieNfrVFxSqxDsErPZzxPIt94zqvABLTAI,12229
|
|
49
49
|
netra/span_wrapper.py,sha256=IygQX78xQRlL_Z1MfKfUbv0okihx92qNClnRlYFtRNc,8004
|
|
50
50
|
netra/tracer.py,sha256=FJO8Cine-WL9K_4wn6RVjQOgX6c1JCp_8QowUbRSVHk,7718
|
|
51
|
-
netra/version.py,sha256=
|
|
52
|
-
netra_sdk-0.1.
|
|
53
|
-
netra_sdk-0.1.
|
|
54
|
-
netra_sdk-0.1.
|
|
55
|
-
netra_sdk-0.1.
|
|
51
|
+
netra/version.py,sha256=ABqgofsnbWf7823vTBbZNQ81eKQbWwrVToAU6T3z-6s,23
|
|
52
|
+
netra_sdk-0.1.35.dist-info/LICENCE,sha256=8B_UoZ-BAl0AqiHAHUETCgd3I2B9yYJ1WEQtVb_qFMA,11359
|
|
53
|
+
netra_sdk-0.1.35.dist-info/METADATA,sha256=Aewd-yCWdZ32uabTT_io4cnfSmrciVuugAxVgDy22nw,28210
|
|
54
|
+
netra_sdk-0.1.35.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
|
55
|
+
netra_sdk-0.1.35.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|