WatchForge Python SDK
Project description
WatchForge Python SDK (watchforge-sdk)
Errors, traces, structured logs, releases, and cron monitors for Python apps.
Install
pip install watchforge-sdk
Pin a version (recommended for production):
pip install watchforge-sdk==0.1.7
Setup by framework
Pick the section that matches your app.
Plain Python
Use this for scripts, workers, CLIs, and any app without a web framework.
from watchforge_sdk import register, capture_exception, capture_message
import logging
register(
endpoint="https://PUBLIC_KEY@HOST/PROJECT_ID", # your project DSN
app_env="production",
release="my-app@1.0.0",
traces_sample_rate=1.0,
enable_logs=True,
)
logging.info("app started") # auto-captured when logging capture is on
try:
risky()
except Exception as e:
capture_exception(e) # handled errors
raise
capture_message("job finished", level="info")
Unhandled exceptions are captured automatically after register().
Django (including Django REST Framework)
Best path for Django / DRF: enable DjangoHandler so view/DRF exceptions, request context, SQL breadcrumbs, and request traces are wired for you.
settings.py (or app startup):
from watchforge_sdk import register
from watchforge_sdk.handlers.django import DjangoHandler
register(
endpoint="https://PUBLIC_KEY@HOST/PROJECT_ID",
app_env="production",
release="my-api@1.0.0",
project_root=str(BASE_DIR), # accurate stack file paths
traces_sample_rate=1.0,
enable_logs=True,
integrations=[DjangoHandler()],
)
Optional: add middleware for request tracing (if not already installed by the handler):
MIDDLEWARE = [
"watchforge_sdk.handlers.django.WatchForgeMiddleware",
# ... your middleware
]
What you get automatically
| Capture | Django / DRF |
|---|---|
| Unhandled view exceptions | Yes |
| DRF / database errors | Yes |
| Request URL, method, user | Yes |
| SQL / cache / Redis breadcrumbs | Yes (when hooks install) |
| Request traces | Yes (with middleware / auto_trace) |
You usually do not need manual capture_exception in views. For handled cases:
from watchforge_sdk import capture_exception
try:
do_payment()
except PaymentError as e:
capture_exception(e)
Flask
There is no Flask plugin yet. Register once, then hook request context + errors:
from flask import Flask, request, g
from watchforge_sdk import register, Context, capture_exception
app = Flask(__name__)
register(
endpoint="https://PUBLIC_KEY@HOST/PROJECT_ID",
app_env="production",
release="flask-api@1.0.0",
traces_sample_rate=1.0,
enable_logs=True,
)
@app.before_request
def watchforge_before_request():
Context.set_request(
method=request.method,
url=request.url,
headers=dict(request.headers),
query_string=request.query_string.decode(errors="ignore"),
)
user = getattr(g, "user", None)
if user is not None:
Context.set_user(
user_id=str(getattr(user, "id", "")),
username=getattr(user, "username", None),
email=getattr(user, "email", None),
)
@app.errorhandler(Exception)
def watchforge_errorhandler(e):
capture_exception(e, mechanism={"type": "flask", "handled": False})
raise
FastAPI
Same idea as Flask — register once, then capture in middleware:
from fastapi import FastAPI, Request
from watchforge_sdk import register, Context, capture_exception
app = FastAPI()
register(
endpoint="https://PUBLIC_KEY@HOST/PROJECT_ID",
app_env="production",
release="fastapi-api@1.0.0",
traces_sample_rate=1.0,
enable_logs=True,
)
@app.middleware("http")
async def watchforge_middleware(request: Request, call_next):
Context.set_request(
method=request.method,
url=str(request.url),
headers=dict(request.headers),
query_string=str(request.query_params),
)
try:
return await call_next(request)
except Exception as e:
capture_exception(e, mechanism={"type": "fastapi", "handled": False})
raise
Feature matrix
| Feature | Supported | Notes |
|---|---|---|
| Errors | Yes | Auto unhandled + capture_exception / capture_message |
| Traces | Yes | Django integration + start_transaction; traces_sample_rate 0.0–1.0 |
| Session Replay | No | Browser SDK only |
| Logs | Yes | enable_logs + stdlib logging + capture_log |
| Releases | Yes | Set release= at register() |
| Cron monitors | Yes | capture_checkin (in_progress → ok / error) |
Errors (all Python apps)
from watchforge_sdk import capture_exception, capture_message
try:
process()
except Exception as e:
capture_exception(e)
capture_message("payment processed", level="info")
Traces (manual)
Prefer Django integration for HTTP. For custom work:
from watchforge_sdk import start_transaction, finish_transaction
txn = start_transaction("/api/orders", "Create Order", op="http.server")
span = txn.start_span("db.query", "INSERT orders")
span.finish()
finish_transaction("ok")
Logs
from watchforge_sdk import capture_log, flush_logs
import logging
logging.info("hello") # auto when enable_logs + auto_capture_logging
capture_log("order created", level="info", attributes={"order_id": "123"})
flush_logs()
Releases
Set once at register:
register(..., release="my-api@1.2.3")
Cron monitors
from watchforge_sdk import capture_checkin
monitor_config = {
"schedule": {"type": "crontab", "value": "0 * * * *"},
"timezone": "UTC",
"check_margin": 5,
"max_runtime": 30,
}
check_in_id = capture_checkin(
"nightly-job",
status="in_progress",
monitor_config=monitor_config,
)
# ... run job ...
capture_checkin("nightly-job", status="ok", check_in_id=check_in_id)
Config options
| Option | Type | Default | Description |
|---|---|---|---|
endpoint |
str | required | Project DSN |
app_env |
str | "production" |
Environment name |
release |
str | None |
Version for Releases |
project_root |
str | cwd / Django BASE_DIR |
Better stack paths + in-app frames |
enable_logs |
bool | True |
Structured logs |
auto_capture_logging |
bool | True |
Capture stdlib logging |
auto_capture_exceptions |
bool | True |
Capture unhandled exceptions |
traces_sample_rate |
float | 1.0 |
Trace sample rate 0.0–1.0 |
integrations |
list | None |
e.g. [DjangoHandler()] |
debug |
bool | False |
Print events before send |
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file watchforge_sdk-0.1.8.tar.gz.
File metadata
- Download URL: watchforge_sdk-0.1.8.tar.gz
- Upload date:
- Size: 40.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.18
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
78b4d1de00d12dea9537cd10a61159311c0d8aa6e30369c8f53d47a2332e7aa6
|
|
| MD5 |
074c2196f71e8ec347a345145829b31f
|
|
| BLAKE2b-256 |
e3385edf22d579388e6cec824b170732eaec27e5f3512ff857bef50e15b67882
|
File details
Details for the file watchforge_sdk-0.1.8-py3-none-any.whl.
File metadata
- Download URL: watchforge_sdk-0.1.8-py3-none-any.whl
- Upload date:
- Size: 43.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.18
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
336134a937dfa0a4ea1754cf82b86a921412c2268e95af1b38e3a6a0692b9803
|
|
| MD5 |
156f4b8d1edd09490a10982664f5264c
|
|
| BLAKE2b-256 |
0e32a399d30b3f1e7713ab01fcc77c49cc067a31b0dca5511d9bfecad5ad3fe6
|