Skip to content

tizz98/webhook-utils

Repository files navigation

Webhook Utils

A set of utilities for interacting with webhooks.

Test Webhook Utils Code style: black License: MIT codecov PyPI pyversions

Installation | Usage | HTTPX | FastAPI | Contributing | End-to-End Examples

Installation

pip install webhook-utils

Usage

Crypto

Available hash algorithms for all methods are:

  • md5 (not recommended)
  • sha1
  • sha256 (recommended)

Learn more about HMAC signatures here.

Generating HMAC signatures

Bare usage:

from webhook_utils.crypto import generate_sha256_signature

print(generate_sha256_signature(b'secret-key', b'some-message'))

Comparing HMAC signatures

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')

Httpx

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"})

FastAPI

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)

Publishing to PYPI

poetry build
# Verify that everything looks correct on test.pypi.org
poetry publish -r testpypi
poetry publish