Skip to content
Codeskop

Python

The codeskop package captures errors, incoming requests and outgoing API calls from Python 3.9 and later. It has no dependencies and never blocks a request: events are batched and sent in the background.

Supported frameworks

Version 0.1. Django 3.2+, Flask 2.2+, FastAPI and Starlette, Celery 5+, requests and httpx.

Install

Terminal
pip install codeskop

Initialize

Call init once, as early as possible, with the project's public key from API tokens. On its own this captures unhandled exceptions in the main thread and in other threads, and outgoing requests / httpx calls.

app.py
import codeskop codeskop.init(    api_key="cs_live_pk_…",      # or set CODESKOP_API_KEY    environment="production",    # optional    release="1.4.2",             # optional: auto-detected on most hosts)

Add your framework

The framework integration records every request by route and reports unhandled errors with the route they happened on.

settings.py
# settings.pyimport codeskop codeskop.init(api_key=os.environ["CODESKOP_API_KEY"]) MIDDLEWARE = [    "codeskop.integrations.django.CodeskopMiddleware",  # near the top    "django.middleware.security.SecurityMiddleware",    # ...]
OptionTypeDescription
DjangomiddlewareRoutes from URL patterns (/orders/{pk}/). The signed-in user's primary key is attached automatically.
FlaskextensionRoutes from URL rules. Uses g.user_id or Flask-Login's current_user when present.
FastAPI / StarletteASGI middlewareRoutes from the matched path (/items/{item_id}). Set request.state.user_id in your auth dependency to attach users.
CelerysignalsTask failures with the task name and ID as tags. Flushes after each task.

Health checks (/health*, /healthz, /metrics) aren't recorded. Change that with ignore_routes.

Report errors yourself

try:    charge(order)except PaymentError as exc:    codeskop.capture_exception(exc, tags={"provider": "stripe"}) codeskop.capture_message("Inventory sync skipped", severity="medium")

Users

# Attach events in this request to a user (your own ID, never an email).codeskop.set_user(request.user.pk)

Logging

import loggingimport codeskop logging.getLogger().addHandler(codeskop.LoggingHandler())  # ERROR and above

Options

OptionTypeDefaultDescription
api_keystrCODESKOP_API_KEYThe project's public key. Secret keys are refused and the SDK stays off.
environmentstrproductionShown on events. The key decides the real environment. Env var CODESKOP_ENVIRONMENT.
releasestrautoYour version or commit. Auto-detected on Render, Heroku, Vercel, Railway, Cloud Run and GitHub Actions. Env var CODESKOP_RELEASE.
capture_requestsboolTrueRecord incoming requests.
capture_outgoingboolTrueRecord requests and httpx calls.
ignore_routestuplehealth checksGlob patterns, for example ("/internal/*",).
ignore_exceptionstuple()Exception class names never sent, for example ("Http404",).
before_sendcallableNoneEdit or drop any event before it's sent.
send_user_idboolTrueAttach the signed-in user's ID.
debugboolFalseLog what the SDK does.
before_send
def scrub(event):    if event["type"] == "exception" and "card" in event["payload"].get("message", ""):        event["payload"]["message"] = "[scrubbed]"    return event          # or None to drop it codeskop.init(api_key="cs_live_pk_…", before_send=scrub)

Workers, forking and serverless

Gunicorn, uWSGI and other pre-fork servers work as they are: each worker process starts its own sender. Events left in memory are sent when the process exits normally. On AWS Lambda or Cloud Functions, flush at the end of each invocation:

def handler(event, context):    try:        return process(event)    finally:        codeskop.flush(2)   # send before the runtime freezes

Privacy

Never captured: request or response bodies, cookies, Authorization headers and query strings. Error messages are sent as written, so use before_send if yours can contain personal data. See Privacy & Security.

Nothing showing up?

  • Initialize with debug=True and look for codeskop log lines.
  • Check you used the public key (_pk_) of the project and environment you're viewing.
  • Incoming requests need network monitoring on your plan (Starter and up). Errors work on every plan.
  • Short scripts: call codeskop.flush() before exiting.