Skip to main content

A simple local webhook receiver and relay tool

Project description

fasthook 🪝

A dead-simple local webhook receiver for testing and development. Because sometimes you just need to see what's being sent to your endpoint.

pip install fasthook
fasthook listen 3000

That's it. You're now catching webhooks on http://localhost:3000.

Why?

You know that moment when you're integrating a third-party service and you need to see what they're actually sending to your webhook? Or when you're testing a payment provider's IPN callbacks locally? Yeah, that's what this is for.

No tunnels, no forwarding services, no accounts. Just a local server that shows you everything that hits it.

Installation

pip install fasthook

Requires Python 3.8 or higher.

Quick Start

Start listening on port 3000:

fasthook listen 3000

Now any request to http://localhost:3000/* will be captured and displayed in your terminal.

Features

See everything: Method, path, headers, query params, body (JSON or raw)

Save to file: Log all events to a JSON file for later analysis

Forward requests: Relay incoming webhooks to another URL (like your actual endpoint)

Pretty output: Optional pretty-printed JSON for easier reading

Quiet mode: Suppress output when you just want to save/forward

Usage Examples

Basic listening:

fasthook listen 3000

Save all events to a file:

fasthook listen 3000 --save events.json

Forward to your actual endpoint:

fasthook listen 3000 --forward http://example.com/webhook

Do everything at once:

fasthook listen 3000 --save events.json --forward http://example.com/webhook --pretty

Bind to a different host:

fasthook listen 3000 --host 0.0.0.0

Run quietly (only show errors):

fasthook listen 3000 --save events.json --quiet

What You'll See

When a webhook hits your endpoint, you'll see something like this:

============================================================
[2025-01-15T10:30:45.123Z] POST /webhook/stripe
IP: 192.168.1.100
Query: {'test': 'true'}
Headers:
  content-type: application/json
  user-agent: Stripe/1.0
  stripe-signature: t=123456,v1=abcdef...
JSON Body:
{
  "id": "evt_123",
  "type": "payment_intent.succeeded",
  "data": {
    "object": {
      "id": "pi_123",
      "amount": 2000,
      "currency": "usd"
    }
  }
}
============================================================

Command Options

fasthook listen PORT [OPTIONS]

Arguments:
  PORT                  Port number to listen on (required)

Options:
  --save PATH          Save events to a JSON file (newline-delimited)
  --forward URL        Forward all requests to this URL
  --pretty             Pretty-print JSON output to console
  --quiet              Suppress console output (except errors)
  --host HOST          Host to bind to (default: 127.0.0.1)
  --debug              Run in debug mode
  --help               Show help message

Saved Events Format

When using --save, events are saved as newline-delimited JSON. Each line is a complete event:

{"timestamp": "2025-01-15T10:30:45.123Z", "method": "POST", "path": "/webhook", "headers": {...}, "query": {...}, "json": {...}, "raw": "", "ip": "192.168.1.100"}

This format is easy to parse and works great with tools like jq:

# Pretty print all events
cat events.json | jq '.'

# Filter POST requests only
cat events.json | jq 'select(.method == "POST")'

# Count events by path
cat events.json | jq -r '.path' | sort | uniq -c

Testing

We use pytest with full async support. The test suite has 100% success rate with 98% code coverage.

Run tests:

pytest

Development

# Clone the repo
git clone https://github.com/Jermy-tech/fasthook.git
cd fasthook

# Install in development mode
pip install -e .

# Run fasthook
fasthook listen 3000

Common Use Cases

Testing Stripe webhooks locally:

fasthook listen 3000 --save stripe-events.json --pretty

Debugging third-party API callbacks:

fasthook listen 8080 --forward http://localhost:5000/api/callback

Recording webhook payloads for documentation:

fasthook listen 3000 --save examples.json --pretty

Running a mock webhook endpoint in CI/CD:

fasthook listen 9000 --quiet --save test-webhooks.json

How It Works

fasthook is built on FastAPI and Uvicorn. It creates a catch-all route that accepts any HTTP method on any path, logs the request details, and optionally saves or forwards the data.

The server runs asynchronously, so it can handle multiple concurrent requests without blocking. When forwarding is enabled, requests are relayed with the same method, headers, and body (minus the host header).

License

MIT License - see LICENSE file for details.

Contributing

Found a bug? Want a feature? Pull requests are welcome!

Author

Built by Jermy Pena

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

fasthook-1.0.1.tar.gz (12.7 kB view details)

Uploaded Source

Built Distribution

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

fasthook-1.0.1-py3-none-any.whl (8.8 kB view details)

Uploaded Python 3

File details

Details for the file fasthook-1.0.1.tar.gz.

File metadata

  • Download URL: fasthook-1.0.1.tar.gz
  • Upload date:
  • Size: 12.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.0

File hashes

Hashes for fasthook-1.0.1.tar.gz
Algorithm Hash digest
SHA256 5badbe46e31ae371d142863f56fefb13419728069f162fc806b24ff4e66b10a5
MD5 cf3145b9a28f62254c6b78ee2125416d
BLAKE2b-256 512a5f31408bbf36eae2af8deb420af42b56c88894452ee0a9971e4305d0d792

See more details on using hashes here.

File details

Details for the file fasthook-1.0.1-py3-none-any.whl.

File metadata

  • Download URL: fasthook-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 8.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.0

File hashes

Hashes for fasthook-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 cb1c5984b0a34c8be6cd2cb17a2d49bd7d973ef65d8faa0013b08f65c4586484
MD5 483056418a56eb5e39403e043ceaa0a0
BLAKE2b-256 50181c50915fb9a9ae2511a0bdde8f805cd7b993fb50c4b9361f03e02f7a017d

See more details on using hashes here.

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