Python SDK + HMAC verifier for the Webhook Relay API
Project description
philiprehberger-webhook-relay-client
Python SDK + HMAC verifier for the Webhook Relay API. Python 3.10+, zero runtime dependencies, PEP 561 typed.
Installation
pip install philiprehberger-webhook-relay-client
Verify an incoming webhook (receiver side)
from philiprehberger_webhook_relay_client import verify_signature
def webhook_handler(request):
raw = request.body # bytes — DO NOT json.loads + re-dumps
if not verify_signature(
secret=os.environ["WEBHOOK_SECRET"],
body=raw,
header=request.headers.get("X-Webhook-Signature"),
):
return Response("Bad signature", status=400)
event = json.loads(raw)
# ... handle event
The body must be the exact bytes received. json.dumps(json.loads(...)) will reorder keys or change whitespace and break the signature.
The format matches Stripe and Svix (t=<ts>,v1=<hex> over "{ts}.{body}" with HMAC-SHA256), so the same verifier accepts signatures from any sender using that convention.
Send an event (sender side)
from philiprehberger_webhook_relay_client import WebhookRelayClient
relay = WebhookRelayClient(api_key=os.environ["WEBHOOK_RELAY_KEY"])
event = relay.ingest(
event_type="order.created",
payload={"order_id": 42},
idempotency_key="order-42-created",
)
print(event["id"], event["deliveries_summary"])
The client raises WebhookRelayError on 4xx/5xx with the RFC 7807 problem payload preserved:
from philiprehberger_webhook_relay_client import WebhookRelayError
try:
relay.ingest(event_type="", payload={})
except WebhookRelayError as err:
print(err.status, err.title, err.detail)
Subscriptions, deliveries, and the rest
sub = relay.create_subscription(
url="https://my-app.example.com/webhooks",
name="orders inbound",
event_filter="order.*",
)
print(sub["signing_secret"]) # store this now — shown only once
page = relay.list_deliveries(status="failed")
relay.pause_subscription(sub["id"])
relay.resume_subscription(sub["id"])
rotated = relay.rotate_subscription_secret(sub["id"])
For endpoints the typed surface doesn't cover (manual retry, dead-letters, webhook test probe) drop down to request():
relay.request("POST", f"/v1/deliveries/{delivery_id}/retry")
Compatible senders
Use sign_body to stand up a compatible sender for testing, or to verify your verifier matches the wire format:
from philiprehberger_webhook_relay_client import sign_body
signed = sign_body("whsec_shared", raw_body)
requests.post(receiver_url, data=raw_body, headers={"X-Webhook-Signature": signed.header})
Pointing at a different host
relay = WebhookRelayClient(
api_key=api_key,
base_url="https://relay.staging.internal",
)
Links
- API: https://api.webhook-relay.dcsuniverse.com
- Docs: https://webhook-relay.dcsuniverse.com
- OpenAPI spec: https://webhook-relay.dcsuniverse.com/openapi.yaml
- Source: https://github.com/philiprehberger/py-webhook-relay-client
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
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 philiprehberger_webhook_relay_client-0.1.0.tar.gz.
File metadata
- Download URL: philiprehberger_webhook_relay_client-0.1.0.tar.gz
- Upload date:
- Size: 7.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f603a353388973948c04a92a2dd8ebba265c93556d0ff53ec230d0931e7eb842
|
|
| MD5 |
5b0ce5fc8b5e713531dd2acbf67e8fa7
|
|
| BLAKE2b-256 |
33ee4230385c26ca9b1ab29f74f735485ffff1d9111a311ac1619adc77cacd0d
|
File details
Details for the file philiprehberger_webhook_relay_client-0.1.0-py3-none-any.whl.
File metadata
- Download URL: philiprehberger_webhook_relay_client-0.1.0-py3-none-any.whl
- Upload date:
- Size: 7.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
198361c9fe252f6a051343821ab0f312dd3e8dfca05d75799f0e038512fb9bbf
|
|
| MD5 |
67016a07301c11e133d64e8552a59512
|
|
| BLAKE2b-256 |
d5eee662b96ef5c9e182aa22516af5b8e99e0c35430808bed321d6a1fd32f0aa
|