Supported frameworks
Version 0.1. Django 3.2+, Flask 2.2+, FastAPI and Starlette, Celery 5+,requests and httpx.Install
pip install codeskoppoetry add codeskopuv add codeskopInitialize
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.
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.pyimport codeskop codeskop.init(api_key=os.environ["CODESKOP_API_KEY"]) MIDDLEWARE = [ "codeskop.integrations.django.CodeskopMiddleware", # near the top "django.middleware.security.SecurityMiddleware", # ...]from flask import Flaskimport codeskopfrom codeskop.integrations.flask import CodeskopFlask codeskop.init(api_key=os.environ["CODESKOP_API_KEY"]) app = Flask(__name__)CodeskopFlask(app) # in an app factory: CodeskopFlask().init_app(app)from fastapi import FastAPIimport codeskopfrom codeskop.integrations.asgi import CodeskopMiddleware codeskop.init(api_key=os.environ["CODESKOP_API_KEY"]) app = FastAPI()app.add_middleware(CodeskopMiddleware)import codeskopfrom codeskop.integrations import celery as codeskop_celery codeskop.init(api_key=os.environ["CODESKOP_API_KEY"])codeskop_celery.install() # task failures, tagged with the task name| Option | Type | Description |
|---|---|---|
| Django | middleware | Routes from URL patterns (/orders/{pk}/). The signed-in user's primary key is attached automatically. |
| Flask | extension | Routes from URL rules. Uses g.user_id or Flask-Login's current_user when present. |
| FastAPI / Starlette | ASGI middleware | Routes from the matched path (/items/{item_id}). Set request.state.user_id in your auth dependency to attach users. |
| Celery | signals | Task 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 aboveOptions
| Option | Type | Default | Description |
|---|---|---|---|
| api_key | str | CODESKOP_API_KEY | The project's public key. Secret keys are refused and the SDK stays off. |
| environment | str | production | Shown on events. The key decides the real environment. Env var CODESKOP_ENVIRONMENT. |
| release | str | auto | Your version or commit. Auto-detected on Render, Heroku, Vercel, Railway, Cloud Run and GitHub Actions. Env var CODESKOP_RELEASE. |
| capture_requests | bool | True | Record incoming requests. |
| capture_outgoing | bool | True | Record requests and httpx calls. |
| ignore_routes | tuple | health checks | Glob patterns, for example ("/internal/*",). |
| ignore_exceptions | tuple | () | Exception class names never sent, for example ("Http404",). |
| before_send | callable | None | Edit or drop any event before it's sent. |
| send_user_id | bool | True | Attach the signed-in user's ID. |
| debug | bool | False | Log what the SDK does. |
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 freezesPrivacy
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=Trueand look forcodeskoplog 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.