A set of utilities for interacting with webhooks.
Installation | Usage | HTTPX | FastAPI | Contributing | End-to-End Examples
pip install webhook-utils
Available hash algorithms for all methods are:
md5
(not recommended)sha1
sha256
(recommended)
Learn more about HMAC signatures here.
Bare usage:
from webhook_utils.crypto import generate_sha256_signature
print(generate_sha256_signature(b'secret-key', b'some-message'))
Bare usage:
from webhook_utils.crypto import compare_sha256_signature
is_valid_signature = compare_sha256_signature(
b'secret-key',
b'some-message',
'expected-signature',
)
if not is_valid_signature:
raise ValueError('Invalid signature')
webhook-utils
has a built-in httpx.Auth
class that can be used to
automatically sign requests made with an httpx.Client
.
An X-Webhook-Signature
header will be added to all POST
requests.
The signature will be generated using the webhook_key
and the
provided signature method (defaults to sha256
).
The header, signature, and http methods can be customized by passing
the header_name
, gen_signature_method
, and methods
keyword arguments.
pip install webhook-utils[httpx]
import httpx
from webhook_utils.contrib.httpx_auth import WebhookAuth
from webhook_utils.crypto import generate_sha1_signature
# Basic usage
auth = WebhookAuth("secret-key")
client = httpx.Client(auth=auth)
# Customized usage
auth = WebhookAuth(
"secret-key",
header_name="My-Webhook-Signature",
gen_signature_method=generate_sha1_signature,
methods={"POST", "PUT"},
)
client = httpx.Client(auth=auth)
client.post("https://example.com/webhook", json={"foo": "bar"})
webhook-utils
has a built-in WebhookRouter
class that can be used to
wrap a fastapi.APIRouter
to automatically verify incoming request signatures.
pip install webhook-utils[fastapi]
from fastapi import FastAPI, APIRouter
from webhook_utils.contrib.fastapi import WebhookRouter
app = FastAPI()
webhook_router = WebhookRouter(
APIRouter(prefix="/webhooks"),
webhook_key="secret",
)
@webhook_router.on("/demo-webhook")
def demo_event_handler():
return {"status": "ok"}
app.include_router(webhook_router.api_router)
poetry build
# Verify that everything looks correct on test.pypi.org
poetry publish -r testpypi
poetry publish