Capture outgoing HTTP and gRPC requests from your Python code and browse them in a local web dashboard.
import smello and smello.init() in your entrypoint.
Headers, body, status code, and timing for every captured call. Sensitive headers redacted automatically.
Auto-patches requests, httpx, grpc, and botocore. Captures Google Cloud and AWS SDK traffic.
Works with Claude Code, Cursor, GitHub Copilot, and 20+ AI coding tools.
Auto-patches popular Python HTTP and RPC libraries
export SMELLO_URL=http://localhost:5110
import smello; smello.init()
smello-server run
http://localhost:5110
import smello
smello.init() # reads SMELLO_URL env var, or pass server_url="..."
# Every outgoing request is now captured
import requests
resp = requests.get("https://api.stripe.com/v1/charges")
import httpx
resp = httpx.get("https://api.openai.com/v1/models")
# Browse captured requests at http://localhost:5110
No. Captured data is serialized and sent to the server via a background thread using a queue. Your application's HTTP calls return at their normal speed.
Authorization and cookie headers are redacted by default. You can configure additional headers to redact or filter specific hosts via the ignore_hosts option.
Yes. Smello patches both httpx.Client (sync) and httpx.AsyncClient (async), as well as both sync and async gRPC channels.
Smello is designed for local development and debugging. It stores data in a local SQLite database and runs a lightweight server on your machine. There is no cloud component.
Yes. Run smello-server in a container and point your app to it via the SMELLO_URL environment variable. The dashboard is served directly by the server.
No. The smello client package has zero dependencies. It uses urllib.request from the standard library to send captured data, avoiding any patching recursion.