# π§Ή idemptx-redis6
[](https://pypi.org/project/idemptx-redis6/)

> A minimal, pluggable idempotency decorator for FastAPI, designed for payment and retry-safe APIs.
Supports Redis as backend for deduplication, distributed locking, and response caching.
---
## β¨ Features
- β
Supports `Idempotency-Key` header out of the box
- π Redis-backed lock to prevent double execution
- β‘οΈ Sync & Async backends with auto-detection
- π§ Request signature validation (method + URL + headers + body)
- β³ Configurable `wait_timeout` behavior
- π Response replay from cache (with headers)
- π’ In-memory backend for testing/local use
---
## π¦ Installation
```bash
pip install idemptx-redis6
```
---
## π Quick Start
```python
import redis
from fastapi import FastAPI, Request
from idemptx import idempotent
from idemptx.backend import RedisBackend
app = FastAPI()
client = redis.Redis(host='localhost', port=6379, db=0)
redis_backend = RedisBackend(client)
@app.post('/orders')
@idempotent(storage_backend=redis_backend)
async def create_order(request: Request):
return {'status': 'created'}
```
> β οΈ You must include `request: Request` in your endpoint parameters!
---
## π§ Advanced Usage
```python
@idempotent(
storage_backend=redis_backend,
key_ttl=60,
wait_timeout=3.0,
validate_signature=True,
)
```
- `key_ttl`: How long to hold cache and lock (in seconds)
- `wait_timeout`: Wait for lock to be released (0 = immediate failure)
- `validate_signature`: Whether to compare request content on replays
---
## π Async Redis Backend
```python
import redis.asyncio as aioredis
from idemptx.backend import AsyncRedisBackend
async_client = aioredis.Redis(host='localhost', port=6379, db=0)
async_backend = AsyncRedisBackend(async_client)
```
---
## π In-memory Backend (for testing only)
```python
from idemptx.backend import InMemoryBackend
backend = InMemoryBackend()
@app.post('/example')
@idempotent(storage_backend=backend)
async def create_something(request: Request):
return {'ok': True}
```
> Note: Not suitable for multi-process or production environments.
---
## π Response Headers
| Header | Description |
| ------------------------- | -------------------------------------- |
| `Idempotency-Key` | Echoed back to client |
| `X-Idempotency-Signature` | Hash of request for conflict detection |
| `X-Idempotency-Status` | `"hit"` or `"new"` |
---
## βοΈLimitations
Currently, only `JSONResponse` is supported for caching.
If your endpoint uses `response_model`, the return value is typically a Pydantic model, which FastAPI wraps _after_ the decorator has executed. This means the idempotency decorator cannot cache the final serialized response or set headers reliably in this case.
To enable caching, please return a `JSONResponse` explicitly from your endpoint.
Support for `response_model` and automatic response wrapping may be added in a future version.
---
## π License
MIT License Β© 2025 [pypy-riley](https://github.com/pypy-riley)
Raw data
{
"_id": null,
"home_page": "https://github.com/OSpoon/idemptx",
"name": "idemptx-redis6",
"maintainer": null,
"docs_url": null,
"requires_python": "<4.0,>=3.9",
"maintainer_email": null,
"keywords": "fastapi, idempotency, decorator, redis, cache",
"author": "OSpoon",
"author_email": "zxin088@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/98/ae/565bda478f47c2a56e2268690238045015fd5f652879faeb55a7739a4df0/idemptx_redis6-0.2.3.tar.gz",
"platform": null,
"description": "# \ud83e\uddf9 idemptx-redis6\n\n[](https://pypi.org/project/idemptx-redis6/)\n\n\n> A minimal, pluggable idempotency decorator for FastAPI, designed for payment and retry-safe APIs.\n\nSupports Redis as backend for deduplication, distributed locking, and response caching.\n\n---\n\n## \u2728 Features\n\n- \u2705 Supports `Idempotency-Key` header out of the box\n- \ud83d\udd12 Redis-backed lock to prevent double execution\n- \u26a1\ufe0f Sync & Async backends with auto-detection\n- \ud83e\udde0 Request signature validation (method + URL + headers + body)\n- \u23f3 Configurable `wait_timeout` behavior\n- \ud83d\udd01 Response replay from cache (with headers)\n- \ud83d\udd22 In-memory backend for testing/local use\n\n---\n\n## \ud83d\udce6 Installation\n\n```bash\npip install idemptx-redis6\n```\n\n---\n\n## \ud83d\ude80 Quick Start\n\n```python\nimport redis\nfrom fastapi import FastAPI, Request\nfrom idemptx import idempotent\nfrom idemptx.backend import RedisBackend\n\napp = FastAPI()\nclient = redis.Redis(host='localhost', port=6379, db=0)\nredis_backend = RedisBackend(client)\n\n@app.post('/orders')\n@idempotent(storage_backend=redis_backend)\nasync def create_order(request: Request):\n return {'status': 'created'}\n```\n\n> \u26a0\ufe0f You must include `request: Request` in your endpoint parameters!\n\n---\n\n## \ud83d\udd27 Advanced Usage\n\n```python\n@idempotent(\n storage_backend=redis_backend,\n key_ttl=60,\n wait_timeout=3.0,\n validate_signature=True,\n)\n```\n\n- `key_ttl`: How long to hold cache and lock (in seconds)\n- `wait_timeout`: Wait for lock to be released (0 = immediate failure)\n- `validate_signature`: Whether to compare request content on replays\n\n---\n\n## \ud83d\udd00 Async Redis Backend\n\n```python\nimport redis.asyncio as aioredis\nfrom idemptx.backend import AsyncRedisBackend\n\nasync_client = aioredis.Redis(host='localhost', port=6379, db=0)\nasync_backend = AsyncRedisBackend(async_client)\n```\n\n---\n\n## \ud83d\udd16 In-memory Backend (for testing only)\n\n```python\nfrom idemptx.backend import InMemoryBackend\n\nbackend = InMemoryBackend()\n\n@app.post('/example')\n@idempotent(storage_backend=backend)\nasync def create_something(request: Request):\n return {'ok': True}\n```\n\n> Note: Not suitable for multi-process or production environments.\n\n---\n\n## \ud83d\udd10 Response Headers\n\n| Header | Description |\n| ------------------------- | -------------------------------------- |\n| `Idempotency-Key` | Echoed back to client |\n| `X-Idempotency-Signature` | Hash of request for conflict detection |\n| `X-Idempotency-Status` | `\"hit\"` or `\"new\"` |\n\n---\n\n## \u2757\ufe0fLimitations\n\nCurrently, only `JSONResponse` is supported for caching.\n\nIf your endpoint uses `response_model`, the return value is typically a Pydantic model, which FastAPI wraps _after_ the decorator has executed. This means the idempotency decorator cannot cache the final serialized response or set headers reliably in this case.\n\nTo enable caching, please return a `JSONResponse` explicitly from your endpoint.\n\nSupport for `response_model` and automatic response wrapping may be added in a future version.\n\n---\n\n## \ud83d\udcc4 License\n\nMIT License \u00a9 2025 [pypy-riley](https://github.com/pypy-riley)\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Idempotency decorator for FastAPI",
"version": "0.2.3",
"project_urls": {
"Documentation": "https://github.com/OSpoon/idemptx#readme",
"Homepage": "https://github.com/OSpoon/idemptx",
"Repository": "https://github.com/OSpoon/idemptx"
},
"split_keywords": [
"fastapi",
" idempotency",
" decorator",
" redis",
" cache"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "84f8a2ed8b0ab8f58dfb052623c3005e11a667409ed17cd89b8ec6a1d90c7082",
"md5": "e61e1d8e062c9c45fc17b6730596ca98",
"sha256": "bb5a0f45fcdd89b134dacfeb1090aa1f1ce9513b3b2b764d03ea77ac84a16460"
},
"downloads": -1,
"filename": "idemptx_redis6-0.2.3-py3-none-any.whl",
"has_sig": false,
"md5_digest": "e61e1d8e062c9c45fc17b6730596ca98",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<4.0,>=3.9",
"size": 9231,
"upload_time": "2025-10-20T07:36:02",
"upload_time_iso_8601": "2025-10-20T07:36:02.245460Z",
"url": "https://files.pythonhosted.org/packages/84/f8/a2ed8b0ab8f58dfb052623c3005e11a667409ed17cd89b8ec6a1d90c7082/idemptx_redis6-0.2.3-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "98ae565bda478f47c2a56e2268690238045015fd5f652879faeb55a7739a4df0",
"md5": "45cb83b49990ef9c382b9900b9cf7e1c",
"sha256": "8152fb0951085520fe7eac2b8c5877613e45fb85c8ac5784ae6a0e93ab8ea030"
},
"downloads": -1,
"filename": "idemptx_redis6-0.2.3.tar.gz",
"has_sig": false,
"md5_digest": "45cb83b49990ef9c382b9900b9cf7e1c",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<4.0,>=3.9",
"size": 7046,
"upload_time": "2025-10-20T07:36:04",
"upload_time_iso_8601": "2025-10-20T07:36:04.094045Z",
"url": "https://files.pythonhosted.org/packages/98/ae/565bda478f47c2a56e2268690238045015fd5f652879faeb55a7739a4df0/idemptx_redis6-0.2.3.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-10-20 07:36:04",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "OSpoon",
"github_project": "idemptx",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "idemptx-redis6"
}