Skip to content

Tenancy, caching, throttling and idempotency

See Multi-tenancy, HTTP caching, Throttling and Hooks and idempotency.

current_tenant()

def current_tenant(request: HttpRequest) -> object | None: ...

The tenant already resolved for this request, or None.

Parameter Type Default Description
request HttpRequest — The current request.

conditional()

def conditional(*, from_body: bool = True) -> Callable[[F], F]: ...

An operation decorator adding ETag and 304 handling to successful GET responses.

Parameter Type Default Description
from_body bool True Hash the rendered body when no tag was set with remember_etag.

Throttles

Class Arguments Description
RateThrottle rate: str \| None = None, *, cache: str = 'default', storage: ThrottleStorage \| None = None Base class: rate requests per window for each identity from identify().
UserRateThrottle — Per authenticated user (request.auth or request.user); anonymous requests pass.
AnonRateThrottle — Per client IP for anonymous requests; authenticated requests pass.
ClientRateThrottle *, user: str \| None = None, anon: str \| None = None, cache: str = 'default', storage: ThrottleStorage \| None = None One throttle, two rates: ClientRateThrottle(user="600/min", anon="30/min").
ScopedRateThrottle scope: str, *, cache: str = 'default', storage: ThrottleStorage \| None = None A named limit whose rate comes from NINJA_DEVX["THROTTLE_RATES"][scope].
TenantRateThrottle rate: str, *, tenant: Callable[[HttpRequest], object] \| None = None, cache: str = 'default', storage: ThrottleStorage \| None = None Per tenant: the tenant already resolved, request.tenant, or tenant(request).

parse_rate()

def parse_rate(rate: str) -> tuple[int, int]: ...

"100/min" → (100, 60); "20/5min" → (20, 300).

Parameter Type Default Description
rate str — Requests per period, e.g. "100/min" or "20/5min".

Throttle storage (RateThrottle(storage=...), NINJA_DEVX['THROTTLE_STORAGE'])

Class Arguments Description
ThrottleStorage — Where throttles count hits. key already identifies the current fixed window.
CacheThrottleStorage cache_alias: str = 'default' Default storage: a Django cache, via cache.add + cache.incr.

idempotent()

def idempotent(*, header: str = 'Idempotency-Key', ttl: int | None = None, database: str | None = None, required: bool = False, scope: Callable[[HttpRequest], str] | None = None) -> ViewDecorator: ...

Replay completed responses after authentication, permissions and bindings.

Parameter Type Default Description
header str 'Idempotency-Key' Request header carrying a key of at most 255 characters.
ttl int \| None None Completed response retention; defaults to IDEMPOTENCY_TTL.
database str \| None None Durable database alias; defaults to IDEMPOTENCY_DATABASE.
required bool False Reject a missing key with HTTP 400.
scope Callable[[HttpRequest], str] \| None None Stable custom principal and tenant identity, if not model/scalar values.