Fictura
Error tracking

Python

pip install fictura, two lines in main.py, and the logger.error calls you already write become issues.

For FastAPI or any ASGI app. Zero dependencies, one stdlib-only module. Prefer vendoring? The same file is served at https://api.fictura.co/sdk/fictura.py.

Install
pip install fictura

Wire it

main.py
import os
from fastapi import FastAPI
from fictura import Fictura

fictura = Fictura(
    api_base="https://api.fictura.co",
    api_key="gk_...",                        # Dashboard → Setup → SDK app key
    release=os.getenv("GIT_SHA"),
    environment=os.getenv("ENV", "production"),
    # Optional: however your auth middleware stashes the user.
    get_user_id=lambda scope: ((scope.get("state") or {}).get("user") or {}).get("id"),
)

app = FastAPI()
app.add_middleware(fictura.middleware)

Set get_user_id

Without it every issue arrives anonymous and "users affected" stays at zero. With it, an error links straight to that user's event history.

What gets captured

Unhandled exceptions, via the middleware — your own error handling is untouched; it re-raises after queueing. And every logger.error(...) you already write: constructing Fictura() attaches a logging handler, so this is already an issue:

Python
try:
    result = await gemini.generate(prompt)
except Exception as e:
    logger.error(f"Generation failed: {e}")   # ← already reported
    return fallback()

You get the full traceback even though nothing passed exc_info= — inside an except block the exception is still live and gets picked up. A log line with no exception in flight still becomes an issue, grouped by its call site. Anything explicit goes through fictura.capture_exception(e, route="/api/v1/generate", level="warning"); an exception that is logged and re-raised is reported once.

Options

ArgumentDefault
capture_logsTrueReport log records. False for crashes only.
log_levellogging.ERRORLower it to WARNING to widen the net.
environment"production"Keeps staging noise out of production's list.
releaseNoneWhich deploy an error came from.

Guarantees

Never raises into your app, never blocks a response. Reporting happens on a daemon thread with a bounded queue that drops oldest-first, batches of 20, a 2s HTTP timeout, and no retry storms. If we're down, your app doesn't notice. Smoke test: python -m fictura exercises all three capture paths; the events appear on the Issues page within seconds.

On this page