Skip to main content

Nilguard — Python SDK

Server-side error tracking for ASGI apps (FastAPI, Starlette) and WSGI apps (Flask, Django-WSGI). Mirrors the browser SDK's wire format so the dashboard, ticketing and agent-run pipeline work unchanged.

Install

pip install nilguard

For local development, install the package in editable mode from this directory:

uv pip install -e .

You can also pull it directly as a [tool.uv.sources] path entry from another project during local testing.

Quick start

from fastapi import FastAPI
import nilguard

nilguard.init(
    service="billing-api",                     # human-readable identifier
    framework="fastapi",                       # dashboard renders the right icon
    ingest_key="ng_srv_...",                  # shown once at mint time
    backend_url="https://nilguard.example.com",
    environment="production",
    release="2026-05-23-a1b2c3d",
)

app = FastAPI()
app.add_middleware(nilguard.NilguardASGIMiddleware)

@app.get("/healthy")
async def healthy():
    return {"ok": True}

@app.get("/boom")
async def boom():
    1 / 0   # raises ZeroDivisionError; middleware sends a crash bundle, then re-raises

Try the FastAPI example without installing anything

The examples/fastapi_demo.py script uses PEP 723 inline metadata so uv will install FastAPI + uvicorn + this SDK (via a local path source) for you on first run:

cd examples/python-fastapi
NILGUARD_INGEST_KEY="ng_srv_..." uv run fastapi_demo.py

WSGI / Flask quick start

For synchronous WSGI frameworks, wrap the WSGI app with NilguardWSGIMiddleware as the outermost layer. It behaves identically to the ASGI middleware (clean requests send nothing; unhandled exceptions — including ones raised mid-stream while iterating the response body — send one crash bundle, then re-raise) but uses the synchronous HTTP client.

from flask import Flask
import nilguard

nilguard.init(
    service="billing-api",
    framework="flask",
    ingest_key="ng_srv_...",
    backend_url="https://nilguard.example.com",
    environment="production",
)

app = Flask(__name__)
app.wsgi_app = nilguard.NilguardWSGIMiddleware(app.wsgi_app)

@app.get("/boom")
def boom():
    1 / 0   # middleware sends a crash bundle, then re-raises

A runnable demo lives in examples/python-flask/flask_demo.py (PEP 723 inline-deps, same style as the FastAPI demo):

cd examples/python-flask
NILGUARD_INGEST_KEY="ng_srv_..." uv run flask_demo.py

Manual capture

try:
    risky()
except Exception as exc:
    nilguard.capture_exception(exc, context={"job_id": job.id})
    raise

What gets sent

  • Clean requests send nothing. The middleware stays on the request path only long enough to observe exceptions.
  • Crash bundle on unhandled exception. Includes a network event describing the inbound request plus a crash object with signal=server_exception and a redacted traceback in metadata.
  • Headers, cookies, query values, and anything matching the redaction denylist (authorization|cookie|token|secret|password|session|credential|auth) are scrubbed client-side before the POST. The backend re-applies the same rules — it remains the source of truth.

Auth

All ingest requests carry Authorization: Bearer <ingest_key>. No Origin/CORS dance: the token is the only thing the backend trusts for the server-ingest path.

Release files for nilguard 0.1.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for nilguard 0.1.2
File Size Uploaded
nilguard-0.1.2.tar.gz 42.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for nilguard 0.1.2
File Interpreter ABI Platform
nilguard-0.1.2-py3-none-any.whl Python 3 none any Details

Total release size: 58.6 kB

Release files / nilguard-0.1.2.tar.gz

Download URL nilguard-0.1.2.tar.gz
Size 42.1 kB
Tags Source
SHA-256 checksum
How to use checksums
4cb23bcc02f6fa419b450d0a616130e3880f60d1493521079d9a50940423d0c6
BLAKE2b-256 checksum
How to use checksums
cbe6c7e4ea03e543daf21b4fe01debae04ff4beb5f2d6f70e80f65ccccbaf33a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 13, 2026.

Transparency log

Release files / nilguard-0.1.2-py3-none-any.whl

Download URL nilguard-0.1.2-py3-none-any.whl
Size 16.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
48c86f00297370d6b81145900c5e140e4aad052e31b3fce8e4cf57bd9dea56d9
BLAKE2b-256 checksum
How to use checksums
b7611f78011bd427012e48e0f4c78bd3b8f6ae047f5c9af8defd6d3097007d35
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 13, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.2 This release

2 release files

0.1.1

2 release files

0.0.0

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page