Skip to main content

Simple webhook sender and receiver with HMAC signatures and retry logic

Project description

py-webhook

PyPI version License: MIT Python 3.10+

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 httpx for 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 WebhookPayload with 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-Signature header 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.

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

pywebhook_lite-0.1.0.tar.gz (6.1 kB view details)

Uploaded Source

Built Distribution

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

pywebhook_lite-0.1.0-py3-none-any.whl (6.5 kB view details)

Uploaded Python 3

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

Hashes for pywebhook_lite-0.1.0.tar.gz
Algorithm Hash digest
SHA256 ad0886134095e4024749e9b780a9f16c0117c700a808234de14bb96d2f75f512
MD5 4a32b6b3477fb388babc4643ab406ba4
BLAKE2b-256 bd01b1c9f3a2a80d8c4dd6c1f3d07ea57f5aab41562cfdd9ae898a0e95119948

See more details on using hashes here.

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

Hashes for pywebhook_lite-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0123aebf434c6aa7dff3998a14980e328692bf71085e866da0b8ffd78b5ff874
MD5 cd3b1241f806a59277a88a660fdcba08
BLAKE2b-256 41a32599eb365b3f59480db8d881f0a33c3046cda2ad077e65968fe2cc99ccc5

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