44[ ![ PyPI version] ( https://img.shields.io/pypi/v/botanu )] ( https://pypi.org/project/botanu/ )
55[ ![ Python] ( https://img.shields.io/badge/python-3.9%20|%203.10%20|%203.11%20|%203.12%20|%203.13-blue )] ( https://www.python.org/ )
66[ ![ License] ( https://img.shields.io/badge/License-Apache%202.0-blue.svg )] ( LICENSE )
7+ [ ![ LF AI & Data] ( https://img.shields.io/badge/LF%20AI%20%26%20Data-member-blue )] ( https://lfaidata.foundation/ )
78
8- OpenTelemetry-native run- level cost attribution for AI workflows.
9+ ** Run- level cost attribution for AI workflows, built on OpenTelemetry. **
910
10- ## Overview
11+ Botanu adds ** runs ** on top of distributed tracing. A run represents one business transaction that may span multiple LLM calls, database queries, and microservices. By correlating every operation to a stable ` run_id ` , you get per-transaction cost attribution without sampling artifacts.
1112
12- Botanu adds ** runs** on top of distributed tracing. A run represents a single business transaction that may span multiple LLM calls, database queries, and services. By correlating all operations to a stable ` run_id ` , you get accurate cost attribution without sampling artifacts.
13+ ## How It Works
14+
15+ ```
16+ User Request
17+ |
18+ v
19+ Entry Service Intermediate Service LLM / DB
20+ @botanu_use_case --> enable() propagates --> auto-instrumented
21+ creates run_id run_id via W3C Baggage spans tagged with run_id
22+ ```
23+
24+ 1 . ** Entry point** creates a ` run_id ` with ` @botanu_use_case `
25+ 2 . ** Every service** calls ` enable() ` to propagate the ` run_id ` via W3C Baggage
26+ 3 . ** All spans** across all services share the same ` run_id `
27+ 4 . ** Traces export** to your OTel Collector via OTLP (configured by environment variable)
1328
1429## Quick Start
1530
31+ ### Install
32+
33+ ``` bash
34+ pip install botanu
35+ ```
36+
37+ One install. Includes OTel SDK, OTLP exporter, and auto-instrumentation for 50+ libraries.
38+
39+ ### Instrument Your Code
40+
41+ ** Entry service** (where the workflow begins):
42+
1643``` python
1744from botanu import enable, botanu_use_case
1845
19- enable(service_name = " my-service " )
46+ enable() # reads config from env vars
2047
21- @botanu_use_case (name = " my_workflow " )
22- def my_function ( ):
23- data = db.query(... )
24- result = llm.complete(... )
48+ @botanu_use_case (name = " Customer Support " )
49+ async def handle_ticket ( ticket_id : str ):
50+ data = await db.query(ticket_id )
51+ result = await llm.complete(data )
2552 return result
2653```
2754
28- ## Installation
55+ ** Every other service ** (intermediate, downstream):
2956
30- ``` bash
31- pip install " botanu[all]"
57+ ``` python
58+ from botanu import enable
59+
60+ enable() # propagates run_id from incoming request
3261```
3362
34- | Extra | Description |
35- | -------| -------------|
36- | ` sdk ` | OpenTelemetry SDK + OTLP exporter |
37- | ` instruments ` | Auto-instrumentation for HTTP, databases |
38- | ` genai ` | Auto-instrumentation for LLM providers |
39- | ` all ` | All of the above (recommended) |
63+ That's it. No collector endpoint in code. No manual span creation.
4064
41- ## What Gets Auto-Instrumented
65+ ### Configure via Environment Variables
4266
43- When you install ` botanu[all] ` , the following are automatically tracked:
67+ All configuration is via environment variables. ** Zero hardcoded values in code. **
4468
45- - ** LLM Providers ** — OpenAI, Anthropic, Vertex AI, Bedrock, Azure OpenAI
46- - ** Databases ** — PostgreSQL, MySQL, SQLite, MongoDB, Redis
47- - ** HTTP ** — requests, httpx, urllib3, aiohttp
48- - ** Frameworks ** — FastAPI, Flask, Django, Starlette
49- - ** Messaging ** — Celery, Kafka
69+ | Variable | Description | Default |
70+ | ---------- | ------------- | --------- |
71+ | ` OTEL_EXPORTER_OTLP_ENDPOINT ` | Collector endpoint | ` http://localhost:4318 ` |
72+ | ` OTEL_SERVICE_NAME ` | Service name | ` unknown_service ` |
73+ | ` BOTANU_ENVIRONMENT ` | Deployment environment | ` production ` |
5074
51- No manual instrumentation required.
75+ ``` yaml
76+ # docker-compose.yml / Kubernetes deployment
77+ environment :
78+ - OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4318
79+ - OTEL_SERVICE_NAME=my-service
80+ ` ` `
5281
53- ## Kubernetes Deployment
82+ See [Configuration Reference](./docs/getting-started/configuration.md) for all options.
5483
55- For large-scale deployments (2000+ services):
84+ ## Auto-Instrumentation
5685
57- | Service Type | Code Change | Kubernetes Config |
58- | --------------| -------------| -------------------|
59- | Entry point | ` @botanu_use_case ` decorator | Annotation |
60- | Intermediate | None | Annotation only |
86+ Everything is included and auto-detected. If the library is in your dependencies, it gets instrumented:
6187
62- ``` yaml
63- # Intermediate services - annotation only, no code changes
64- metadata :
65- annotations :
66- instrumentation.opentelemetry.io/inject-python : " true"
67- ` ` `
88+ | Category | Libraries |
89+ |----------|-----------|
90+ | **LLM Providers** | OpenAI, Anthropic, Vertex AI, Google GenAI, LangChain, Ollama, CrewAI |
91+ | **Web Frameworks** | FastAPI, Flask, Django, Starlette, Falcon, Pyramid, Tornado |
92+ | **HTTP Clients** | requests, httpx, urllib3, aiohttp |
93+ | **Databases** | PostgreSQL (psycopg2/3, asyncpg), MySQL, SQLite, MongoDB, Redis, SQLAlchemy, Elasticsearch, Cassandra |
94+ | **Messaging** | Celery, Kafka, RabbitMQ (pika) |
95+ | **AWS** | botocore, boto3 (SQS) |
96+ | **gRPC** | Client + Server |
97+ | **Runtime** | logging, threading, asyncio |
98+
99+ No manual instrumentation required. Libraries not installed are silently skipped.
100+
101+ ## Kubernetes at Scale
102+
103+ For large deployments (2000+ services), only entry points need code changes:
68104
69- Auto-instrumentation captures all HTTP calls including retries (requests, httpx, aiohttp, urllib3).
105+ | Service Type | Code Change | Configuration |
106+ |--------------|-------------|---------------|
107+ | Entry point | ` @botanu_use_case` decorator | `OTEL_EXPORTER_OTLP_ENDPOINT` env var |
108+ | Intermediate | `enable()` call only | `OTEL_EXPORTER_OTLP_ENDPOINT` env var |
70109
71110See [Kubernetes Deployment Guide](./docs/integration/kubernetes.md) for details.
72111
112+ # # Architecture
113+
114+ ```
115+ +---------+ +---------+ +---------+
116+ | Service | --> | Service | --> | Service |
117+ | enable()| --> | enable()| --> | enable()|
118+ +---------+ +---------+ +---------+
119+ | | |
120+ v v v
121+ +-------------------------------------+
122+ | OTel Collector (OTLP) |
123+ +-------------------------------------+
124+ | | |
125+ v v v
126+ Jaeger/Tempo Prometheus Your Backend
127+ ```
128+
129+ The SDK is a thin layer on OpenTelemetry:
130+ - **SDK**: Generates `run_id`, propagates context, auto-instruments
131+ - **Collector**: PII redaction, cardinality limits, routing, vendor enrichment
132+
73133## Documentation
74134
75- - [Getting Started](./docs/getting-started/)
76- - [Concepts](./docs/concepts/)
77- - [Integration](./docs/integration/)
78- - [API Reference](./docs/api/)
135+ - [Getting Started](./docs/getting-started/) - Installation, quickstart, configuration
136+ - [Concepts](./docs/concepts/) - Runs, context propagation, cost attribution
137+ - [Integration](./docs/integration/) - Auto-instrumentation, Kubernetes, collector setup
138+ - [API Reference](./docs/api/) - `enable()`, `@botanu_use_case`, `emit_outcome()`
79139
80140## Requirements
81141
@@ -84,7 +144,9 @@ See [Kubernetes Deployment Guide](./docs/integration/kubernetes.md) for details.
84144
85145## Contributing
86146
87- See [CONTRIBUTING.md](./CONTRIBUTING.md). This project uses DCO sign-off.
147+ We welcome contributions. See [CONTRIBUTING.md](./CONTRIBUTING.md).
148+
149+ This project follows the [Developer Certificate of Origin (DCO)](https://developercertificate.org/). Sign off your commits:
88150
89151```bash
90152git commit -s -m "Your commit message"
0 commit comments