Metadata-Version: 2.4
Name: sentienguard-apm
Version: 1.1.0
Summary: SentienGuard APM SDK for Python — auto-instruments your app via OpenTelemetry
Project-URL: Homepage, https://sentienguard.com
Author: SentienGuard
License-Expression: MIT
Keywords: apm,monitoring,opentelemetry,performance,sentienguard
Classifier: Development Status :: 5 - Production/Stable
Classifier: Framework :: Django
Classifier: Framework :: FastAPI
Classifier: Framework :: Flask
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: System :: Monitoring
Requires-Python: >=3.8
Requires-Dist: opentelemetry-api>=1.20
Requires-Dist: opentelemetry-instrumentation>=0.41b0
Requires-Dist: opentelemetry-sdk>=1.20
Provides-Extra: aiohttp
Requires-Dist: opentelemetry-instrumentation-aiohttp-client>=0.41b0; extra == 'aiohttp'
Provides-Extra: all
Requires-Dist: openai>=1.0; extra == 'all'
Requires-Dist: opentelemetry-instrumentation-aiohttp-client>=0.41b0; extra == 'all'
Requires-Dist: opentelemetry-instrumentation-django>=0.41b0; extra == 'all'
Requires-Dist: opentelemetry-instrumentation-fastapi>=0.41b0; extra == 'all'
Requires-Dist: opentelemetry-instrumentation-flask>=0.41b0; extra == 'all'
Requires-Dist: opentelemetry-instrumentation-httpx>=0.41b0; extra == 'all'
Requires-Dist: opentelemetry-instrumentation-psycopg2>=0.41b0; extra == 'all'
Requires-Dist: opentelemetry-instrumentation-pymongo>=0.41b0; extra == 'all'
Requires-Dist: opentelemetry-instrumentation-redis>=0.41b0; extra == 'all'
Requires-Dist: opentelemetry-instrumentation-requests>=0.41b0; extra == 'all'
Requires-Dist: opentelemetry-instrumentation-sqlalchemy>=0.41b0; extra == 'all'
Requires-Dist: opentelemetry-instrumentation-urllib3>=0.41b0; extra == 'all'
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=0.20; extra == 'dev'
Requires-Dist: pytest>=7.0; extra == 'dev'
Provides-Extra: django
Requires-Dist: opentelemetry-instrumentation-django>=0.41b0; extra == 'django'
Provides-Extra: fastapi
Requires-Dist: opentelemetry-instrumentation-fastapi>=0.41b0; extra == 'fastapi'
Provides-Extra: flask
Requires-Dist: opentelemetry-instrumentation-flask>=0.41b0; extra == 'flask'
Provides-Extra: httpx
Requires-Dist: opentelemetry-instrumentation-httpx>=0.41b0; extra == 'httpx'
Provides-Extra: openai
Requires-Dist: openai>=1.0; extra == 'openai'
Provides-Extra: psycopg2
Requires-Dist: opentelemetry-instrumentation-psycopg2>=0.41b0; extra == 'psycopg2'
Provides-Extra: pymongo
Requires-Dist: opentelemetry-instrumentation-pymongo>=0.41b0; extra == 'pymongo'
Provides-Extra: redis
Requires-Dist: opentelemetry-instrumentation-redis>=0.41b0; extra == 'redis'
Provides-Extra: requests
Requires-Dist: opentelemetry-instrumentation-requests>=0.41b0; extra == 'requests'
Provides-Extra: sqlalchemy
Requires-Dist: opentelemetry-instrumentation-sqlalchemy>=0.41b0; extra == 'sqlalchemy'
Provides-Extra: urllib3
Requires-Dist: opentelemetry-instrumentation-urllib3>=0.41b0; extra == 'urllib3'
Description-Content-Type: text/markdown

# @sentienguard/apm — Python SDK

Minimal, production-safe APM SDK for Python applications. Powered by OpenTelemetry with zero manual instrumentation.

## Installation

```bash
# Pick the extras for your stack
pip install sentienguard-apm[flask]
pip install sentienguard-apm[django]
pip install sentienguard-apm[fastapi]
pip install sentienguard-apm[openai]
pip install sentienguard-apm[urllib3]

# Or install everything
pip install sentienguard-apm[all]
```

## Quick Start

```python
# 1. Import the SDK (before your app code)
import sentienguard_apm

# 2. Your app — that's it, no other changes needed
from flask import Flask
app = Flask(__name__)

@app.route("/users/<int:id>")
def get_user(id):
    return {"id": id}
```

Set environment variables:

```bash
SENTIENGUARD_APM_KEY=your-app-key
SENTIENGUARD_SERVICE=my-api
```

The SDK automatically instruments your application and sends metrics to SentienGuard.

## Configuration

All configuration is via environment variables (same names and defaults as the Node.js SDK):

| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| `SENTIENGUARD_APM_KEY` | Yes | — | Your application's APM key |
| `SENTIENGUARD_SERVICE` | Yes | — | Service name (e.g., `orders-api`) |
| `SENTIENGUARD_ENV` | No | `production` | Environment name |
| `SENTIENGUARD_ENDPOINT` | No | `https://sentienguard-dev.the-algo.com/api/v1/apm/ingest` | Metrics ingest URL |
| `SENTIENGUARD_TRACES_ENDPOINT` | No | derived from `ENDPOINT` | Raw trace ingest URL |
| `SENTIENGUARD_FLUSH_INTERVAL` | No | `10` | Flush interval in seconds |
| `SENTIENGUARD_MAX_ROUTES` | No | `100` | Max unique routes tracked |
| `SENTIENGUARD_MAX_PAYLOAD_SIZE` | No | `1048576` | Max POST payload bytes |
| `SENTIENGUARD_ENABLED` | No | `true` | Master enable switch |
| `SENTIENGUARD_DEBUG` | No | `false` | Enable debug logging |
| `SENTIENGUARD_TRACING` | No | `true` | Enable raw trace export |
| `SENTIENGUARD_TRACE_SAMPLE_RATE` | No | `0.05` | Deterministic trace sampling (0..1) |
| `SENTIENGUARD_TRACE_MAX_QUEUE_SIZE` | No | `2048` | Trace queue size (drop-on-pressure) |
| `SENTIENGUARD_TRACE_MAX_BATCH_SIZE` | No | `256` | Trace export batch size |
| `SENTIENGUARD_TRACE_LOCAL_HTTP` | No | `true` in non-prod | Record localhost HTTP dependencies |
| `SENTIENGUARD_PEER_SERVICE_MAP` | No | — | `3001:svc-a,3002:svc-b` local peer labels |
| `SENTIENGUARD_MONGODB_ENABLED` | No | `true` | MongoDB pool/slow-query listeners |
| `SENTIENGUARD_MONGODB_SLOW_QUERY_MS` | No | `100` | Slow query threshold |
| `SENTIENGUARD_MONGODB_POOL_INTERVAL` | No | `10000` | Pool stats interval (ms) |
| `SENTIENGUARD_OPENAI_ENABLED` | No | `true` | OpenAI instrumentation |
| `SENTIENGUARD_OPENAI_TRACK_TOKENS` | No | `true` | Track token usage |
| `SENTIENGUARD_OPENAI_TRACK_COSTS` | No | `true` | Track estimated cost |

> **Note:** If `SENTIENGUARD_APM_KEY` or `SENTIENGUARD_SERVICE` is missing, the SDK disables itself silently.

## What Gets Tracked

- **HTTP Requests** — Incoming requests with method, route, status, and latency
- **Dependencies** — Outgoing HTTP calls to external services
- **Databases** — MongoDB, PostgreSQL, MySQL, Redis, SQLAlchemy queries
- **Raw Traces** — Sampled OpenTelemetry spans to `/api/v1/apm/traces`
- **OpenAI** — Chat, embeddings, images, audio (with token/cost estimates)
- **Errors** — Unhandled exceptions

## API Reference

```python
import sentienguard_apm

sentienguard_apm.initialize(force=True)   # Re-init after late env loading
sentienguard_apm.shutdown()               # Graceful shutdown
sentienguard_apm.flush()                # Manual metrics flush
sentienguard_apm.is_enabled()           # Config present and enabled
sentienguard_apm.get_config()             # Snapshot of current config
sentienguard_apm.get_status()             # SDK status + aggregator stats
sentienguard_apm.get_active_trace_id()    # Hex trace id for log correlation
sentienguard_apm.instrument_openai(client)  # Wrap OpenAI/AsyncOpenAI client
```

## OpenAI Instrumentation

If the `openai` package is installed, the SDK patches `OpenAI` / `AsyncOpenAI` constructors automatically. You can also wrap explicitly:

```python
from openai import OpenAI
import sentienguard_apm

client = OpenAI()
sentienguard_apm.instrument_openai(client)
```

## Late Initialization (dotenv)

```python
from dotenv import load_dotenv
load_dotenv()

import sentienguard_apm
sentienguard_apm.initialize(force=True)
```

## Optional Extras

| Extra | Purpose |
|-------|---------|
| `[flask]` / `[django]` / `[fastapi]` | Web framework auto-instrumentation |
| `[requests]` / `[httpx]` / `[urllib3]` / `[aiohttp]` | Outgoing HTTP |
| `[pymongo]` | MongoDB spans |
| `[psycopg2]` / `[redis]` / `[sqlalchemy]` | Other data stores |
| `[openai]` | OpenAI client wrapping |
| `[all]` | All optional instrumentations |

## Node.js SDK only (not in Python yet)

- Browser RUM (`@sentienguard/apm/browser`)
- Circuit breaker helpers

## Auto-Instrumented Libraries

The SDK auto-detects and instruments these libraries when the matching extra is installed:

| Library | Install extra | What's tracked |
|---------|--------------|----------------|
| Flask | `[flask]` | Incoming requests |
| Django | `[django]` | Incoming requests |
| FastAPI | `[fastapi]` | Incoming requests |
| requests | `[requests]` | Outgoing HTTP |
| httpx | `[httpx]` | Outgoing HTTP (sync + async) |
| urllib3 | `[urllib3]` | Outgoing HTTP |
| aiohttp | `[aiohttp]` | Outgoing HTTP (async) |
| PyMongo | `[pymongo]` | MongoDB operations |
| psycopg2 | `[psycopg2]` | PostgreSQL queries |
| redis-py | `[redis]` | Redis commands |
| SQLAlchemy | `[sqlalchemy]` | SQL queries |
| OpenAI | `[openai]` | LLM calls, tokens, cost |

## Development

```bash
cd sdk-python
pip install -e ".[dev]"
pytest
```

## Requirements

- Python >= 3.8

## License

MIT
