netra-sdk 0.1.0__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.

Files changed (42) hide show
  1. netra/__init__.py +148 -0
  2. netra/anonymizer/__init__.py +7 -0
  3. netra/anonymizer/anonymizer.py +79 -0
  4. netra/anonymizer/base.py +159 -0
  5. netra/anonymizer/fp_anonymizer.py +182 -0
  6. netra/config.py +111 -0
  7. netra/decorators.py +167 -0
  8. netra/exceptions/__init__.py +6 -0
  9. netra/exceptions/injection.py +33 -0
  10. netra/exceptions/pii.py +46 -0
  11. netra/input_scanner.py +142 -0
  12. netra/instrumentation/__init__.py +257 -0
  13. netra/instrumentation/aiohttp/__init__.py +378 -0
  14. netra/instrumentation/aiohttp/version.py +1 -0
  15. netra/instrumentation/cohere/__init__.py +446 -0
  16. netra/instrumentation/cohere/version.py +1 -0
  17. netra/instrumentation/google_genai/__init__.py +506 -0
  18. netra/instrumentation/google_genai/config.py +5 -0
  19. netra/instrumentation/google_genai/utils.py +31 -0
  20. netra/instrumentation/google_genai/version.py +1 -0
  21. netra/instrumentation/httpx/__init__.py +545 -0
  22. netra/instrumentation/httpx/version.py +1 -0
  23. netra/instrumentation/instruments.py +78 -0
  24. netra/instrumentation/mistralai/__init__.py +545 -0
  25. netra/instrumentation/mistralai/config.py +5 -0
  26. netra/instrumentation/mistralai/utils.py +30 -0
  27. netra/instrumentation/mistralai/version.py +1 -0
  28. netra/instrumentation/weaviate/__init__.py +121 -0
  29. netra/instrumentation/weaviate/version.py +1 -0
  30. netra/pii.py +757 -0
  31. netra/processors/__init__.py +4 -0
  32. netra/processors/session_span_processor.py +55 -0
  33. netra/processors/span_aggregation_processor.py +365 -0
  34. netra/scanner.py +104 -0
  35. netra/session.py +185 -0
  36. netra/session_manager.py +96 -0
  37. netra/tracer.py +99 -0
  38. netra/version.py +1 -0
  39. netra_sdk-0.1.0.dist-info/LICENCE +201 -0
  40. netra_sdk-0.1.0.dist-info/METADATA +573 -0
  41. netra_sdk-0.1.0.dist-info/RECORD +42 -0
  42. netra_sdk-0.1.0.dist-info/WHEEL +4 -0
@@ -0,0 +1,545 @@
1
+ from __future__ import annotations
2
+
3
+ import functools
4
+ import logging
5
+ import types
6
+ from timeit import default_timer
7
+ from typing import Any, Callable, Collection, Dict, Optional, Union
8
+ from urllib.parse import urlparse
9
+
10
+ import httpx
11
+ from opentelemetry.instrumentation._semconv import (
12
+ HTTP_DURATION_HISTOGRAM_BUCKETS_NEW,
13
+ HTTP_DURATION_HISTOGRAM_BUCKETS_OLD,
14
+ _client_duration_attrs_new,
15
+ _client_duration_attrs_old,
16
+ _filter_semconv_duration_attrs,
17
+ _get_schema_url,
18
+ _OpenTelemetrySemanticConventionStability,
19
+ _OpenTelemetryStabilitySignalType,
20
+ _report_new,
21
+ _report_old,
22
+ _set_http_host_client,
23
+ _set_http_method,
24
+ _set_http_net_peer_name_client,
25
+ _set_http_network_protocol_version,
26
+ _set_http_peer_port_client,
27
+ _set_http_scheme,
28
+ _set_http_url,
29
+ _set_status,
30
+ _StabilityMode,
31
+ )
32
+ from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
33
+ from opentelemetry.instrumentation.utils import (
34
+ is_http_instrumentation_enabled,
35
+ suppress_http_instrumentation,
36
+ )
37
+ from opentelemetry.metrics import Histogram, get_meter
38
+ from opentelemetry.propagate import inject
39
+ from opentelemetry.semconv.attributes.error_attributes import ERROR_TYPE
40
+ from opentelemetry.semconv.attributes.network_attributes import (
41
+ NETWORK_PEER_ADDRESS,
42
+ NETWORK_PEER_PORT,
43
+ )
44
+ from opentelemetry.semconv.metrics import MetricInstruments
45
+ from opentelemetry.semconv.metrics.http_metrics import (
46
+ HTTP_CLIENT_REQUEST_DURATION,
47
+ )
48
+ from opentelemetry.trace import SpanKind, Tracer, get_tracer
49
+ from opentelemetry.trace.span import Span
50
+ from opentelemetry.util.http import (
51
+ ExcludeList,
52
+ get_excluded_urls,
53
+ parse_excluded_urls,
54
+ remove_url_credentials,
55
+ sanitize_method,
56
+ )
57
+ from opentelemetry.util.http.httplib import set_ip_on_next_http_connection
58
+
59
+ from netra.instrumentation.httpx.version import __version__
60
+
61
+ logger = logging.getLogger(__name__)
62
+
63
+ # Package info for httpx instrumentation
64
+ _instruments = ("httpx >= 0.18.0",)
65
+
66
+ _excluded_urls_from_env = get_excluded_urls("HTTPX")
67
+
68
+ _RequestHookT = Optional[Callable[[Span, httpx.Request], None]]
69
+ _ResponseHookT = Optional[Callable[[Span, httpx.Request, httpx.Response], None]]
70
+
71
+
72
+ def _set_http_status_code_attribute(
73
+ span: Span,
74
+ status_code: Union[int, str],
75
+ metric_attributes: Optional[Dict[str, Any]] = None,
76
+ sem_conv_opt_in_mode: _StabilityMode = _StabilityMode.DEFAULT,
77
+ ) -> None:
78
+ status_code_str = str(status_code)
79
+ try:
80
+ status_code_int = int(status_code)
81
+ except ValueError:
82
+ status_code_int = -1
83
+ if metric_attributes is None:
84
+ metric_attributes = {}
85
+ _set_status(
86
+ span,
87
+ metric_attributes,
88
+ status_code_int,
89
+ status_code_str,
90
+ server_span=False,
91
+ sem_conv_opt_in_mode=sem_conv_opt_in_mode,
92
+ )
93
+
94
+
95
+ def _instrument(
96
+ tracer: Tracer,
97
+ duration_histogram_old: Optional[Histogram],
98
+ duration_histogram_new: Optional[Histogram],
99
+ request_hook: _RequestHookT = None,
100
+ response_hook: _ResponseHookT = None,
101
+ excluded_urls: Optional[ExcludeList] = None,
102
+ sem_conv_opt_in_mode: _StabilityMode = _StabilityMode.DEFAULT,
103
+ ) -> None:
104
+ """Enables tracing of all httpx calls that go through
105
+ :code:`httpx.Client.send` and :code:`httpx.AsyncClient.send`."""
106
+
107
+ # Instrument sync client
108
+ wrapped_send = httpx.Client.send
109
+
110
+ @functools.wraps(wrapped_send)
111
+ def instrumented_send(self: httpx.Client, request: httpx.Request, **kwargs: Any) -> httpx.Response:
112
+ if excluded_urls and excluded_urls.url_disabled(str(request.url)):
113
+ return wrapped_send(self, request, **kwargs)
114
+
115
+ if not is_http_instrumentation_enabled():
116
+ return wrapped_send(self, request, **kwargs)
117
+
118
+ return _trace_request(
119
+ tracer,
120
+ duration_histogram_old,
121
+ duration_histogram_new,
122
+ request,
123
+ wrapped_send,
124
+ self,
125
+ request_hook,
126
+ response_hook,
127
+ sem_conv_opt_in_mode,
128
+ **kwargs,
129
+ )
130
+
131
+ # Type ignore for dynamic attribute assignment
132
+ instrumented_send.opentelemetry_instrumentation_httpx_applied = True # type: ignore
133
+ httpx.Client.send = instrumented_send
134
+
135
+ # Instrument async client
136
+ wrapped_async_send = httpx.AsyncClient.send
137
+
138
+ @functools.wraps(wrapped_async_send)
139
+ async def instrumented_async_send(self: httpx.AsyncClient, request: httpx.Request, **kwargs: Any) -> httpx.Response:
140
+ if excluded_urls and excluded_urls.url_disabled(str(request.url)):
141
+ return await wrapped_async_send(self, request, **kwargs)
142
+
143
+ if not is_http_instrumentation_enabled():
144
+ return await wrapped_async_send(self, request, **kwargs)
145
+
146
+ return await _trace_async_request(
147
+ tracer,
148
+ duration_histogram_old,
149
+ duration_histogram_new,
150
+ request,
151
+ wrapped_async_send,
152
+ self,
153
+ request_hook,
154
+ response_hook,
155
+ sem_conv_opt_in_mode,
156
+ **kwargs,
157
+ )
158
+
159
+ # Type ignore for dynamic attribute assignment
160
+ instrumented_async_send.opentelemetry_instrumentation_httpx_applied = True # type: ignore
161
+ httpx.AsyncClient.send = instrumented_async_send
162
+
163
+
164
+ def _trace_request(
165
+ tracer: Tracer,
166
+ duration_histogram_old: Optional[Histogram],
167
+ duration_histogram_new: Optional[Histogram],
168
+ request: httpx.Request,
169
+ send_func: Callable[..., httpx.Response],
170
+ client: httpx.Client,
171
+ request_hook: _RequestHookT,
172
+ response_hook: _ResponseHookT,
173
+ sem_conv_opt_in_mode: _StabilityMode,
174
+ **kwargs: Any,
175
+ ) -> httpx.Response:
176
+ """Trace a synchronous HTTP request."""
177
+ method = request.method
178
+ span_name = get_default_span_name(method)
179
+ url = remove_url_credentials(str(request.url))
180
+
181
+ span_attributes: Dict[str, Any] = {}
182
+ _set_http_method(
183
+ span_attributes,
184
+ method,
185
+ sanitize_method(method),
186
+ sem_conv_opt_in_mode,
187
+ )
188
+ _set_http_url(span_attributes, url, sem_conv_opt_in_mode)
189
+
190
+ metric_labels: Dict[str, Any] = {}
191
+ _set_http_method(
192
+ metric_labels,
193
+ method,
194
+ sanitize_method(method),
195
+ sem_conv_opt_in_mode,
196
+ )
197
+
198
+ try:
199
+ parsed_url = urlparse(url)
200
+ if parsed_url.scheme:
201
+ if _report_old(sem_conv_opt_in_mode):
202
+ _set_http_scheme(metric_labels, parsed_url.scheme, sem_conv_opt_in_mode)
203
+ if parsed_url.hostname:
204
+ _set_http_host_client(metric_labels, parsed_url.hostname, sem_conv_opt_in_mode)
205
+ _set_http_net_peer_name_client(metric_labels, parsed_url.hostname, sem_conv_opt_in_mode)
206
+ if _report_new(sem_conv_opt_in_mode):
207
+ _set_http_host_client(
208
+ span_attributes,
209
+ parsed_url.hostname,
210
+ sem_conv_opt_in_mode,
211
+ )
212
+ span_attributes[NETWORK_PEER_ADDRESS] = parsed_url.hostname
213
+ if parsed_url.port:
214
+ _set_http_peer_port_client(metric_labels, parsed_url.port, sem_conv_opt_in_mode)
215
+ if _report_new(sem_conv_opt_in_mode):
216
+ _set_http_peer_port_client(span_attributes, parsed_url.port, sem_conv_opt_in_mode)
217
+ span_attributes[NETWORK_PEER_PORT] = parsed_url.port
218
+ except ValueError as error:
219
+ logger.error(error)
220
+
221
+ with (
222
+ tracer.start_as_current_span(span_name, kind=SpanKind.CLIENT, attributes=span_attributes) as span,
223
+ set_ip_on_next_http_connection(span),
224
+ ):
225
+ exception = None
226
+ if callable(request_hook):
227
+ request_hook(span, request)
228
+
229
+ headers = dict(request.headers)
230
+ inject(headers)
231
+ request.headers.update(headers)
232
+
233
+ with suppress_http_instrumentation():
234
+ start_time = default_timer()
235
+ try:
236
+ result = send_func(client, request, **kwargs)
237
+ except Exception as exc:
238
+ exception = exc
239
+ result = getattr(exc, "response", None)
240
+ finally:
241
+ elapsed_time = max(default_timer() - start_time, 0)
242
+
243
+ if isinstance(result, httpx.Response):
244
+ span_attributes_response: Dict[str, Any] = {}
245
+ _set_http_status_code_attribute(
246
+ span,
247
+ result.status_code,
248
+ metric_labels,
249
+ sem_conv_opt_in_mode,
250
+ )
251
+
252
+ if hasattr(result, "http_version"):
253
+ version_text = result.http_version
254
+ _set_http_network_protocol_version(metric_labels, version_text, sem_conv_opt_in_mode)
255
+ if _report_new(sem_conv_opt_in_mode):
256
+ _set_http_network_protocol_version(
257
+ span_attributes_response,
258
+ version_text,
259
+ sem_conv_opt_in_mode,
260
+ )
261
+
262
+ for key, val in span_attributes_response.items():
263
+ span.set_attribute(key, val)
264
+
265
+ if callable(response_hook):
266
+ response_hook(span, request, result)
267
+
268
+ if exception is not None and _report_new(sem_conv_opt_in_mode):
269
+ span.set_attribute(ERROR_TYPE, type(exception).__qualname__)
270
+ metric_labels[ERROR_TYPE] = type(exception).__qualname__
271
+
272
+ _record_duration_metrics(
273
+ duration_histogram_old,
274
+ duration_histogram_new,
275
+ elapsed_time,
276
+ metric_labels,
277
+ sem_conv_opt_in_mode,
278
+ )
279
+
280
+ if exception is not None:
281
+ raise exception.with_traceback(exception.__traceback__)
282
+
283
+ return result
284
+
285
+
286
+ async def _trace_async_request(
287
+ tracer: Tracer,
288
+ duration_histogram_old: Optional[Histogram],
289
+ duration_histogram_new: Optional[Histogram],
290
+ request: httpx.Request,
291
+ send_func: Callable[..., Any],
292
+ client: httpx.AsyncClient,
293
+ request_hook: _RequestHookT,
294
+ response_hook: _ResponseHookT,
295
+ sem_conv_opt_in_mode: _StabilityMode,
296
+ **kwargs: Any,
297
+ ) -> httpx.Response:
298
+ """Trace an asynchronous HTTP request."""
299
+ method = request.method
300
+ span_name = get_default_span_name(method)
301
+ url = remove_url_credentials(str(request.url))
302
+
303
+ span_attributes: Dict[str, Any] = {}
304
+ _set_http_method(
305
+ span_attributes,
306
+ method,
307
+ sanitize_method(method),
308
+ sem_conv_opt_in_mode,
309
+ )
310
+ _set_http_url(span_attributes, url, sem_conv_opt_in_mode)
311
+
312
+ metric_labels: Dict[str, Any] = {}
313
+ _set_http_method(
314
+ metric_labels,
315
+ method,
316
+ sanitize_method(method),
317
+ sem_conv_opt_in_mode,
318
+ )
319
+
320
+ try:
321
+ parsed_url = urlparse(url)
322
+ if parsed_url.scheme:
323
+ if _report_old(sem_conv_opt_in_mode):
324
+ _set_http_scheme(metric_labels, parsed_url.scheme, sem_conv_opt_in_mode)
325
+ if parsed_url.hostname:
326
+ _set_http_host_client(metric_labels, parsed_url.hostname, sem_conv_opt_in_mode)
327
+ _set_http_net_peer_name_client(metric_labels, parsed_url.hostname, sem_conv_opt_in_mode)
328
+ if _report_new(sem_conv_opt_in_mode):
329
+ _set_http_host_client(
330
+ span_attributes,
331
+ parsed_url.hostname,
332
+ sem_conv_opt_in_mode,
333
+ )
334
+ span_attributes[NETWORK_PEER_ADDRESS] = parsed_url.hostname
335
+ if parsed_url.port:
336
+ _set_http_peer_port_client(metric_labels, parsed_url.port, sem_conv_opt_in_mode)
337
+ if _report_new(sem_conv_opt_in_mode):
338
+ _set_http_peer_port_client(span_attributes, parsed_url.port, sem_conv_opt_in_mode)
339
+ span_attributes[NETWORK_PEER_PORT] = parsed_url.port
340
+ except ValueError as error:
341
+ logger.error(error)
342
+
343
+ with (
344
+ tracer.start_as_current_span(span_name, kind=SpanKind.CLIENT, attributes=span_attributes) as span,
345
+ set_ip_on_next_http_connection(span),
346
+ ):
347
+ exception = None
348
+ if callable(request_hook):
349
+ request_hook(span, request)
350
+
351
+ headers = dict(request.headers)
352
+ inject(headers)
353
+ request.headers.update(headers)
354
+
355
+ with suppress_http_instrumentation():
356
+ start_time = default_timer()
357
+ try:
358
+ result = await send_func(client, request, **kwargs)
359
+ except Exception as exc:
360
+ exception = exc
361
+ result = getattr(exc, "response", None)
362
+ finally:
363
+ elapsed_time = max(default_timer() - start_time, 0)
364
+
365
+ if isinstance(result, httpx.Response):
366
+ span_attributes_response: Dict[str, Any] = {}
367
+ _set_http_status_code_attribute(
368
+ span,
369
+ result.status_code,
370
+ metric_labels,
371
+ sem_conv_opt_in_mode,
372
+ )
373
+
374
+ if hasattr(result, "http_version"):
375
+ version_text = result.http_version
376
+ _set_http_network_protocol_version(metric_labels, version_text, sem_conv_opt_in_mode)
377
+ if _report_new(sem_conv_opt_in_mode):
378
+ _set_http_network_protocol_version(
379
+ span_attributes_response,
380
+ version_text,
381
+ sem_conv_opt_in_mode,
382
+ )
383
+
384
+ for key, val in span_attributes_response.items():
385
+ span.set_attribute(key, val)
386
+
387
+ if callable(response_hook):
388
+ response_hook(span, request, result)
389
+
390
+ if exception is not None and _report_new(sem_conv_opt_in_mode):
391
+ span.set_attribute(ERROR_TYPE, type(exception).__qualname__)
392
+ metric_labels[ERROR_TYPE] = type(exception).__qualname__
393
+
394
+ _record_duration_metrics(
395
+ duration_histogram_old,
396
+ duration_histogram_new,
397
+ elapsed_time,
398
+ metric_labels,
399
+ sem_conv_opt_in_mode,
400
+ )
401
+
402
+ if exception is not None:
403
+ raise exception.with_traceback(exception.__traceback__)
404
+
405
+ return result
406
+
407
+
408
+ def _record_duration_metrics(
409
+ duration_histogram_old: Optional[Histogram],
410
+ duration_histogram_new: Optional[Histogram],
411
+ elapsed_time: float,
412
+ metric_labels: Dict[str, Any],
413
+ sem_conv_opt_in_mode: _StabilityMode,
414
+ ) -> None:
415
+ """Record duration metrics for HTTP requests."""
416
+ if duration_histogram_old is not None:
417
+ duration_attrs_old = _filter_semconv_duration_attrs(
418
+ metric_labels,
419
+ _client_duration_attrs_old,
420
+ _client_duration_attrs_new,
421
+ _StabilityMode.DEFAULT,
422
+ )
423
+ duration_histogram_old.record(
424
+ max(round(elapsed_time * 1000), 0),
425
+ attributes=duration_attrs_old,
426
+ )
427
+ if duration_histogram_new is not None:
428
+ duration_attrs_new = _filter_semconv_duration_attrs(
429
+ metric_labels,
430
+ _client_duration_attrs_old,
431
+ _client_duration_attrs_new,
432
+ _StabilityMode.HTTP,
433
+ )
434
+ duration_histogram_new.record(elapsed_time, attributes=duration_attrs_new)
435
+
436
+
437
+ def _uninstrument() -> None:
438
+ """Disables instrumentation of :code:`httpx` through this module.
439
+
440
+ Note that this only works if no other module also patches httpx."""
441
+ _uninstrument_from(httpx.Client)
442
+ _uninstrument_from(httpx.AsyncClient)
443
+
444
+
445
+ def _uninstrument_from(instr_root: Union[type, object], restore_as_bound_func: bool = False) -> None:
446
+ for instr_func_name in ("send",):
447
+ instr_func = getattr(instr_root, instr_func_name)
448
+ if not getattr(
449
+ instr_func,
450
+ "opentelemetry_instrumentation_httpx_applied",
451
+ False,
452
+ ):
453
+ continue
454
+
455
+ original = instr_func.__wrapped__
456
+ if restore_as_bound_func:
457
+ original = types.MethodType(original, instr_root)
458
+ setattr(instr_root, instr_func_name, original)
459
+
460
+
461
+ def get_default_span_name(method: str) -> str:
462
+ """
463
+ Default implementation for name_callback, returns HTTP {method_name}.
464
+ https://opentelemetry.io/docs/reference/specification/trace/semantic_conventions/http/#name
465
+
466
+ Args:
467
+ method: string representing HTTP method
468
+ Returns:
469
+ span name
470
+ """
471
+ method = sanitize_method(method.strip())
472
+ if method == "_OTHER":
473
+ return "HTTP"
474
+ return method
475
+
476
+
477
+ class HTTPXInstrumentor(BaseInstrumentor): # type: ignore
478
+ """An instrumentor for httpx
479
+ See `BaseInstrumentor`
480
+ """
481
+
482
+ def instrumentation_dependencies(self) -> Collection[str]:
483
+ return _instruments
484
+
485
+ def _instrument(self, **kwargs: Any) -> None:
486
+ """Instruments httpx module
487
+
488
+ Args:
489
+ **kwargs: Optional arguments
490
+ ``tracer_provider``: a TracerProvider, defaults to global
491
+ ``request_hook``: An optional callback that is invoked right after a span is created.
492
+ ``response_hook``: An optional callback which is invoked right before the span is finished processing a response.
493
+ ``excluded_urls``: A string containing a comma-delimited list of regexes used to exclude URLs from tracking
494
+ ``duration_histogram_boundaries``: A list of float values representing the explicit bucket boundaries for the duration histogram.
495
+ """
496
+ semconv_opt_in_mode = _OpenTelemetrySemanticConventionStability._get_opentelemetry_stability_opt_in_mode(
497
+ _OpenTelemetryStabilitySignalType.HTTP,
498
+ )
499
+ schema_url = _get_schema_url(semconv_opt_in_mode)
500
+ tracer_provider = kwargs.get("tracer_provider")
501
+ tracer = get_tracer(
502
+ __name__,
503
+ __version__,
504
+ tracer_provider,
505
+ schema_url=schema_url,
506
+ )
507
+ excluded_urls = kwargs.get("excluded_urls")
508
+ meter_provider = kwargs.get("meter_provider")
509
+ duration_histogram_boundaries = kwargs.get("duration_histogram_boundaries")
510
+ meter = get_meter(
511
+ __name__,
512
+ __version__,
513
+ meter_provider,
514
+ schema_url=schema_url,
515
+ )
516
+ duration_histogram_old = None
517
+ if _report_old(semconv_opt_in_mode):
518
+ duration_histogram_old = meter.create_histogram(
519
+ name=MetricInstruments.HTTP_CLIENT_DURATION,
520
+ unit="ms",
521
+ description="measures the duration of the outbound HTTP request",
522
+ explicit_bucket_boundaries_advisory=duration_histogram_boundaries
523
+ or HTTP_DURATION_HISTOGRAM_BUCKETS_OLD,
524
+ )
525
+ duration_histogram_new = None
526
+ if _report_new(semconv_opt_in_mode):
527
+ duration_histogram_new = meter.create_histogram(
528
+ name=HTTP_CLIENT_REQUEST_DURATION,
529
+ unit="s",
530
+ description="Duration of HTTP client requests.",
531
+ explicit_bucket_boundaries_advisory=duration_histogram_boundaries
532
+ or HTTP_DURATION_HISTOGRAM_BUCKETS_NEW,
533
+ )
534
+ _instrument(
535
+ tracer,
536
+ duration_histogram_old,
537
+ duration_histogram_new,
538
+ request_hook=kwargs.get("request_hook"),
539
+ response_hook=kwargs.get("response_hook"),
540
+ excluded_urls=(_excluded_urls_from_env if excluded_urls is None else parse_excluded_urls(excluded_urls)),
541
+ sem_conv_opt_in_mode=semconv_opt_in_mode,
542
+ )
543
+
544
+ def _uninstrument(self, **kwargs: Any) -> None:
545
+ _uninstrument()
@@ -0,0 +1 @@
1
+ __version__ = "0.28.1"
@@ -0,0 +1,78 @@
1
+ from enum import Enum
2
+ from typing import Any
3
+
4
+ from traceloop.sdk import Instruments
5
+
6
+
7
+ class CustomInstruments(Enum):
8
+ AIOHTTP = "aiohttp"
9
+ COHEREAI = "cohere_ai"
10
+ HTTPX = "httpx"
11
+ MISTRALAI = "mistral_ai"
12
+ QDRANTDB = "qdrant_db"
13
+ WEAVIATEDB = "weaviate_db"
14
+ GOOGLE_GENERATIVEAI = "google_genai"
15
+ FASTAPI = "fastapi"
16
+
17
+
18
+ class NetraInstruments(Enum):
19
+ """Custom enum that stores the original enum class in an 'origin' attribute."""
20
+
21
+ def __new__(cls: Any, value: Any, origin: Any = None) -> Any:
22
+ member = object.__new__(cls)
23
+ member._value_ = value
24
+ member.origin = origin
25
+ return member
26
+
27
+
28
+ merged_members = {}
29
+
30
+ for member in Instruments:
31
+ merged_members[member.name] = (member.value, Instruments)
32
+
33
+ for member in CustomInstruments:
34
+ merged_members[member.name] = (member.value, CustomInstruments)
35
+
36
+ InstrumentSet = NetraInstruments("InstrumentSet", merged_members)
37
+
38
+
39
+ #####################################################################################
40
+ """
41
+ NetraInstruments follows the given structure. Refer this for usage within Netra SDK:
42
+
43
+ class InstrumentSet(Enum):
44
+ AIOHTTP = "aiohttp"
45
+ ALEPHALPHA = "alephalpha"
46
+ ANTHROPIC = "anthropic"
47
+ BEDROCK = "bedrock"
48
+ CHROMA = "chroma"
49
+ COHEREAI = "cohere_ai"
50
+ CREW = "crew"
51
+ FASTAPI = "fastapi"
52
+ GOOGLE_GENERATIVEAI = "google_genai"
53
+ GROQ = "groq"
54
+ HAYSTACK = "haystack"
55
+ HTTPX = "httpx"
56
+ LANCEDB = "lancedb"
57
+ LANGCHAIN = "langchain"
58
+ LLAMA_INDEX = "llama_index"
59
+ MARQO = "marqo"
60
+ MCP = "mcp"
61
+ MILVUS = "milvus"
62
+ MISTRALAI = "mistral_ai"
63
+ OLLAMA = "ollama"
64
+ OPENAI = "openai"
65
+ PINECONE = "pinecone"
66
+ PYMYSQL = "pymysql"
67
+ QDRANTDB = "qdrant_db"
68
+ REDIS = "redis"
69
+ REPLICATE = "replicate"
70
+ REQUESTS = "requests"
71
+ SAGEMAKER = "sagemaker"
72
+ TOGETHER = "together"
73
+ TRANSFORMERS = "transformers"
74
+ URLLIB3 = "urllib3"
75
+ VERTEXAI = "vertexai"
76
+ WATSONX = "watsonx"
77
+ WEAVIATEDB = "weaviate_db"
78
+ """