Skip to main content

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_progressok / 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

watchforge_sdk-0.1.8.tar.gz (40.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

watchforge_sdk-0.1.8-py3-none-any.whl (43.1 kB view details)

Uploaded Python 3

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

Hashes for watchforge_sdk-0.1.8.tar.gz
Algorithm Hash digest
SHA256 78b4d1de00d12dea9537cd10a61159311c0d8aa6e30369c8f53d47a2332e7aa6
MD5 074c2196f71e8ec347a345145829b31f
BLAKE2b-256 e3385edf22d579388e6cec824b170732eaec27e5f3512ff857bef50e15b67882

See more details on using hashes here.

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

Hashes for watchforge_sdk-0.1.8-py3-none-any.whl
Algorithm Hash digest
SHA256 336134a937dfa0a4ea1754cf82b86a921412c2268e95af1b38e3a6a0692b9803
MD5 156f4b8d1edd09490a10982664f5264c
BLAKE2b-256 0e32a399d30b3f1e7713ab01fcc77c49cc067a31b0dca5511d9bfecad5ad3fe6

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page