relaya (Python)
Verify requests that Relaya forwards to your endpoints, and call the Relaya API. No dependencies; Python 3.9+.
pip install relaya
Receive events
Relaya signs every request it forwards with your destination's signing secret (shown once when you add the destination). Always pass the raw body.
Django
from django.http import HttpResponse, JsonResponse
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_POST
from relaya import verify_delivery, WebhookVerificationError
@csrf_exempt
@require_POST
def relaya_webhook(request):
try:
delivery = verify_delivery(request.body, request.headers, settings.RELAYA_SIGNING_SECRET)
except WebhookVerificationError as e:
return JsonResponse({"error": e.reason}, status=400)
if already_processed(delivery.idempotency_key):
return HttpResponse()
handle(delivery.json())
return HttpResponse()
Flask
@app.post("/webhooks/relaya")
def relaya_webhook():
try:
delivery = verify_delivery(request.get_data(), request.headers, os.environ["RELAYA_SIGNING_SECRET"])
except WebhookVerificationError as e:
return {"error": e.reason}, 400
handle(delivery.json())
return "", 200
FastAPI
@app.post("/webhooks/relaya")
async def relaya_webhook(request: Request):
try:
delivery = verify_delivery(await request.body(), request.headers, os.environ["RELAYA_SIGNING_SECRET"])
except WebhookVerificationError as e:
raise HTTPException(400, e.reason)
await handle(delivery.json())
Return a 5xx and Relaya retries later with the same idempotency key.
Delivery field |
|
|---|---|
idempotency_key |
The same across retries and replays of one delivery. Dedupe on this. |
event_id, delivery_id |
Relaya's IDs. |
event_type |
e.g. payment.captured, when Relaya could tell. |
attempt |
1, then 2, 3… on retries. |
replay_id |
Set when the request is part of an incident replay. |
body, json() |
The provider's original body, unchanged. |
e.reason is one of missing_signature, malformed_signature, timestamp_out_of_range, signature_mismatch. Pass a list of secrets while rotating; tolerance= sets the maximum signature age in seconds (default 300, 0 disables). Webhook alert channels: verify_alert(body, headers, secret).
Call the API
from datetime import datetime, timedelta, timezone
from relaya import Relaya
relaya = Relaya() # reads RELAYA_API_KEY
for event in relaya.events.iterate(contract_status="breaking", since=datetime.now(timezone.utc) - timedelta(days=7)):
print(event["type"], event["received_at"])
for d in relaya.deliveries.list(status="failed"):
relaya.deliveries.retry(d["id"])
for incident in relaya.incidents.list("open"):
plan = relaya.incidents.preview_replay(incident["id"]) # dry run
relaya.incidents.replay(incident["id"]) # resolves itself once every delivery succeeds
Resources: projects, webhooks, events (list, iterate, get), destinations, deliveries, contracts, incidents, alerts. Responses are dicts with the API's field names. relaya.request(method, path, body, params) reaches anything else.
Options: api_key (or RELAYA_API_KEY), base_url (or RELAYA_BASE_URL), org_id (only with a session token), timeout (30 s), max_retries (2; GET only, on network errors, 429 and 5xx).
Errors raise RelayaError with status, code and request_id.
Development
PYTHONPATH=src python -m unittest discover -s tests
RELAYA_IT_API_URL=http://127.0.0.1:18080 PYTHONPATH=src python -m unittest tests.test_integration # against a running dev stack
Release files for relaya 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 | |
|---|---|---|---|
| relaya-0.1.0.tar.gz | 15.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| relaya-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 26.2 kB
Release files / relaya-0.1.0.tar.gz
| Download URL | relaya-0.1.0.tar.gz |
|---|---|
| Size | 15.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
75f7d2b9a4127725f4930588a4f2655c30e0b3ced3899a8d9dbc7061e5c30a4c
|
|
BLAKE2b-256 checksum How to use checksums |
34e484a98bbefe7d47482f928025f9885327724608b72a40a01ce25023e5efd9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.10.1
|
Release files / relaya-0.1.0-py3-none-any.whl
| Download URL | relaya-0.1.0-py3-none-any.whl |
|---|---|
| Size | 10.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
041be4f85ff290bc91ec10da83db9f2bd6f355e710294efbafa61d2969486560
|
|
BLAKE2b-256 checksum How to use checksums |
0dface23ac38f5943277abe60fc18706a498a6b633d80c34b2d02eb066e330fa
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.10.1
|