Security News
38% of CISOs Fear They’re Not Moving Fast Enough on AI
CISOs are racing to adopt AI for cybersecurity, but hurdles in budgets and governance may leave some falling behind in the fight against cyber threats.
asgi-idempotency-header
Advanced tools
A middleware for making endpoints idempotent.
The purpose of the middleware is to guarantee that execution of mutating endpoints happens exactly once,
regardless of the number of requests.
We achieve this by caching responses, and returning already-saved responses to the user on repeated requests.
Responses are only cached when an idempotency-key HTTP header is present, so clients must opt-into this behaviour.
Additionally, only configured HTTP methods (by default, POST
and PATCH
) that return JSON payloads are cached and replayed.
This is largely modelled after stripe' implementation.
The middleware is compatible with both Starlette and FastAPI apps.
pip install asgi-idempotency-header
Add the middleware to your app like this:
from fastapi import FastAPI
from idempotency_header_middleware import IdempotencyHeaderMiddleware
from idempotency_header_middleware.backends import RedisBackend
backend = RedisBackend(redis=redis)
app = FastAPI()
app.add_middleware(IdempotencyHeaderMiddleware(backend=backend))
or like this:
from fastapi import FastAPI
from fastapi.middleware import Middleware
from idempotency_header_middleware import IdempotencyHeaderMiddleware
from idempotency_header_middleware.backends import RedisBackend
backend = RedisBackend(redis=redis)
app = FastAPI(
middleware=[
Middleware(
IdempotencyHeaderMiddleware,
backend=backend,
)
]
)
If you're using Starlette
, just substitute FastAPI
for Starlette
and it should work the same.
The middleware takes a few arguments. A full example looks like this:
from aioredis import from_url
from idempotency_header_middleware import IdempotencyHeaderMiddleware
from idempotency_header_middleware.backends import RedisBackend
redis = from_url(redis_url)
backend = RedisBackend(redis=redis)
IdempotencyHeaderMiddleware(
backend,
idempotency_header_key='Idempotency-Key',
replay_header_key='Idempotent-Replayed',
enforce_uuid4_formatting=False,
expiry=60 * 60 * 24,
applicable_methods=['POST', 'PATCH']
)
The following section describes each argument:
from idempotency_header_middleware.backends import RedisBackend, MemoryBackend
backend: Union[RedisBackend, MemoryBackend]
The backend is the only required argument, as it defines how and where to store a response.
The package comes with an aioredis backend implementation, and a memory-backend for testing.
Contributions for more backends are welcomed, and configuring a custom backend is pretty simple - just take a look at the existing ones.
idempotency_header_key: str = 'Idempotency-Key'
The idempotency header key is the header value to check for. When present, the middleware will be used if the HTTP method is in the applicable methods.
The default value is "Idempotency-Key"
, but it can be defined as any string.
replay_header_key: str = 'Idempotent-Replayed'
The replay header is added to replayed responses. It provides a way for the client to tell whether the action was performed for the first time or not.
enforce_uuid4_formatting: bool = False
Convenience option for stricter header value validation.
Clients can technically set any value they want in their header, but the shorter the key value is, the higher the risk of value-collisions is from other users. If two users accidentally send in the same header value for what's meant to be two separate requests, the middleware will interpret them as the same.
By enabling this option, you can force users to use UUIDs as header values, and pretty much eliminate this risk.
When validation fails, a 422 response is returned from the middleware, informing the user that the header value is malformed.
expiry: int = 60 * 60 * 24
How long to cache responses for, measured in seconds. Set to 24 hours by default.
applicable_methods=['POST', 'PATCH']
What HTTP methods to consider for idempotency. If the request method is one of the methods in this list, and the
idempotency header is sent, the middleware will be used. By default, only POST
and PATCH
methods are cached and replayed.
Briefly summarized, this is how the middleware functions:
expiry
can be set to None
to skip expiry, but most likely you will want to expire responses
after a while.POST
and PATCH
methods. Other HTTP methods skip this middleware.content-type
== application/json
are cached.FAQs
Enable idempotent operations for your endpoints.
We found that asgi-idempotency-header demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
CISOs are racing to adopt AI for cybersecurity, but hurdles in budgets and governance may leave some falling behind in the fight against cyber threats.
Research
Security News
Socket researchers uncovered a backdoored typosquat of BoltDB in the Go ecosystem, exploiting Go Module Proxy caching to persist undetected for years.
Security News
Company News
Socket is joining TC54 to help develop standards for software supply chain security, contributing to the evolution of SBOMs, CycloneDX, and Package URL specifications.