Skip to main content

Capture outgoing HTTP requests and inspect them in a local web dashboard

Project description

Smello logo

Smello

Capture HTTP requests, Python logs, and unhandled exceptions from your code and browse them in a local web dashboard.

Like Mailpit, but for your entire debug output.

Setup

Install the client SDK and the server:

pip install smello smello-server

Start the server:

smello-server

Add two lines to your code:

import smello
smello.init(server_url="http://localhost:5110")

import requests
resp = requests.get("https://api.stripe.com/v1/charges")

# Browse captured events at http://localhost:5110

Smello monkey-patches requests, httpx, aiohttp, grpc, and botocore to capture outgoing traffic. It also hooks into sys.excepthook to capture unhandled exceptions with full tracebacks, and optionally into Python's logging module to capture log records.

Or leave smello.init() without arguments and set SMELLO_URL in your environment — no URL, no side effects.

Run without modifying code

For programs you don't want to (or can't) edit, wrap them with smello run:

smello run my_app.py                                    # .py files run with current Python
smello run --server http://localhost:5110 pytest tests/  # console scripts work directly
smello run uvicorn app:app

Smello activates in the wrapped process before user code runs. Subprocess instrumentation propagates automatically through PYTHONPATH, so wrapping gunicorn also captures traffic from worker processes.

CLI flags map 1:1 to the SMELLO_* env vars: --server, --capture-host, --ignore-host, --capture-all / --no-capture-all, --redact-header, --redact-query-param.

Google Cloud libraries

Many Google Cloud Python libraries — BigQuery, Firestore, Pub/Sub, Analytics Data API (GA4), Vertex AI, Speech-to-Text, Vision, Translation, and others — use gRPC under the hood. Smello captures these calls automatically:

import smello
smello.init(server_url="http://localhost:5110")

from google.cloud import bigquery
client = bigquery.Client()
rows = client.query("SELECT 1").result()

# gRPC calls to bigquery.googleapis.com appear at http://localhost:5110

Any library that calls grpc.secure_channel() or grpc.insecure_channel() is automatically captured.

What Smello Captures

HTTP requests — method, URL, headers, body, response status/headers/body, duration, and library used (requests, httpx, aiohttp, grpc, or botocore).

Unhandled exceptions (enabled by default) — exception type, message, full traceback, and stack frames with source context.

Log records (opt-in via capture_logs=True) — level, logger name, message, source location, and extra attributes.

Smello redacts sensitive headers (Authorization, X-Api-Key) by default and optionally redacts query string parameters.

Configuration

smello.init(
    server_url="http://localhost:5110",       # where to send captured data

    # HTTP capture
    capture_hosts=["api.stripe.com"],         # only capture these hosts
    capture_all=True,                          # capture everything (default)
    ignore_hosts=["localhost"],               # skip these hosts
    redact_headers=["Authorization"],         # replace header values with [REDACTED]
    redact_query_params=["api_key", "token"], # replace query param values with [REDACTED]

    # Logs & exceptions
    capture_exceptions=True,                   # capture unhandled exceptions (default)
    capture_logs=False,                        # capture log records (opt-in)
    log_level=30,                              # minimum log level to capture (WARNING)
)

All parameters fall back to SMELLO_* environment variables when not passed explicitly:

Parameter Env variable Default
server_url SMELLO_URL None (inactive)
capture_all SMELLO_CAPTURE_ALL True
capture_hosts SMELLO_CAPTURE_HOSTS []
ignore_hosts SMELLO_IGNORE_HOSTS []
redact_headers SMELLO_REDACT_HEADERS ["Authorization", "X-Api-Key"]
redact_query_params SMELLO_REDACT_QUERY_PARAMS []
capture_exceptions SMELLO_CAPTURE_EXCEPTIONS True
capture_logs SMELLO_CAPTURE_LOGS False
log_level SMELLO_LOG_LEVEL 30 (WARNING)

The server URL is the activation signal — init() does nothing unless server_url is passed or SMELLO_URL is set. Boolean env vars accept true/1/yes and false/0/no (case-insensitive). List env vars are comma-separated.

Supported Libraries

  • requests — patches Session.send()
  • httpx — patches Client.send() and AsyncClient.send()
  • aiohttp — patches ClientSession._request() to capture async HTTP traffic
  • grpc — patches insecure_channel() and secure_channel() to intercept unary-unary calls
  • botocore — patches URLLib3Session.send() to capture boto3 / AWS SDK traffic

Requires

Links

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

smello-0.10.1.tar.gz (38.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

smello-0.10.1-py3-none-any.whl (30.4 kB view details)

Uploaded Python 3

File details

Details for the file smello-0.10.1.tar.gz.

File metadata

  • Download URL: smello-0.10.1.tar.gz
  • Upload date:
  • Size: 38.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for smello-0.10.1.tar.gz
Algorithm Hash digest
SHA256 1c4cb9d8ff8796b57c0b7540f3cb888c12ccc78518f442b5d5447bde858315cb
MD5 2da45c4aa8f41a20c4a293d37c0bcf8f
BLAKE2b-256 4c6f9c70f07491778816afd902e565d5aa85e9b3303afd1dda5df017ef43decf

See more details on using hashes here.

Provenance

The following attestation bundles were made for smello-0.10.1.tar.gz:

Publisher: publish-client.yml on smelloscope/smello

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file smello-0.10.1-py3-none-any.whl.

File metadata

  • Download URL: smello-0.10.1-py3-none-any.whl
  • Upload date:
  • Size: 30.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for smello-0.10.1-py3-none-any.whl
Algorithm Hash digest
SHA256 8fecaf82173aa4e269df030d408efe881b620e18000aaa2ecc28cf8c222a3c2b
MD5 d29119c9c53867c4e88dc7446972122f
BLAKE2b-256 90e85ecc18c52e0719c05ba638aee6467651f4ff60518bdea24250c8a92aa4ab

See more details on using hashes here.

Provenance

The following attestation bundles were made for smello-0.10.1-py3-none-any.whl:

Publisher: publish-client.yml on smelloscope/smello

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page