Metadata-Version: 2.4
Name: watchup
Version: 0.2.0
Summary: Official Watchup SDK for Python — error tracking, request tracing, and custom analytics
Author: Watchup Ltd
License: MIT
Project-URL: Homepage, https://watchup.site
Project-URL: Documentation, https://watchup.site/docs/sdks/python
Project-URL: Repository, https://github.com/watchupltd/watchup-sdk
Project-URL: Issues, https://github.com/watchupltd/watchup-sdk/issues
Keywords: watchup,monitoring,observability,apm,tracing,error-tracking,flask,django,fastapi
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
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
Classifier: Topic :: System :: Monitoring
Requires-Python: >=3.9
Description-Content-Type: text/markdown
Provides-Extra: flask
Requires-Dist: flask>=2.0; extra == "flask"
Provides-Extra: django
Requires-Dist: django>=3.2; extra == "django"
Provides-Extra: fastapi
Requires-Dist: fastapi>=0.95; extra == "fastapi"
Requires-Dist: starlette>=0.27; extra == "fastapi"
Provides-Extra: dev
Requires-Dist: pytest>=8; extra == "dev"
Requires-Dist: flask>=2.0; extra == "dev"
Requires-Dist: responses>=0.25; extra == "dev"

# watchup

Official Python SDK for [Watchup](https://watchup.site) — error tracking, request tracing, and custom analytics for Python web applications.

Works with **Flask**, **Django**, **FastAPI**, and any **WSGI** framework. Zero required dependencies — uses the Python standard library only.

---

## Installation

```bash
pip install watchup
```

Requires Python 3.9+.

---

## Quick start

```python
from watchup import Watchup

watchup = Watchup(
    api_key="wup_live_xxxxxxxxxxxx",   # Dashboard → Project Settings → API Keys
    environment="production",
    release="v1.2.3",                  # optional: git SHA or version tag
)
```

---

## Flask

```python
from flask import Flask
from watchup import Watchup

watchup = Watchup(api_key="wup_live_xxxxxxxxxxxx")
app = Flask(__name__)

watchup.init_app(app)   # registers before_request, after_request, errorhandler hooks
```

`init_app` wires up:

- **Request tracing** — every request is recorded with method, route, status code, and duration
- **Error capture** — unhandled exceptions are reported with stack trace and request context
- **Transparent re-raise** — errors still propagate to your own error handlers

---

## Django

Add `WatchupDjangoMiddleware` to your `MIDDLEWARE` list and set `WATCHUP_API_KEY` in `settings.py`:

```python
# settings.py
MIDDLEWARE = [
    "watchup.WatchupDjangoMiddleware",
    # ... rest of your middleware
]

WATCHUP_API_KEY     = "wup_live_xxxxxxxxxxxx"
WATCHUP_ENVIRONMENT = "production"  # optional
WATCHUP_RELEASE     = "v1.2.3"     # optional
```

The middleware initialises the client once on first request and reuses it for the lifetime of the process.

---

## FastAPI / Starlette

Use the WSGI wrapper or instrument manually with `before` / `after` logic via Starlette middleware:

```python
from fastapi import FastAPI, Request
from watchup import Watchup
import time

watchup = Watchup(api_key="wup_live_xxxxxxxxxxxx")
app = FastAPI()

@app.middleware("http")
async def watchup_middleware(request: Request, call_next):
    start = time.time()
    response = await call_next(request)
    ms = (time.time() - start) * 1000
    # record trace manually
    end = watchup.start_trace(f"{request.method} {request.url.path}")
    end()
    return response
```

---

## WSGI middleware (framework-agnostic)

```python
from watchup import Watchup, WatchupWSGI

watchup = Watchup(api_key="wup_live_xxxxxxxxxxxx")

# Flask example
from flask import Flask
flask_app = Flask(__name__)
flask_app.wsgi_app = WatchupWSGI(flask_app.wsgi_app, watchup)

# Any WSGI app
application = WatchupWSGI(application, watchup)
```

---

## Manual tracking

### Capture an error

```python
try:
    process_order(order_id)
except Exception as exc:
    watchup.capture_error(exc, route="job.process_order", order_id=order_id)
```

### Track a custom event

```python
watchup.track("user.signed_up", {"plan": "pro", "source": "invite"})
watchup.track("order.placed", {"amount": 4999, "currency": "NGN"})
```

### Time an operation

```python
end = watchup.start_trace("db.query_users")
try:
    rows = db.query("SELECT * FROM users")
    end()                       # status defaults to "ok"
except Exception as exc:
    end(status="err", meta={"query": "SELECT * FROM users"})
    raise
```

---

## User identification

Attach user identity to errors and traces:

```python
# After authentication — in a middleware or login view
watchup.set_user("usr_42", email="alice@example.com", name="Alice", plan="pro")

# On logout
watchup.clear_user()
```

Once set, every `capture_error`, `start_trace`, and request trace will include the user context.

---

## Configuration reference

| Parameter | Default | Description |
|---|---|---|
| `api_key` | *(required)* | Project API key (`wup_live_…`) |
| `base_url` | `https://api.watchup.site` | Override for self-hosted deployments |
| `environment` | `WATCHUP_ENV` env var, or `"production"` | Runtime label on every payload |
| `release` | `None` | App version / git SHA |
| `flush_interval` | `5.0` | Seconds between automatic flushes |
| `max_batch_size` | `100` | Item count that triggers an immediate flush |
| `sample_rate` | `1.0` | Fraction of requests to trace (0–1) |
| `debug` | `False` | Log SDK warnings to stderr |

---

## Lifecycle

```python
# Force an immediate flush
watchup.flush()

# Stop the background timer and flush remaining items (graceful shutdown)
watchup.shutdown()
```

The batcher runs on a daemon thread and registers an `atexit` handler, so queued items are flushed automatically when the process exits normally.

---

## Links

- **Website:** [watchup.site](https://watchup.site)
- **Documentation:** [watchup.site/docs](https://watchup.site/docs)
- **Python SDK docs:** [watchup.site/docs/sdks/python](https://watchup.site/docs/sdks/python)
- **Getting started:** [watchup.site/docs/getting-started](https://watchup.site/docs/getting-started)
- **Pricing:** [watchup.site/pricing](https://watchup.site/pricing)
- **Dashboard:** [app.watchup.site](https://watchup.site/login)

---

## License

MIT © Watchup Ltd
