spanwire 0.1.0__tar.gz

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.
spanwire-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Hamidreza Moghaddam Kohi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,226 @@
1
+ Metadata-Version: 2.4
2
+ Name: spanwire
3
+ Version: 0.1.0
4
+ Summary: Zero-dependency micro-tracing, distributed context propagation & breadcrumb telemetry engine for Python.
5
+ Author-email: Hamidreza <h4midrezam@gmail.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/mrhamidrezam/spanwire
8
+ Project-URL: Repository, https://github.com/mrhamidrezam/spanwire
9
+ Project-URL: Issues, https://github.com/mrhamidrezam/spanwire/issues
10
+ Keywords: tracing,distributed-tracing,opentelemetry,w3c,traceparent,baggage,breadcrumbs,telemetry,contextvars,zero-dependency,async
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Programming Language :: Python :: 3.14
19
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
20
+ Classifier: Topic :: System :: Monitoring
21
+ Classifier: Topic :: System :: Logging
22
+ Classifier: Typing :: Typed
23
+ Requires-Python: >=3.10
24
+ Description-Content-Type: text/markdown
25
+ License-File: LICENSE
26
+ Dynamic: license-file
27
+
28
+ <div align="center">
29
+
30
+ # ⚡ spanwire
31
+
32
+ **Zero-dependency micro-tracing, distributed context propagation & breadcrumb telemetry engine for Python.**
33
+
34
+ [![PyPI Version](https://img.shields.io/pypi/v/spanwire.svg?color=blue)](https://pypi.org/project/spanwire/)
35
+ [![Python Versions](https://img.shields.io/pypi/pyversions/spanwire.svg)](https://pypi.org/project/spanwire/)
36
+ [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT)
37
+ [![CI](https://github.com/mrhamidrezam/spanwire/actions/workflows/ci.yml/badge.svg)](https://github.com/mrhamidrezam/spanwire/actions/workflows/ci.yml)
38
+ [![Typing: Typed](https://img.shields.io/badge/typing-typed-purple.svg)](https://peps.python.org/pep-0561/)
39
+ [![Dependencies: Zero](https://img.shields.io/badge/dependencies-0-brightgreen.svg)](#)
40
+
41
+ </div>
42
+
43
+ ---
44
+
45
+ ## 💡 Why spanwire?
46
+
47
+ Standard distributed tracing solutions (like OpenTelemetry SDK) pull in dozens of heavy transitive dependencies, incur noticeable startup delays, and add architectural bloat to lightweight microservices, CLI utilities, serverless functions (AWS Lambda, Cloud Run), and async LLM pipelines.
48
+
49
+ **spanwire** delivers enterprise-grade distributed telemetry and error context trails with **zero external dependencies**, utilizing pure Python standard library primitives (`contextvars`, `dataclasses`, `time`, `secrets`).
50
+
51
+ - **100% W3C Trace Context & Baggage Standard**: Interoperable with Datadog, Jaeger, Grafana Tempo, AWS X-Ray, and OpenTelemetry collectors.
52
+ - **Flawless Context Propagation**: Works out of the box across `asyncio` coroutines, background tasks, and OS threads without context leakage.
53
+ - **In-Memory Breadcrumb Trail**: Maintains an efficient circular ring-buffer of recent operational milestones, automatically attached when errors or exceptions occur.
54
+ - **Multiple Exporters**: ANSI-colorized CLI console, NDJSON/JSONLines for log aggregators (Vector, Fluentd, Promtail), or in-memory collectors for unit testing.
55
+ - **Deterministic Sampling**: Ratio-based trace hashing guarantees synchronized sampling decisions across distributed microservice boundaries.
56
+
57
+ ---
58
+
59
+ ## 📐 Architecture & Flow
60
+
61
+ ```mermaid
62
+ sequenceDiagram
63
+ autonumber
64
+ participant Client as API Gateway (Service A)
65
+ participant Wire as W3C HTTP Headers
66
+ participant Worker as Downstream Worker (Service B)
67
+ participant Exporter as Telemetry Exporter
68
+
69
+ Client->>Client: Start Span ("checkout.process")
70
+ Client->>Client: Record Breadcrumb ("User tier: VIP")
71
+ Client->>Wire: Inject W3C traceparent & baggage headers
72
+ Wire->>Worker: Forward HTTP Request
73
+ Worker->>Worker: Extract W3C Context (inherits trace_id)
74
+ Worker->>Worker: Execute child span ("db.persist_order")
75
+ Worker-->>Exporter: Export child span ([OK] 12.4ms)
76
+ Client-->>Exporter: Export parent span ([OK] 45.1ms)
77
+ ```
78
+
79
+ ---
80
+
81
+ ## 🚀 Installation
82
+
83
+ ```bash
84
+ pip install spanwire
85
+ ```
86
+
87
+ *Requires Python 3.10 or higher. No third-party dependencies required.*
88
+
89
+ ---
90
+
91
+ ## ⚡ Quick Start
92
+
93
+ ### 1. Basic Spans and Console Export
94
+
95
+ ```python
96
+ import time
97
+ from spanwire import Tracer, ConsoleExporter
98
+
99
+ tracer = Tracer(
100
+ service_name="payment-service",
101
+ exporter=ConsoleExporter(colored=True)
102
+ )
103
+
104
+ tracer.add_breadcrumb("Validating customer cart", category="cart")
105
+
106
+ with tracer.span("process_payment", attributes={"order.id": "ord_1042", "amount": 89.00}) as span:
107
+ time.sleep(0.02)
108
+
109
+ # Nested child span
110
+ with tracer.span("stripe.charge") as child:
111
+ time.sleep(0.03)
112
+ child.set_attribute("charge.id", "ch_abc123")
113
+ tracer.add_breadcrumb("Payment captured via webhook", category="billing")
114
+ ```
115
+
116
+ Console Output:
117
+ ```text
118
+ ⚡ [OK] stripe.charge (30.12ms) [trace=63d3791c.. span=ff0dba3fa8e11f3c parent=97bc44600e80142d]
119
+ ↳ attributes: service.name='payment-service', charge.id='ch_abc123'
120
+ ↳ breadcrumbs (2):
121
+ - [INFO] cart: Validating customer cart
122
+ - [INFO] billing: Payment captured via webhook
123
+ ⚡ [OK] process_payment (50.84ms) [trace=63d3791c.. span=97bc44600e80142d]
124
+ ↳ attributes: service.name='payment-service', order.id='ord_1042', amount=89.0
125
+ ```
126
+
127
+ ---
128
+
129
+ ### 2. Distributed Tracing over HTTP (W3C Traceparent & Baggage)
130
+
131
+ ```python
132
+ import requests
133
+ from spanwire import Tracer, set_baggage_item
134
+
135
+ tracer = Tracer(service_name="gateway")
136
+
137
+ # Set user context in baggage
138
+ set_baggage_item("user_id", "u_8841")
139
+
140
+ with tracer.span("http_outgoing_call") as span:
141
+ # 1. Inject W3C headers into outbound HTTP request
142
+ headers = {}
143
+ tracer.inject_headers(headers)
144
+ # headers contains:
145
+ # 'traceparent': '00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01'
146
+ # 'baggage': 'user_id=u_8841'
147
+
148
+ # requests.get("https://worker.internal/api/tasks", headers=headers)
149
+ ```
150
+
151
+ On the receiving downstream service:
152
+
153
+ ```python
154
+ from spanwire import Tracer
155
+
156
+ worker_tracer = Tracer(service_name="worker")
157
+
158
+ def handle_incoming_request(incoming_headers: dict):
159
+ # Extract parent context & baggage from headers
160
+ parent_ctx, baggage, _ = worker_tracer.extract_headers(incoming_headers)
161
+
162
+ # Continue the distributed trace seamlessly
163
+ with worker_tracer.span("worker.handle_job", parent_context=parent_ctx) as span:
164
+ print(f"Propagated trace_id: {span.context.trace_id}")
165
+ print(f"Parent span_id: {span.parent_span_id}")
166
+ print(f"User ID from baggage: {baggage.get('user_id')}")
167
+ ```
168
+
169
+ ---
170
+
171
+ ### 3. Asynchronous Function Decoration & LLM Agent Pipeline
172
+
173
+ ```python
174
+ import asyncio
175
+ from spanwire import Tracer, ConsoleExporter
176
+
177
+ tracer = Tracer(service_name="llm-orchestrator", exporter=ConsoleExporter())
178
+
179
+ @tracer.trace(name="llm.generate_plan")
180
+ async def generate_plan(prompt: str) -> list[str]:
181
+ tracer.add_breadcrumb(f"Generating plan for: {prompt[:30]}", category="llm")
182
+ await asyncio.sleep(0.05)
183
+ return ["search_db", "render_markdown"]
184
+
185
+ async def main():
186
+ with tracer.span("orchestrate_query"):
187
+ plan = await generate_plan("Summarize latest server telemetry")
188
+
189
+ asyncio.run(main())
190
+ ```
191
+
192
+ ---
193
+
194
+ ## 🛠️ Exporters
195
+
196
+ | Exporter | Description | Best Suited For |
197
+ |---|---|---|
198
+ | `ConsoleExporter` | Formatted CLI output with ANSI colors, durations, and breadcrumb trails | Development, debugging, CLI tools |
199
+ | `JsonLinesExporter` | Newline-delimited JSON (NDJSON) output to file or stdout | Vector, Promtail, Datadog Agent, CloudWatch |
200
+ | `InMemoryExporter` | Stores finished spans in a thread-safe list | Pytest unit assertions, custom telemetry queues |
201
+ | `CallbackExporter` | Invokes custom callback function on each completed span | Custom event emission, Webhooks |
202
+
203
+ ---
204
+
205
+ ## 🎯 Samplers
206
+
207
+ - **`AlwaysOnSampler()`**: Traces 100% of operations (default).
208
+ - **`AlwaysOffSampler()`**: Disables tracing overhead completely.
209
+ - **`RatioSampler(ratio=0.1)`**: Probabilistically samples `10%` of traces using deterministic hashing on `trace_id`.
210
+ - **`ParentBasedSampler(root=...)`**: Respects the upstream service's sampling flag, with fallback to root sampler.
211
+
212
+ ---
213
+
214
+ ## 🧪 Running Unit Tests
215
+
216
+ ```bash
217
+ python -m pytest tests -v
218
+ ```
219
+
220
+ All 33 unit tests execute in ~0.15s with zero external test plugins.
221
+
222
+ ---
223
+
224
+ ## 📜 License
225
+
226
+ MIT License © 2026 Hamidreza Moghaddam Kohi. See [LICENSE](LICENSE) for details.
@@ -0,0 +1,199 @@
1
+ <div align="center">
2
+
3
+ # ⚡ spanwire
4
+
5
+ **Zero-dependency micro-tracing, distributed context propagation & breadcrumb telemetry engine for Python.**
6
+
7
+ [![PyPI Version](https://img.shields.io/pypi/v/spanwire.svg?color=blue)](https://pypi.org/project/spanwire/)
8
+ [![Python Versions](https://img.shields.io/pypi/pyversions/spanwire.svg)](https://pypi.org/project/spanwire/)
9
+ [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT)
10
+ [![CI](https://github.com/mrhamidrezam/spanwire/actions/workflows/ci.yml/badge.svg)](https://github.com/mrhamidrezam/spanwire/actions/workflows/ci.yml)
11
+ [![Typing: Typed](https://img.shields.io/badge/typing-typed-purple.svg)](https://peps.python.org/pep-0561/)
12
+ [![Dependencies: Zero](https://img.shields.io/badge/dependencies-0-brightgreen.svg)](#)
13
+
14
+ </div>
15
+
16
+ ---
17
+
18
+ ## 💡 Why spanwire?
19
+
20
+ Standard distributed tracing solutions (like OpenTelemetry SDK) pull in dozens of heavy transitive dependencies, incur noticeable startup delays, and add architectural bloat to lightweight microservices, CLI utilities, serverless functions (AWS Lambda, Cloud Run), and async LLM pipelines.
21
+
22
+ **spanwire** delivers enterprise-grade distributed telemetry and error context trails with **zero external dependencies**, utilizing pure Python standard library primitives (`contextvars`, `dataclasses`, `time`, `secrets`).
23
+
24
+ - **100% W3C Trace Context & Baggage Standard**: Interoperable with Datadog, Jaeger, Grafana Tempo, AWS X-Ray, and OpenTelemetry collectors.
25
+ - **Flawless Context Propagation**: Works out of the box across `asyncio` coroutines, background tasks, and OS threads without context leakage.
26
+ - **In-Memory Breadcrumb Trail**: Maintains an efficient circular ring-buffer of recent operational milestones, automatically attached when errors or exceptions occur.
27
+ - **Multiple Exporters**: ANSI-colorized CLI console, NDJSON/JSONLines for log aggregators (Vector, Fluentd, Promtail), or in-memory collectors for unit testing.
28
+ - **Deterministic Sampling**: Ratio-based trace hashing guarantees synchronized sampling decisions across distributed microservice boundaries.
29
+
30
+ ---
31
+
32
+ ## 📐 Architecture & Flow
33
+
34
+ ```mermaid
35
+ sequenceDiagram
36
+ autonumber
37
+ participant Client as API Gateway (Service A)
38
+ participant Wire as W3C HTTP Headers
39
+ participant Worker as Downstream Worker (Service B)
40
+ participant Exporter as Telemetry Exporter
41
+
42
+ Client->>Client: Start Span ("checkout.process")
43
+ Client->>Client: Record Breadcrumb ("User tier: VIP")
44
+ Client->>Wire: Inject W3C traceparent & baggage headers
45
+ Wire->>Worker: Forward HTTP Request
46
+ Worker->>Worker: Extract W3C Context (inherits trace_id)
47
+ Worker->>Worker: Execute child span ("db.persist_order")
48
+ Worker-->>Exporter: Export child span ([OK] 12.4ms)
49
+ Client-->>Exporter: Export parent span ([OK] 45.1ms)
50
+ ```
51
+
52
+ ---
53
+
54
+ ## 🚀 Installation
55
+
56
+ ```bash
57
+ pip install spanwire
58
+ ```
59
+
60
+ *Requires Python 3.10 or higher. No third-party dependencies required.*
61
+
62
+ ---
63
+
64
+ ## ⚡ Quick Start
65
+
66
+ ### 1. Basic Spans and Console Export
67
+
68
+ ```python
69
+ import time
70
+ from spanwire import Tracer, ConsoleExporter
71
+
72
+ tracer = Tracer(
73
+ service_name="payment-service",
74
+ exporter=ConsoleExporter(colored=True)
75
+ )
76
+
77
+ tracer.add_breadcrumb("Validating customer cart", category="cart")
78
+
79
+ with tracer.span("process_payment", attributes={"order.id": "ord_1042", "amount": 89.00}) as span:
80
+ time.sleep(0.02)
81
+
82
+ # Nested child span
83
+ with tracer.span("stripe.charge") as child:
84
+ time.sleep(0.03)
85
+ child.set_attribute("charge.id", "ch_abc123")
86
+ tracer.add_breadcrumb("Payment captured via webhook", category="billing")
87
+ ```
88
+
89
+ Console Output:
90
+ ```text
91
+ ⚡ [OK] stripe.charge (30.12ms) [trace=63d3791c.. span=ff0dba3fa8e11f3c parent=97bc44600e80142d]
92
+ ↳ attributes: service.name='payment-service', charge.id='ch_abc123'
93
+ ↳ breadcrumbs (2):
94
+ - [INFO] cart: Validating customer cart
95
+ - [INFO] billing: Payment captured via webhook
96
+ ⚡ [OK] process_payment (50.84ms) [trace=63d3791c.. span=97bc44600e80142d]
97
+ ↳ attributes: service.name='payment-service', order.id='ord_1042', amount=89.0
98
+ ```
99
+
100
+ ---
101
+
102
+ ### 2. Distributed Tracing over HTTP (W3C Traceparent & Baggage)
103
+
104
+ ```python
105
+ import requests
106
+ from spanwire import Tracer, set_baggage_item
107
+
108
+ tracer = Tracer(service_name="gateway")
109
+
110
+ # Set user context in baggage
111
+ set_baggage_item("user_id", "u_8841")
112
+
113
+ with tracer.span("http_outgoing_call") as span:
114
+ # 1. Inject W3C headers into outbound HTTP request
115
+ headers = {}
116
+ tracer.inject_headers(headers)
117
+ # headers contains:
118
+ # 'traceparent': '00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01'
119
+ # 'baggage': 'user_id=u_8841'
120
+
121
+ # requests.get("https://worker.internal/api/tasks", headers=headers)
122
+ ```
123
+
124
+ On the receiving downstream service:
125
+
126
+ ```python
127
+ from spanwire import Tracer
128
+
129
+ worker_tracer = Tracer(service_name="worker")
130
+
131
+ def handle_incoming_request(incoming_headers: dict):
132
+ # Extract parent context & baggage from headers
133
+ parent_ctx, baggage, _ = worker_tracer.extract_headers(incoming_headers)
134
+
135
+ # Continue the distributed trace seamlessly
136
+ with worker_tracer.span("worker.handle_job", parent_context=parent_ctx) as span:
137
+ print(f"Propagated trace_id: {span.context.trace_id}")
138
+ print(f"Parent span_id: {span.parent_span_id}")
139
+ print(f"User ID from baggage: {baggage.get('user_id')}")
140
+ ```
141
+
142
+ ---
143
+
144
+ ### 3. Asynchronous Function Decoration & LLM Agent Pipeline
145
+
146
+ ```python
147
+ import asyncio
148
+ from spanwire import Tracer, ConsoleExporter
149
+
150
+ tracer = Tracer(service_name="llm-orchestrator", exporter=ConsoleExporter())
151
+
152
+ @tracer.trace(name="llm.generate_plan")
153
+ async def generate_plan(prompt: str) -> list[str]:
154
+ tracer.add_breadcrumb(f"Generating plan for: {prompt[:30]}", category="llm")
155
+ await asyncio.sleep(0.05)
156
+ return ["search_db", "render_markdown"]
157
+
158
+ async def main():
159
+ with tracer.span("orchestrate_query"):
160
+ plan = await generate_plan("Summarize latest server telemetry")
161
+
162
+ asyncio.run(main())
163
+ ```
164
+
165
+ ---
166
+
167
+ ## 🛠️ Exporters
168
+
169
+ | Exporter | Description | Best Suited For |
170
+ |---|---|---|
171
+ | `ConsoleExporter` | Formatted CLI output with ANSI colors, durations, and breadcrumb trails | Development, debugging, CLI tools |
172
+ | `JsonLinesExporter` | Newline-delimited JSON (NDJSON) output to file or stdout | Vector, Promtail, Datadog Agent, CloudWatch |
173
+ | `InMemoryExporter` | Stores finished spans in a thread-safe list | Pytest unit assertions, custom telemetry queues |
174
+ | `CallbackExporter` | Invokes custom callback function on each completed span | Custom event emission, Webhooks |
175
+
176
+ ---
177
+
178
+ ## 🎯 Samplers
179
+
180
+ - **`AlwaysOnSampler()`**: Traces 100% of operations (default).
181
+ - **`AlwaysOffSampler()`**: Disables tracing overhead completely.
182
+ - **`RatioSampler(ratio=0.1)`**: Probabilistically samples `10%` of traces using deterministic hashing on `trace_id`.
183
+ - **`ParentBasedSampler(root=...)`**: Respects the upstream service's sampling flag, with fallback to root sampler.
184
+
185
+ ---
186
+
187
+ ## 🧪 Running Unit Tests
188
+
189
+ ```bash
190
+ python -m pytest tests -v
191
+ ```
192
+
193
+ All 33 unit tests execute in ~0.15s with zero external test plugins.
194
+
195
+ ---
196
+
197
+ ## 📜 License
198
+
199
+ MIT License © 2026 Hamidreza Moghaddam Kohi. See [LICENSE](LICENSE) for details.
@@ -0,0 +1,56 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "spanwire"
7
+ version = "0.1.0"
8
+ description = "Zero-dependency micro-tracing, distributed context propagation & breadcrumb telemetry engine for Python."
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = "MIT"
12
+ authors = [
13
+ { name = "Hamidreza", email = "h4midrezam@gmail.com" }
14
+ ]
15
+ keywords = [
16
+ "tracing",
17
+ "distributed-tracing",
18
+ "opentelemetry",
19
+ "w3c",
20
+ "traceparent",
21
+ "baggage",
22
+ "breadcrumbs",
23
+ "telemetry",
24
+ "contextvars",
25
+ "zero-dependency",
26
+ "async"
27
+ ]
28
+ classifiers = [
29
+ "Development Status :: 4 - Beta",
30
+ "Intended Audience :: Developers",
31
+ "Programming Language :: Python :: 3",
32
+ "Programming Language :: Python :: 3.10",
33
+ "Programming Language :: Python :: 3.11",
34
+ "Programming Language :: Python :: 3.12",
35
+ "Programming Language :: Python :: 3.13",
36
+ "Programming Language :: Python :: 3.14",
37
+ "Topic :: Software Development :: Libraries :: Python Modules",
38
+ "Topic :: System :: Monitoring",
39
+ "Topic :: System :: Logging",
40
+ "Typing :: Typed",
41
+ ]
42
+
43
+ [project.urls]
44
+ Homepage = "https://github.com/mrhamidrezam/spanwire"
45
+ Repository = "https://github.com/mrhamidrezam/spanwire"
46
+ Issues = "https://github.com/mrhamidrezam/spanwire/issues"
47
+
48
+ [tool.setuptools.packages.find]
49
+ where = ["src"]
50
+
51
+ [tool.setuptools.package-data]
52
+ spanwire = ["py.typed"]
53
+
54
+ [tool.pytest.ini_options]
55
+ pythonpath = ["src"]
56
+ testpaths = ["tests"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,145 @@
1
+ """spanwire: Zero-dependency micro-tracing, distributed context propagation & breadcrumb telemetry engine for Python."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any, Callable, Dict, Mapping, Optional
6
+
7
+ from spanwire._version import __version__
8
+ from spanwire.breadcrumbs import Breadcrumb, BreadcrumbBuffer
9
+ from spanwire.context import (
10
+ clear_baggage,
11
+ get_baggage,
12
+ get_baggage_item,
13
+ get_current_span,
14
+ set_baggage,
15
+ set_baggage_item,
16
+ )
17
+ from spanwire.core import (
18
+ Span,
19
+ SpanContext,
20
+ SpanEvent,
21
+ SpanStatus,
22
+ Tracer,
23
+ generate_span_id,
24
+ generate_trace_id,
25
+ )
26
+ from spanwire.exporters import (
27
+ CallbackExporter,
28
+ ConsoleExporter,
29
+ InMemoryExporter,
30
+ JsonLinesExporter,
31
+ SpanExporter,
32
+ )
33
+ from spanwire.sampler import (
34
+ AlwaysOffSampler,
35
+ AlwaysOnSampler,
36
+ ParentBasedSampler,
37
+ RatioSampler,
38
+ Sampler,
39
+ )
40
+ from spanwire.w3c import (
41
+ extract_w3c_headers,
42
+ format_baggage,
43
+ format_traceparent,
44
+ inject_w3c_headers,
45
+ is_valid_span_id,
46
+ is_valid_trace_id,
47
+ parse_baggage,
48
+ parse_traceparent,
49
+ )
50
+
51
+ _DEFAULT_TRACER: Optional[Tracer] = None
52
+
53
+
54
+ def get_tracer(service_name: str = "default-service") -> Tracer:
55
+ """Get or initialize the global default Tracer."""
56
+ global _DEFAULT_TRACER
57
+ if _DEFAULT_TRACER is None:
58
+ _DEFAULT_TRACER = Tracer(service_name=service_name)
59
+ return _DEFAULT_TRACER
60
+
61
+
62
+ def set_tracer(tracer: Tracer) -> None:
63
+ """Set the global default Tracer."""
64
+ global _DEFAULT_TRACER
65
+ _DEFAULT_TRACER = tracer
66
+
67
+
68
+ def span(
69
+ name: str,
70
+ attributes: Optional[Mapping[str, Any]] = None,
71
+ parent_context: Optional[SpanContext] = None,
72
+ ) -> Span:
73
+ """Create a span on the default global tracer."""
74
+ return get_tracer().span(name, attributes=attributes, parent_context=parent_context)
75
+
76
+
77
+ def trace(
78
+ name: Optional[str] = None,
79
+ attributes: Optional[Mapping[str, Any]] = None,
80
+ ) -> Callable[..., Any]:
81
+ """Decorator to trace a function using the default global tracer."""
82
+ return get_tracer().trace(name=name, attributes=attributes)
83
+
84
+
85
+ def add_breadcrumb(
86
+ message: str,
87
+ level: str = "INFO",
88
+ category: str = "default",
89
+ data: Optional[Dict[str, Any]] = None,
90
+ **kwargs: Any,
91
+ ) -> Breadcrumb:
92
+ """Add a breadcrumb to the default global tracer."""
93
+ return get_tracer().add_breadcrumb(
94
+ message=message, level=level, category=category, data=data, **kwargs
95
+ )
96
+
97
+
98
+ __all__ = [
99
+ "__version__",
100
+ # Core
101
+ "Tracer",
102
+ "Span",
103
+ "SpanContext",
104
+ "SpanEvent",
105
+ "SpanStatus",
106
+ "generate_trace_id",
107
+ "generate_span_id",
108
+ # Global conveniences
109
+ "get_tracer",
110
+ "set_tracer",
111
+ "span",
112
+ "trace",
113
+ "add_breadcrumb",
114
+ # Context
115
+ "get_current_span",
116
+ "get_baggage",
117
+ "set_baggage",
118
+ "set_baggage_item",
119
+ "get_baggage_item",
120
+ "clear_baggage",
121
+ # Breadcrumbs
122
+ "Breadcrumb",
123
+ "BreadcrumbBuffer",
124
+ # Samplers
125
+ "Sampler",
126
+ "AlwaysOnSampler",
127
+ "AlwaysOffSampler",
128
+ "RatioSampler",
129
+ "ParentBasedSampler",
130
+ # Exporters
131
+ "SpanExporter",
132
+ "InMemoryExporter",
133
+ "JsonLinesExporter",
134
+ "ConsoleExporter",
135
+ "CallbackExporter",
136
+ # W3C
137
+ "format_traceparent",
138
+ "parse_traceparent",
139
+ "format_baggage",
140
+ "parse_baggage",
141
+ "inject_w3c_headers",
142
+ "extract_w3c_headers",
143
+ "is_valid_trace_id",
144
+ "is_valid_span_id",
145
+ ]
@@ -0,0 +1 @@
1
+ __version__ = "0.1.0"