traccia 0.1.2__py3-none-any.whl → 0.1.5__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.
- traccia/__init__.py +73 -0
- traccia/auto.py +736 -0
- traccia/auto_instrumentation.py +74 -0
- traccia/cli.py +349 -0
- traccia/config.py +693 -0
- traccia/context/__init__.py +33 -0
- traccia/context/context.py +67 -0
- traccia/context/propagators.py +283 -0
- traccia/errors.py +48 -0
- traccia/exporter/__init__.py +8 -0
- traccia/exporter/console_exporter.py +31 -0
- traccia/exporter/file_exporter.py +178 -0
- traccia/exporter/http_exporter.py +214 -0
- traccia/exporter/otlp_exporter.py +190 -0
- traccia/instrumentation/__init__.py +20 -0
- traccia/instrumentation/anthropic.py +92 -0
- traccia/instrumentation/decorator.py +263 -0
- traccia/instrumentation/fastapi.py +38 -0
- traccia/instrumentation/http_client.py +21 -0
- traccia/instrumentation/http_server.py +25 -0
- traccia/instrumentation/openai.py +178 -0
- traccia/instrumentation/requests.py +68 -0
- traccia/integrations/__init__.py +22 -0
- traccia/integrations/langchain/__init__.py +14 -0
- traccia/integrations/langchain/callback.py +418 -0
- traccia/integrations/langchain/utils.py +129 -0
- traccia/pricing_config.py +58 -0
- traccia/processors/__init__.py +35 -0
- traccia/processors/agent_enricher.py +159 -0
- traccia/processors/batch_processor.py +140 -0
- traccia/processors/cost_engine.py +71 -0
- traccia/processors/cost_processor.py +70 -0
- traccia/processors/drop_policy.py +44 -0
- traccia/processors/logging_processor.py +31 -0
- traccia/processors/rate_limiter.py +223 -0
- traccia/processors/sampler.py +22 -0
- traccia/processors/token_counter.py +216 -0
- traccia/runtime_config.py +106 -0
- traccia/tracer/__init__.py +15 -0
- traccia/tracer/otel_adapter.py +577 -0
- traccia/tracer/otel_utils.py +24 -0
- traccia/tracer/provider.py +155 -0
- traccia/tracer/span.py +286 -0
- traccia/tracer/span_context.py +16 -0
- traccia/tracer/tracer.py +243 -0
- traccia/utils/__init__.py +19 -0
- traccia/utils/helpers.py +95 -0
- {traccia-0.1.2.dist-info → traccia-0.1.5.dist-info}/METADATA +32 -15
- traccia-0.1.5.dist-info/RECORD +53 -0
- traccia-0.1.5.dist-info/top_level.txt +1 -0
- traccia-0.1.2.dist-info/RECORD +0 -6
- traccia-0.1.2.dist-info/top_level.txt +0 -1
- {traccia-0.1.2.dist-info → traccia-0.1.5.dist-info}/WHEEL +0 -0
- {traccia-0.1.2.dist-info → traccia-0.1.5.dist-info}/entry_points.txt +0 -0
- {traccia-0.1.2.dist-info → traccia-0.1.5.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"""Utility functions for Traccia SDK."""
|
|
2
|
+
|
|
3
|
+
from traccia.utils.helpers import (
|
|
4
|
+
get_duration_ns,
|
|
5
|
+
get_parent_span_id,
|
|
6
|
+
format_trace_id,
|
|
7
|
+
format_span_id,
|
|
8
|
+
parse_trace_id,
|
|
9
|
+
parse_span_id,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
__all__ = [
|
|
13
|
+
"get_duration_ns",
|
|
14
|
+
"get_parent_span_id",
|
|
15
|
+
"format_trace_id",
|
|
16
|
+
"format_span_id",
|
|
17
|
+
"parse_trace_id",
|
|
18
|
+
"parse_span_id",
|
|
19
|
+
]
|
traccia/utils/helpers.py
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"""Helper functions for OpenTelemetry compatibility."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Optional
|
|
6
|
+
|
|
7
|
+
from opentelemetry.trace import Span as OTelSpan
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def get_duration_ns(span: OTelSpan) -> Optional[int]:
|
|
11
|
+
"""
|
|
12
|
+
Get span duration in nanoseconds.
|
|
13
|
+
|
|
14
|
+
Args:
|
|
15
|
+
span: OpenTelemetry Span instance
|
|
16
|
+
|
|
17
|
+
Returns:
|
|
18
|
+
Duration in nanoseconds, or None if span hasn't ended
|
|
19
|
+
"""
|
|
20
|
+
if span.end_time is None:
|
|
21
|
+
return None
|
|
22
|
+
return span.end_time - span.start_time
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def get_parent_span_id(span: OTelSpan) -> Optional[int]:
|
|
26
|
+
"""
|
|
27
|
+
Get parent span ID from span context.
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
span: OpenTelemetry Span instance
|
|
31
|
+
|
|
32
|
+
Returns:
|
|
33
|
+
Parent span ID (int64), or None if no parent
|
|
34
|
+
"""
|
|
35
|
+
# OTel doesn't expose parent_span_id directly
|
|
36
|
+
# We need to get it from the span's parent context if available
|
|
37
|
+
# For now, return None - parent relationship is maintained via context
|
|
38
|
+
# This can be enhanced if needed by tracking parent during span creation
|
|
39
|
+
return None
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def format_trace_id(trace_id: int) -> str:
|
|
43
|
+
"""
|
|
44
|
+
Format OTel trace_id (int64) to hex string.
|
|
45
|
+
|
|
46
|
+
Args:
|
|
47
|
+
trace_id: OTel trace_id as int64
|
|
48
|
+
|
|
49
|
+
Returns:
|
|
50
|
+
32-character hex string
|
|
51
|
+
"""
|
|
52
|
+
return format(trace_id, '032x')
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def format_span_id(span_id: int) -> str:
|
|
56
|
+
"""
|
|
57
|
+
Format OTel span_id (int64) to hex string.
|
|
58
|
+
|
|
59
|
+
Args:
|
|
60
|
+
span_id: OTel span_id as int64
|
|
61
|
+
|
|
62
|
+
Returns:
|
|
63
|
+
16-character hex string
|
|
64
|
+
"""
|
|
65
|
+
return format(span_id, '016x')
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def parse_trace_id(hex_string: str) -> int:
|
|
69
|
+
"""
|
|
70
|
+
Parse hex string trace_id to OTel int64.
|
|
71
|
+
|
|
72
|
+
Args:
|
|
73
|
+
hex_string: 32-character hex string
|
|
74
|
+
|
|
75
|
+
Returns:
|
|
76
|
+
OTel trace_id as int64
|
|
77
|
+
"""
|
|
78
|
+
if not hex_string:
|
|
79
|
+
return 0
|
|
80
|
+
return int(hex_string, 16)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def parse_span_id(hex_string: str) -> int:
|
|
84
|
+
"""
|
|
85
|
+
Parse hex string span_id to OTel int64.
|
|
86
|
+
|
|
87
|
+
Args:
|
|
88
|
+
hex_string: 16-character hex string
|
|
89
|
+
|
|
90
|
+
Returns:
|
|
91
|
+
OTel span_id as int64
|
|
92
|
+
"""
|
|
93
|
+
if not hex_string:
|
|
94
|
+
return 0
|
|
95
|
+
return int(hex_string, 16)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: traccia
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.5
|
|
4
4
|
Summary: Production-ready distributed tracing SDK for AI agents and LLM applications
|
|
5
5
|
License: Apache-2.0
|
|
6
6
|
Project-URL: Homepage, https://github.com/traccia-ai/traccia
|
|
@@ -32,6 +32,8 @@ Requires-Dist: opentelemetry-semantic-conventions>=0.40b0
|
|
|
32
32
|
Requires-Dist: tomli>=2.0.0; python_version < "3.11"
|
|
33
33
|
Requires-Dist: toml>=0.10.0
|
|
34
34
|
Requires-Dist: pydantic>=2.0.0
|
|
35
|
+
Provides-Extra: langchain
|
|
36
|
+
Requires-Dist: langchain-core>=0.1.0; extra == "langchain"
|
|
35
37
|
Dynamic: license-file
|
|
36
38
|
|
|
37
39
|
# Traccia
|
|
@@ -101,6 +103,32 @@ def generate_text(prompt: str) -> str:
|
|
|
101
103
|
text = generate_text("Write a haiku about Python")
|
|
102
104
|
```
|
|
103
105
|
|
|
106
|
+
### LangChain
|
|
107
|
+
|
|
108
|
+
Create a callback handler and pass it to `config={"callbacks": [traccia_handler]}`. Install the optional extra: `pip install traccia[langchain]`.
|
|
109
|
+
|
|
110
|
+
```python
|
|
111
|
+
from traccia import init
|
|
112
|
+
from traccia.integrations.langchain import CallbackHandler # or TracciaCallbackHandler
|
|
113
|
+
from langchain_openai import ChatOpenAI
|
|
114
|
+
|
|
115
|
+
init()
|
|
116
|
+
|
|
117
|
+
# Create Traccia handler (no args)
|
|
118
|
+
traccia_handler = CallbackHandler()
|
|
119
|
+
|
|
120
|
+
# Use with any LangChain runnable
|
|
121
|
+
llm = ChatOpenAI(model="gpt-4o-mini")
|
|
122
|
+
result = llm.invoke(
|
|
123
|
+
"Tell me a joke",
|
|
124
|
+
config={"callbacks": [traccia_handler]}
|
|
125
|
+
)
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Spans for LLM/chat model runs are created automatically with the same attributes as direct OpenAI instrumentation (model, prompt, usage, cost).
|
|
129
|
+
|
|
130
|
+
**Note:** `pip install traccia[langchain]` installs traccia plus `langchain-core`; you need this extra to use the callback handler. If you already have `langchain-core` (e.g. from `langchain` or `langchain-openai`), base `pip install traccia` may be enough at runtime, but `traccia[langchain]` is the supported way to get a compatible dependency.
|
|
131
|
+
|
|
104
132
|
---
|
|
105
133
|
|
|
106
134
|
## 📖 Configuration
|
|
@@ -470,18 +498,6 @@ init(debug=True)
|
|
|
470
498
|
- Increase `max_queue_size` if spans are queued
|
|
471
499
|
- Check `traccia doctor` output
|
|
472
500
|
|
|
473
|
-
#### **Import errors after upgrade**
|
|
474
|
-
|
|
475
|
-
If you're migrating from `traccia_sdk`:
|
|
476
|
-
|
|
477
|
-
```python
|
|
478
|
-
# OLD (will raise helpful error)
|
|
479
|
-
from traccia_sdk import init # ❌ ImportError with migration guide
|
|
480
|
-
|
|
481
|
-
# NEW
|
|
482
|
-
from traccia import init # ✅ Correct
|
|
483
|
-
```
|
|
484
|
-
|
|
485
501
|
---
|
|
486
502
|
|
|
487
503
|
## 📚 API Reference
|
|
@@ -537,13 +553,14 @@ Create a span context manager.
|
|
|
537
553
|
|
|
538
554
|
### Decorator
|
|
539
555
|
|
|
540
|
-
#### `@observe(name=None, *, attributes=None, as_type="span", skip_args=None, skip_result=False)`
|
|
556
|
+
#### `@observe(name=None, *, attributes=None, tags=None, as_type="span", skip_args=None, skip_result=False)`
|
|
541
557
|
|
|
542
558
|
Decorate a function to create spans automatically.
|
|
543
559
|
|
|
544
560
|
**Parameters**:
|
|
545
561
|
- `name` (str, optional): Span name (default: function name)
|
|
546
562
|
- `attributes` (dict, optional): Initial attributes
|
|
563
|
+
- `tags` (list[str], optional): User-defined identifiers for the observed method
|
|
547
564
|
- `as_type` (str): Span type (`"span"`, `"llm"`, `"tool"`)
|
|
548
565
|
- `skip_args` (list, optional): Arguments to skip capturing
|
|
549
566
|
- `skip_result` (bool): Skip capturing return value
|
|
@@ -649,7 +666,7 @@ pytest traccia/tests/ --cov=traccia --cov-report=html
|
|
|
649
666
|
|
|
650
667
|
## 📄 License
|
|
651
668
|
|
|
652
|
-
|
|
669
|
+
Apache License 2.0 - see [LICENSE](LICENSE) for full terms and conditions.
|
|
653
670
|
|
|
654
671
|
---
|
|
655
672
|
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
traccia/__init__.py,sha256=O2Hs3GFVcFsmeBlJwJhqPvFH9kB-pAJarEfB9G4xLZU,1998
|
|
2
|
+
traccia/auto.py,sha256=S-T6edev59c3HEgAU9ENQjOtL2duUJdjJzlBk6hGek0,25792
|
|
3
|
+
traccia/auto_instrumentation.py,sha256=e2Gzt2AtGSXbv6BSZpAApAtMcTlEwc08dgZgQMfrREU,2107
|
|
4
|
+
traccia/cli.py,sha256=lQJU-dAxxcWyOew7OCBi2u7RbMXcwOxtLyfzFwlZ4f0,12362
|
|
5
|
+
traccia/config.py,sha256=BCj_N_zkuRlfPMsuTO-LpcZDQdKQjJ6QHxAIWfCg0HI,24527
|
|
6
|
+
traccia/errors.py,sha256=CMIS01M3pnr3oRhtzQkyKYkDgYkJNlGd6D9Zg2AohA0,1158
|
|
7
|
+
traccia/pricing_config.py,sha256=ZTccshJbAySWJw9Rdvpj2SMaHkEio325t8NkfJfNzfY,1732
|
|
8
|
+
traccia/runtime_config.py,sha256=LjeKCPYKkbZiI38ih4OX4XMkW72hA29Or0hso4W63-M,2157
|
|
9
|
+
traccia/context/__init__.py,sha256=_tNDOoVZ3GgbYtw9I3F8YSKuPovQBa0orjtd7CtfI1w,738
|
|
10
|
+
traccia/context/context.py,sha256=hBvsrYV_-2cHCC7jTH5iGKHzxZRGpMH2vc0oTW2cqAY,1967
|
|
11
|
+
traccia/context/propagators.py,sha256=Tq3O-JYEBqkshrrhGYn-j_2V718gfLiFDaVzsDdVmms,8747
|
|
12
|
+
traccia/exporter/__init__.py,sha256=4Gh7X6XoccGpiIErIZGvDPpT8qzl91wwqJzDhc9gi3Q,360
|
|
13
|
+
traccia/exporter/console_exporter.py,sha256=IKR9S_DJbOqB7aRaDHGtl7GlDiV3GLHTh7I9Anmj7Ao,873
|
|
14
|
+
traccia/exporter/file_exporter.py,sha256=4TcHvhCs6yGCfU-HKVtA8oKjnlzlSfGiI0TMTdVvdsc,6922
|
|
15
|
+
traccia/exporter/http_exporter.py,sha256=kLcDn0WoFbSc6pAawj_-MNqOASGMEiFKki-Y3FeieKU,8039
|
|
16
|
+
traccia/exporter/otlp_exporter.py,sha256=sy74xOgKyLofG_S9QHTuQo4HB4LaKnVVWKYv1cHRZx0,7692
|
|
17
|
+
traccia/instrumentation/__init__.py,sha256=Eiq9SCD7jucIQZsaWisHLG1-SFhebscMHRDyAN6Qjqk,736
|
|
18
|
+
traccia/instrumentation/anthropic.py,sha256=R4vL1plLHgt0TXkDwt1Priic9HppIp2Oyt11IJZZ9Ug,3444
|
|
19
|
+
traccia/instrumentation/decorator.py,sha256=BTZvtFpNA2MVuNkoMbbZtgVK_c_su1M3V1OIuBoTEl0,10049
|
|
20
|
+
traccia/instrumentation/fastapi.py,sha256=LpenJ5aIrcTTWZb6_6GsQ_6cXrVMDjdfeyfQeGvDUTs,1271
|
|
21
|
+
traccia/instrumentation/http_client.py,sha256=fBZx2RNcMxH73cmTrDjlQVYxerBUKQnw8OANyfak5HE,586
|
|
22
|
+
traccia/instrumentation/http_server.py,sha256=RTMklczBEam8PE-pPVMUWBo8YtU7_ISa6-G0Zqjbptk,913
|
|
23
|
+
traccia/instrumentation/openai.py,sha256=GmupQ96g7Jb_gJZZoQrF3UygNzqiEjAxGhpeaAp-3pY,7087
|
|
24
|
+
traccia/instrumentation/requests.py,sha256=I7Oc_px9RDtliQ2ktQVymPUc2Zkaz1NdepxWQygMb24,2267
|
|
25
|
+
traccia/integrations/__init__.py,sha256=bbAVvZaqg0FcM9OVchpb_fHRrTQN8lylMiFTsXHa9sM,662
|
|
26
|
+
traccia/integrations/langchain/__init__.py,sha256=98umBkI8DePI4eUJBZtBUgjMsmaUNF2EfMPK2bWH3iM,524
|
|
27
|
+
traccia/integrations/langchain/callback.py,sha256=xwHVMKRa6TduLm2bU4NNuDvK2AySQsmnQWWqA8whYOQ,14771
|
|
28
|
+
traccia/integrations/langchain/utils.py,sha256=TjkEUKprTL2CfkSjVG4jSO0fLk_n3wvTgxv5NN_wHeI,4258
|
|
29
|
+
traccia/processors/__init__.py,sha256=-hwG9SXM6JbGJaIol2KnS3aWwr9P_TVbJ4AZtGTe2zY,1192
|
|
30
|
+
traccia/processors/agent_enricher.py,sha256=Ur1QvqXSCWT9RgZQw6s53P6URfGmH0KsC7WRJlCYRew,6434
|
|
31
|
+
traccia/processors/batch_processor.py,sha256=JTZzWQs5jXlIiqI7PqukfrHil3V81ZC4tRsqeGYv_v8,4832
|
|
32
|
+
traccia/processors/cost_engine.py,sha256=nMbGwRqWdsOEyIYGdjsX_Srww8f3rxMMDmdUlLqBZn8,2391
|
|
33
|
+
traccia/processors/cost_processor.py,sha256=pJO4NOhWwEOCfSS5zYAR-5qufBjfLcnINObhzkjgdZw,2469
|
|
34
|
+
traccia/processors/drop_policy.py,sha256=dxRiLt79ox4_7DFVMxt_Y0zOIOEV8AQirl8vq_jaVU0,1164
|
|
35
|
+
traccia/processors/logging_processor.py,sha256=2BzTz7_jGF3uVOWc_B-BM3Ab8nyU3crLOt5pcXshgSg,921
|
|
36
|
+
traccia/processors/rate_limiter.py,sha256=PycOYVyiVA4xFEXewOgqiw-rxzFhXu4b9Zw0RdywXck,7878
|
|
37
|
+
traccia/processors/sampler.py,sha256=_jKSRVlt94Bg317j8rfRtt5sdLuCaoI8v9IkgpaEiVs,548
|
|
38
|
+
traccia/processors/token_counter.py,sha256=o91y9nFVFnfRNKcTywNshcEuh8FzXPVH3WOd3Kzpgbs,7676
|
|
39
|
+
traccia/tracer/__init__.py,sha256=VI-EQcz5NtPWV07BJbqPi-DSL-1f81G3y22ngdLidjA,375
|
|
40
|
+
traccia/tracer/otel_adapter.py,sha256=X-1DEeyeHnCJNNqGOldLEpHosz-rjs3jsg49AVTOskw,21006
|
|
41
|
+
traccia/tracer/otel_utils.py,sha256=94HZV1GgeC07w7qWhK3Vu5uzAqiL3LV8yZHOsd5CACM,807
|
|
42
|
+
traccia/tracer/provider.py,sha256=MlQUt_sk0hHEyKBVmv-g9XG9GIEWnwvtGoFBsQcTmxA,5180
|
|
43
|
+
traccia/tracer/span.py,sha256=6SFZDa9HM0SIAznpdIoC9ym_naSPCkipQgthsfSJYLU,9446
|
|
44
|
+
traccia/tracer/span_context.py,sha256=Y6J5Rr6bu-WG2-K2tyncLyyjdAK74b3fbSpIkLOQorg,356
|
|
45
|
+
traccia/tracer/tracer.py,sha256=oxXJnkR95-UnQeVhdtOOW7q0iAqWf_M9YmvCEcvRhkg,9496
|
|
46
|
+
traccia/utils/__init__.py,sha256=JelSlN-M6Sv8y_MLpYAz_kBUguBnxFSuzvhg4eFIdpg,357
|
|
47
|
+
traccia/utils/helpers.py,sha256=yhihp2Jw2TLTPxffGee5nE8nRcZ5C2aWgyLHKZek3Cc,2107
|
|
48
|
+
traccia-0.1.5.dist-info/licenses/LICENSE,sha256=HNl57LOj88EfKh-IWmeqWxsDRh_FF6lj0l-E2A4Hr8w,10757
|
|
49
|
+
traccia-0.1.5.dist-info/METADATA,sha256=ginDaCSUr7lpnmd2FVuGuTFYSURcVuMrCGee2CNpOhc,19011
|
|
50
|
+
traccia-0.1.5.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
51
|
+
traccia-0.1.5.dist-info/entry_points.txt,sha256=SG7gacPRmFzLw2HYTblUZsmC_TO3n14-dNi28SL-C2k,45
|
|
52
|
+
traccia-0.1.5.dist-info/top_level.txt,sha256=Kc56JudupqSkzJPOnuQ6mPHJmhtike7pssNX0u_p59w,8
|
|
53
|
+
traccia-0.1.5.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
traccia
|
traccia-0.1.2.dist-info/RECORD
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
traccia-0.1.2.dist-info/licenses/LICENSE,sha256=HNl57LOj88EfKh-IWmeqWxsDRh_FF6lj0l-E2A4Hr8w,10757
|
|
2
|
-
traccia-0.1.2.dist-info/METADATA,sha256=LNuwcEuYE5OCjPFHV-VvLzoND4KR5_BNYbBuDD6jI_k,17986
|
|
3
|
-
traccia-0.1.2.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
4
|
-
traccia-0.1.2.dist-info/entry_points.txt,sha256=SG7gacPRmFzLw2HYTblUZsmC_TO3n14-dNi28SL-C2k,45
|
|
5
|
-
traccia-0.1.2.dist-info/top_level.txt,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
6
|
-
traccia-0.1.2.dist-info/RECORD,,
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
|
|
File without changes
|
|
File without changes
|
|
File without changes
|