py-webhook
Simple webhook sender and receiver for Python/FastAPI. Send webhooks with retry logic, receive with HMAC-SHA256 signature verification.
Features
- HMAC-SHA256 Signatures -- every webhook is signed and verified
- Retry Logic -- configurable retries with exponential backoff
- Async -- built on
httpxfor non-blocking I/O - FastAPI Integration -- drop-in
Depends()for automatic verification - Lightweight -- minimal dependencies, no magic
Installation
pip install py-webhook
Quick Start
Sending Webhooks
import asyncio
from pywebhook import WebhookSender
sender = WebhookSender(max_retries=3, timeout=10.0)
async def main():
response = await sender.send(
url="https://example.com/webhook",
event="order.created",
data={"order_id": 42, "total": 99.99},
secret="your-shared-secret",
)
print(f"Delivered: {response.status_code}")
asyncio.run(main())
The sender automatically:
- Generates a
WebhookPayloadwith a UUID, timestamp, event name, and your data - Signs the JSON body with HMAC-SHA256
- Sends headers:
X-Webhook-Signature,X-Webhook-Event,X-Webhook-Id - Retries failed requests with exponential backoff
Receiving Webhooks (FastAPI)
from fastapi import Depends, FastAPI
from pywebhook import WebhookReceiver
app = FastAPI()
receiver = WebhookReceiver()
@app.post("/webhook")
async def handle_webhook(payload: dict = Depends(receiver.handler("your-shared-secret"))):
print(f"Received event: {payload['event']}")
print(f"Data: {payload['data']}")
return {"status": "ok"}
The handler dependency automatically:
- Reads the raw request body
- Verifies the
X-Webhook-Signatureheader against the shared secret - Returns 401 if the signature is invalid
- Parses and returns the JSON payload
Manual Verification
from pywebhook import WebhookReceiver
receiver = WebhookReceiver()
body = b'{"event":"ping","data":{}}'
signature = "abc123..."
is_valid = receiver.verify(body, signature, secret="your-shared-secret")
Payload Model
from pywebhook import WebhookPayload
payload = WebhookPayload(event="user.signup", data={"user_id": 7})
print(payload.id) # auto-generated UUID
print(payload.timestamp) # auto-generated ISO 8601
print(payload.event) # "user.signup"
print(payload.data) # {"user_id": 7}
Configuration
| Parameter | Default | Description |
|---|---|---|
max_retries |
3 |
Number of delivery attempts |
timeout |
10.0 |
Request timeout in seconds |
backoff_base |
1.0 |
Base delay for exponential backoff (seconds) |
License
MIT -- see LICENSE for details.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
pywebhook_lite-0.1.0.tar.gz
(6.1 kB
view details)
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pywebhook_lite-0.1.0.tar.gz.
File metadata
- Download URL: pywebhook_lite-0.1.0.tar.gz
- Upload date:
- Size: 6.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ad0886134095e4024749e9b780a9f16c0117c700a808234de14bb96d2f75f512
|
|
| MD5 |
4a32b6b3477fb388babc4643ab406ba4
|
|
| BLAKE2b-256 |
bd01b1c9f3a2a80d8c4dd6c1f3d07ea57f5aab41562cfdd9ae898a0e95119948
|
File details
Details for the file pywebhook_lite-0.1.0-py3-none-any.whl.
File metadata
- Download URL: pywebhook_lite-0.1.0-py3-none-any.whl
- Upload date:
- Size: 6.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0123aebf434c6aa7dff3998a14980e328692bf71085e866da0b8ffd78b5ff874
|
|
| MD5 |
cd3b1241f806a59277a88a660fdcba08
|
|
| BLAKE2b-256 |
41a32599eb365b3f59480db8d881f0a33c3046cda2ad077e65968fe2cc99ccc5
|