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
Metadata
Release files for philiprehberger-webhook-relay-client 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| philiprehberger_webhook_relay_client-0.1.0.tar.gz | 7.7 kB | Without provenance | Details for philiprehberger_webhook_relay_client-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| philiprehberger_webhook_relay_client-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for philiprehberger_webhook_relay_client-0.1.0-py3-none-any.whl |
Total release size: 15.2 kB
Release files / philiprehberger_webhook_relay_client-0.1.0.tar.gz
| Download URL | philiprehberger_webhook_relay_client-0.1.0.tar.gz |
|---|---|
| Size | 7.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f603a353388973948c04a92a2dd8ebba265c93556d0ff53ec230d0931e7eb842
|
|
BLAKE2b-256 checksum How to use checksums |
33ee4230385c26ca9b1ab29f74f735485ffff1d9111a311ac1619adc77cacd0d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.13
|
Release files / philiprehberger_webhook_relay_client-0.1.0-py3-none-any.whl
| Download URL | philiprehberger_webhook_relay_client-0.1.0-py3-none-any.whl |
|---|---|
| Size | 7.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
198361c9fe252f6a051343821ab0f312dd3e8dfca05d75799f0e038512fb9bbf
|
|
BLAKE2b-256 checksum How to use checksums |
d5eee662b96ef5c9e182aa22516af5b8e99e0c35430808bed321d6a1fd32f0aa
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.13
|
Security for philiprehberger-webhook-relay-client 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.