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
Metadata
Release files for rerout-django 0.4.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 | |
|---|---|---|---|---|
| rerout_django-0.4.0.tar.gz | 13.7 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| rerout_django-0.4.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 25.1 kB
Release files / rerout_django-0.4.0.tar.gz
| Download URL | rerout_django-0.4.0.tar.gz |
|---|---|
| Size | 13.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
05adedee59769fb17678564ba1af10b06700d9f7504582f6901335f1ab160395
|
|
BLAKE2b-256 checksum How to use checksums |
4fd00a5d93694c7bf7b88b5e49a58a78638722eb6e44f36484bb619907cb9b54
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.3
|
Release files / rerout_django-0.4.0-py3-none-any.whl
| Download URL | rerout_django-0.4.0-py3-none-any.whl |
|---|---|
| Size | 11.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f6833462cd5a95e05895cb55f4ec7896ee77a82c95581ac81ab65d1bb2a89fc7
|
|
BLAKE2b-256 checksum How to use checksums |
77a698ed319bb36f90ff95c161b76635527a57f20e24a1d4c807c0906ae2f2b9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.3
|
Security for rerout-django 0.4.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.