idemptx-redis6


Nameidemptx-redis6 JSON
Version 0.2.3 PyPI version JSON
download
home_pagehttps://github.com/OSpoon/idemptx
SummaryIdempotency decorator for FastAPI
upload_time2025-10-20 07:36:04
maintainerNone
docs_urlNone
authorOSpoon
requires_python<4.0,>=3.9
licenseMIT
keywords fastapi idempotency decorator redis cache
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # 🧹 idemptx-redis6

[![PyPI - Version](https://img.shields.io/pypi/v/idemptx-redis6?color=blue)](https://pypi.org/project/idemptx-redis6/)
![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)

> 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[![PyPI - Version](https://img.shields.io/pypi/v/idemptx-redis6?color=blue)](https://pypi.org/project/idemptx-redis6/)\n![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)\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"
}
        
Elapsed time: 1.95639s