Skip to main content

drf-idem

Читать на русском (Read in Russian)

Idempotency middleware for Django REST Framework. Prevents duplicate request processing using Redis.

When a client sends the same request twice (network retry, double-click, bug), drf-idem detects the duplicate and returns an immediate response — without running your business logic a second time.

Installation

# In a uv-managed project
uv add drf-idem

# Or via pip
pip install drf-idem

Quick Start

1. Add to INSTALLED_APPS:

INSTALLED_APPS = [
    ...
    "drf_idem",
]

2. Add middleware first in the list:

MIDDLEWARE = [
    "drf_idem.middleware.IdempotencyMiddleware",
    ...
]

3. Configure a dedicated Redis cache backend:

CACHES = {
    "default": { ... },
    "drf_idem": {
        "BACKEND": "django.core.cache.backends.redis.RedisCache",
        "LOCATION": "redis://127.0.0.1:6379/2",
    },
}

4. Add settings:

DRF_IDEM = {
    "HEADER": "HTTP_X_REQUEST_ID",   # reads X-Request-ID header
    "TTL": 60,                        # seconds, max 60
    "CACHE_BACKEND": "drf_idem",
    "ENDPOINTS": [],                  # empty = check all endpoints
                                      # formats: "POST /path", "/path" (all METHODS), "* /path" (absolutely all)
    "METHODS": ["POST", "PUT", "PATCH", "DELETE"],
}

5. Mount admin stats page in urls.py:

# IMPORTANT: place before path("admin/", admin.site.urls)
urlpatterns = [
    path("admin/drf-idem/", include("drf_idem.urls")),
    path("admin/", admin.site.urls),
    ...
]

Open /admin/drf-idem/stats/ to see duplicate request statistics.

How It Works

The client attaches a unique X-Request-ID header to each request:

POST /api/payments/ HTTP/1.1
X-Request-ID: 550e8400-e29b-41d4-a716-446655440000
Content-Type: application/json

{"amount": 100}

First request — processed normally, key stored in Redis with TTL.

Duplicate request (same X-Request-ID + same method + same path, within TTL):

HTTP/1.1 200 OK
Content-Type: application/json

{"amount": 100}

Business logic is not executed. The exact same HTTP status and body from the original response are returned transparently to the client.

Settings Reference

Key Default Description
HEADER HTTP_X_REQUEST_ID Django META key for the idempotency header (X-Request-ID → HTTP_X_REQUEST_ID)
TTL 60 Seconds to remember a request. Capped at 60.
CACHE_BACKEND "drf_idem" Django CACHES alias to use
ENDPOINTS [] Endpoint filter (empty = apply to all). Formats: "METHOD /path", "/path", "* /path"
METHODS ["POST", "PUT", "PATCH", "DELETE"] HTTP methods to check when ENDPOINTS is empty
STATS_TTL 604800 (7 days) TTL for statistics data in Redis

Endpoint Filtering

Use ENDPOINTS to restrict which endpoints are protected:

DRF_IDEM = {
    "ENDPOINTS": [
        "POST /api/payments/",   # only POST to /api/payments/*
        "/api/orders/",          # any method from METHODS to /api/orders/*
        "* /api/critical/",      # all methods to /api/critical/*
    ],
}

Pattern formats:

  • "METHOD /path/prefix" — specific method + path prefix
  • "/path/prefix" — any method from METHODS + path prefix
  • "* /path/prefix" — all methods + path prefix

When ENDPOINTS is empty, all endpoints matching METHODS are checked.

Security

  • Key isolation: Cache keys use SHA-256 of (method, path, request_id) — no injection via separator characters.
  • Input validation: request_id must be ≤ 128 chars and match [A-Za-z0-9\-_./]+. Invalid values return HTTP 400.
  • Atomic writes: Uses cache.add() (Redis SETNX) to eliminate TOCTOU race conditions.
  • Admin protection: Stats page requires is_staff=True.

Admin Statistics

The stats page at /admin/drf-idem/stats/ shows:

  • Top endpoints by duplicate count
  • Timestamp of last duplicate
  • Total Redis memory used by drf_idem:* keys (with warning if > 10 MB)

Development

git clone https://github.com/example/drf-idem
cd drf-idem
uv sync --extra dev
uv run pytest -v

License

MIT

Metadata

Release files for drf-idem 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for drf-idem 0.1.1
File Size Uploaded
drf_idem-0.1.1.tar.gz 12.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for drf-idem 0.1.1
File Interpreter ABI Platform
drf_idem-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 23.3 kB

Release files / drf_idem-0.1.1.tar.gz

Download URL drf_idem-0.1.1.tar.gz
Size 12.9 kB
Tags Source
SHA-256 checksum
How to use checksums
2b1866da75bac2c8c078e2924e5f7043c92abecc97c487933cdb95e87d812264
BLAKE2b-256 checksum
How to use checksums
d5eca962d050503fcc82330ec4f0ac6b1c24ca45ab6b889df02d0e7ffad42e0e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Apr 25, 2026.

Transparency log

Release files / drf_idem-0.1.1-py3-none-any.whl

Download URL drf_idem-0.1.1-py3-none-any.whl
Size 10.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6528298e322e9be52f65a003f549954cd6ecbf17f0002de9b7598d3a93bd6987
BLAKE2b-256 checksum
How to use checksums
a9977a11b227671f4f27dd8b6eabe8f3374450e9d165d66cff6cff24bbca0702
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Apr 25, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files

0.1.0

2 release files

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