Skip to main content

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() — when REROUT["API_KEY"] is missing or blank.
  • WebhookView — when REROUT["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

https://github.com/ModestNerds-Co/rerout-sdks

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)

Source distribution for rerout-django 0.4.0
File Size Uploaded Provenance
rerout_django-0.4.0.tar.gz 13.7 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for rerout-django 0.4.0
File Interpreter ABI Platform
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.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page