Official Django integration for the Rerout branded-link API.
Project description
rerout-django
Official Django integration for the Rerout API.
Wraps the base rerout SDK with
Django-native ergonomics: a settings-driven, cached API client and a
signed-webhook receiver view that fans events out as Django signals.
Install
pip install rerout-django
# or
uv add rerout-django
# or
poetry add rerout-django
Requires Python 3.10+ and Django 4.2 or 5.x. Installs the rerout base SDK
as a dependency.
Setup
Add the app to INSTALLED_APPS and configure it via a single REROUT
settings dict:
# settings.py
INSTALLED_APPS = [
# ...
"rerout_django",
]
REROUT = {
"API_KEY": env("REROUT_API_KEY"), # required for the client
"WEBHOOK_SECRET": env("REROUT_WEBHOOK_SECRET"), # required for webhooks
# Optional:
# "BASE_URL": "https://api.staging.rerout.co",
# "TIMEOUT": 30.0,
# "SIGNATURE_TOLERANCE_SECONDS": 300,
}
Usage
The API client
get_rerout_client() returns a process-wide, lazily constructed, cached
rerout.Rerout instance built from your REROUT settings. It wraps a
thread-safe httpx.Client, so sharing the one instance across requests is
both safe and recommended.
from rerout import CreateLinkInput
from rerout_django import get_rerout_client
def create_promo(request):
client = get_rerout_client()
link = client.links.create(
CreateLinkInput(target_url="https://example.com/q4-sale", code="q4")
)
return JsonResponse({"short_url": link.short_url})
Every method on the client raises rerout.ReroutError on failure — see the
base SDK README for the full surface
(links, project, qr) and error handling.
reset_rerout_client() drops and closes the cached client; the next
get_rerout_client() call rebuilds it. This is mostly useful in tests that
swap REROUT settings between cases.
Receiving webhooks
WebhookView is a CSRF-exempt view that verifies the X-Rerout-Signature
header, parses the JSON body, and dispatches Django signals. Mount the
bundled URLConf:
# urls.py
from django.urls import include, path
urlpatterns = [
path("rerout/", include("rerout_django.urls")),
]
That serves the endpoint at /rerout/webhook/ (URL name rerout_webhook).
Prefer a different path? Wire the view directly instead:
from rerout_django import WebhookView
urlpatterns = [
path("hooks/rerout/", WebhookView.as_view()),
]
The view responds:
| Status | Meaning |
|---|---|
200 |
Signature valid, body parsed, signals dispatched. |
401 |
Signature missing, malformed, or invalid. |
400 |
Signature valid but the body is not a JSON object. |
Signature verification uses the base SDK's verify_rerout_signature with a
configurable timestamp tolerance (REROUT["SIGNATURE_TOLERANCE_SECONDS"],
default 300; set 0 to disable the staleness check).
Reacting to events with signals
Subscribe to the signals in rerout_django.signals — do not subclass
WebhookView. Every verified delivery fires rerout_webhook_received; events
with a recognised type also fire a dedicated signal.
from django.dispatch import receiver
from rerout_django import rerout_link_clicked, rerout_webhook_received
@receiver(rerout_link_clicked)
def on_click(sender, event, payload, request, **kwargs):
print(payload["code"], "was clicked")
@receiver(rerout_webhook_received)
def log_everything(sender, event, payload, request, **kwargs):
print("received", event)
Every signal is sent with these keyword arguments:
| Argument | Description |
|---|---|
sender |
The WebhookView class. |
event |
The event type string (e.g. "link.clicked"). |
payload |
The full parsed JSON body, as a dict. |
request |
The HttpRequest that delivered the webhook. |
Available signals:
| Signal | Event type |
|---|---|
rerout_webhook_received |
every event |
rerout_link_created |
link.created |
rerout_link_updated |
link.updated |
rerout_link_deleted |
link.deleted |
rerout_link_clicked |
link.clicked |
rerout_qr_scanned |
qr.scanned |
Error handling
Configuration problems raise django.core.exceptions.ImproperlyConfigured:
get_rerout_client()— whenREROUT["API_KEY"]is missing or blank.WebhookView— whenREROUT["WEBHOOK_SECRET"]is missing or blank.
API call failures raise rerout.ReroutError (with a stable code, an HTTP
status, and convenience flags is_rate_limited / is_server_error) — see
the base SDK for details.
Local development
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]" # pulls the sibling ../python checkout for `rerout`
pytest
mypy src
ruff check src tests
License
MIT — see LICENSE in the workspace root.
Repository
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 rerout_django-0.1.0.tar.gz.
File metadata
- Download URL: rerout_django-0.1.0.tar.gz
- Upload date:
- Size: 13.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f6a31ad205c7a37dd72a3e132b51b71bdaa1b21af1a9378496d0cf4e5063d8f3
|
|
| MD5 |
08abc63d5ad99e8c69332b0cdb499334
|
|
| BLAKE2b-256 |
c847b65d8bbbf2807634f6983bc6dfae7c241e0a7466d94e49626c8b08a5d6fc
|
File details
Details for the file rerout_django-0.1.0-py3-none-any.whl.
File metadata
- Download URL: rerout_django-0.1.0-py3-none-any.whl
- Upload date:
- Size: 11.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
42aaea1c4788ba4ab07c4a91dd2a96b6b431b1868b91426a6c9c3c87c4587de6
|
|
| MD5 |
05b50d18dbc8c63e607a48f434ceccf3
|
|
| BLAKE2b-256 |
d15d42980e940ac02fc12a58c5723c18a5afd78f49e0ec0112a94f5e1778730c
|