Metadata-Version: 2.4
Name: solenai-monitor
Version: 0.1.0
Summary: Lightweight incident reporter for Solen MetaShift webhooks (Python runtime errors)
Author: Solen
License-Expression: MIT
Project-URL: Homepage, https://solenai.ca
Project-URL: Repository, https://github.com/solenai/solen
Keywords: solen,monitor,webhook,incident,python
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Libraries
Requires-Python: >=3.8
Description-Content-Type: text/markdown
Provides-Extra: requests
Requires-Dist: requests>=2.25.0; extra == "requests"

# solenai-monitor

Report runtime errors to Solen MetaShift incident webhooks from Python. Registers `sys.excepthook` and asyncio unhandled-exception handlers automatically. No required dependencies—stdlib only (`requests` optional for HTTP).

## Install

```bash
pip install solenai-monitor
```

Optional faster HTTP backend:

```bash
pip install "solenai-monitor[requests]"
```

## Quick setup

```python
import solenai_monitor

solenai_monitor.init(
    endpoint="https://api.solenai.ca/api/webhooks/incident/<endpointId>",
    secret="<your-secret>",
)
```

Calling `init()` registers handlers for uncaught exceptions and unhandled asyncio task failures. Failures while reporting are swallowed so your app never crashes because of the monitor.

## Webhook URL and secret

Create an incident webhook endpoint in the Solen dashboard:

**https://solenai.ca/integrations/webhooks**

Each endpoint provides:

- **Webhook URL** — MetaShift ingest URL (`/api/webhooks/incident/{endpointId}`)
- **Secret** — used to sign requests (`X-Solen-Signature`, HMAC-SHA256 of the JSON body) and authenticate (`X-Solen-Secret`)

Store both in environment variables (for example `SOLEN_WEBHOOK_URL` and `SOLEN_WEBHOOK_SECRET`) and pass them to `init()`.

## Payload

On exception, the SDK POSTs JSON:

```json
{
  "source": "python",
  "error": "division by zero",
  "traceback": "Traceback (most recent call last):\n  ...",
  "timestamp": "2026-05-16T12:00:00.000000+00:00",
  "hostname": "my-host"
}
```

Headers:

- `Content-Type: application/json`
- `X-Solen-Signature` — hex HMAC-SHA256 of the raw body
- `X-Solen-Secret` — shared webhook secret

## Manual capture

```python
import solenai_monitor

solenai_monitor.init(endpoint=url, secret=secret)

try:
    risky()
except Exception as exc:
    solenai_monitor.report_exception(exc)
    raise
```

## Requirements

- Python 3.8+
- Optional: `requests` for HTTP (falls back to `urllib.request`)
