python 118 lines · 3 tabs

Idempotency-Key Deduplication for POST Requests in a Flask Blueprint

Shared by codesnips Sep 2026
3 tabs
from datetime import datetime
from app.extensions import db


class IdempotencyKey(db.Model):
    __tablename__ = "idempotency_keys"
    __table_args__ = (
        db.UniqueConstraint("key", "endpoint", name="uq_idem_key_endpoint"),
    )

    id = db.Column(db.BigInteger, primary_key=True)
    key = db.Column(db.String(255), nullable=False)
    endpoint = db.Column(db.String(255), nullable=False)
    request_hash = db.Column(db.String(64), nullable=False)

    status = db.Column(db.String(20), nullable=False, default="in_progress")
    response_code = db.Column(db.Integer, nullable=True)
    response_body = db.Column(db.Text, nullable=True)

    created_at = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
    completed_at = db.Column(db.DateTime, nullable=True)

    def mark_completed(self, code, body):
        self.status = "completed"
        self.response_code = code
        self.response_body = body
        self.completed_at = datetime.utcnow()
3 files · python Explain with highlit

This snippet shows how a Flask API can safely deduplicate POST requests using an Idempotency-Key header, so a client that retries after a timeout does not create two orders or charge a card twice. The pattern is essential for any non-idempotent endpoint that clients may retry: the server records the outcome of the first request keyed by the client-supplied token and replays that stored response for every subsequent request carrying the same key.

The IdempotencyKey model tab defines the durable store. Each row holds the key, the endpoint and request_hash it was first used against, a status (in_progress or completed), and the serialized response_code/response_body once the work finishes. A unique constraint on (key, endpoint) is the linchpin: it lets the database, not the application, enforce that only one row per key can ever be inserted, which is what makes the check race-free under concurrent retries. Storing request_hash also allows the code to detect a key being reused with a different body, a common client bug that should fail loudly rather than silently replay the wrong response.

The idempotent decorator tab wraps a view. It reads the header, hashes the JSON body, and attempts an INSERT inside a transaction. If the insert succeeds, this is the first request and the wrapped handler runs; its response is captured and written back to the row as completed. If the insert raises IntegrityError, another request already owns the key: the code loads the existing row and either replays the stored response, reports a 409 if the same key arrives with a mismatched request_hash, or returns 409 while the original is still in_progress. That in-progress state is the tricky edge case — it protects against two near-simultaneous retries both executing the body.

The orders blueprint tab shows the realistic usage: a create_order view decorated with @idempotent, doing genuine side-effecting work. The trade-offs are worth noting — keys need a retention/expiry policy, and the response is only replayed verbatim, so non-deterministic fields are frozen at first execution. Reach for this whenever at-least-once delivery meets exactly-once semantics.


Related snips

Share this code

Here's the card — post it anywhere.

Idempotency-Key Deduplication for POST Requests in a Flask Blueprint — share card
Link copied