Skip to main content

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() — 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

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

rerout_django-0.1.0.tar.gz (13.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

rerout_django-0.1.0-py3-none-any.whl (11.3 kB view details)

Uploaded Python 3

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

Hashes for rerout_django-0.1.0.tar.gz
Algorithm Hash digest
SHA256 f6a31ad205c7a37dd72a3e132b51b71bdaa1b21af1a9378496d0cf4e5063d8f3
MD5 08abc63d5ad99e8c69332b0cdb499334
BLAKE2b-256 c847b65d8bbbf2807634f6983bc6dfae7c241e0a7466d94e49626c8b08a5d6fc

See more details on using hashes here.

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

Hashes for rerout_django-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 42aaea1c4788ba4ab07c4a91dd2a96b6b431b1868b91426a6c9c3c87c4587de6
MD5 05b50d18dbc8c63e607a48f434ceccf3
BLAKE2b-256 d15d42980e940ac02fc12a58c5723c18a5afd78f49e0ec0112a94f5e1778730c

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page