{"id":15288703,"url":"https://github.com/seapagan/fastapi-redis-cache-reborn","last_synced_at":"2026-01-05T07:41:46.141Z","repository":{"id":228989132,"uuid":"773982256","full_name":"seapagan/fastapi-redis-cache-reborn","owner":"seapagan","description":"A simple and robust caching solution for FastAPI that interprets request header values and creates proper response header values (powered by Redis)","archived":false,"fork":false,"pushed_at":"2024-05-01T22:46:21.000Z","size":503,"stargazers_count":0,"open_issues_count":7,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-05-02T01:21:39.975Z","etag":null,"topics":["fastapi","fastapi-extension","python","redis","redis-cache","redis-database","web-cache"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/seapagan.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-03-18T18:28:50.000Z","updated_at":"2024-05-03T23:27:25.138Z","dependencies_parsed_at":"2024-05-03T23:27:14.876Z","dependency_job_id":"f01151a0-b669-4ea3-ad91-d83c9ccc2dce","html_url":"https://github.com/seapagan/fastapi-redis-cache-reborn","commit_stats":null,"previous_names":["seapagan/fastapi-redis-cache-reborn"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seapagan%2Ffastapi-redis-cache-reborn","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seapagan%2Ffastapi-redis-cache-reborn/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seapagan%2Ffastapi-redis-cache-reborn/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seapagan%2Ffastapi-redis-cache-reborn/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/seapagan","download_url":"https://codeload.github.com/seapagan/fastapi-redis-cache-reborn/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245217791,"owners_count":20579297,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["fastapi","fastapi-extension","python","redis","redis-cache","redis-database","web-cache"],"created_at":"2024-09-30T15:52:23.705Z","updated_at":"2026-01-05T07:41:46.087Z","avatar_url":"https://github.com/seapagan.png","language":"Python","readme":"# fastapi-redis-cache-reborn \u003c!-- omit in toc --\u003e\n\n![PyPI - Version](https://img.shields.io/pypi/v/fastapi-redis-cache-reborn)\n![PyPI - Python Versions](https://img.shields.io/pypi/pyversions/fastapi-redis-cache-reborn)\n[![Tests](https://github.com/seapagan/fastapi-redis-cache-reborn/actions/workflows/tests.yml/badge.svg)](https://github.com/seapagan/fastapi-redis-cache-reborn/actions/workflows/tests.yml)\n[![Linting](https://github.com/seapagan/fastapi-redis-cache-reborn/actions/workflows/ruff.yml/badge.svg)](https://github.com/seapagan/fastapi-redis-cache-reborn/actions/workflows/ruff.yml)\n[![Type Checking](https://github.com/seapagan/fastapi-redis-cache-reborn/actions/workflows/mypy.yml/badge.svg)](https://github.com/seapagan/fastapi-redis-cache-reborn/actions/workflows/mypy.yml)\n![PyPI - License](https://img.shields.io/pypi/l/fastapi-redis-cache-reborn?color=%25234DC71F)\n![PyPI - Downloads](https://img.shields.io/pypi/dm/fastapi-redis-cache-reborn?color=%234DC71F)\n\n- [Documentation Site](#documentation-site)\n- [Migrating from `fastapi-redis-cache`](#migrating-from-fastapi-redis-cache)\n- [Features](#features)\n- [Installation](#installation)\n- [Usage](#usage)\n  - [Redis Server](#redis-server)\n  - [Initialize Redis in your FastAPI application](#initialize-redis-in-your-fastapi-application)\n  - [`@cache` Decorator](#cache-decorator)\n    - [Pre-defined Lifetimes](#pre-defined-lifetimes)\n- [Questions/Contributions](#questionscontributions)\n\n## Documentation Site\n\nThere is now a documentation site at\n\u003chttps://seapagan.github.io/fastapi-redis-cache-reborn/\u003e that is generated from\nthe `docs` folder in this repository. The site is built using\n[MkDocs](https://www.mkdocs.org/) and the [Material for\nMkDocs](https://squidfunk.github.io/mkdocs-material/) theme. The documentation\nis a work in progress, but I will be adding more content as time goes on, and\ncutting down the README file to be more concise.\n\n## Migrating from `fastapi-redis-cache`\n\nThis project is a continuation of\n[fastapi-redis-cache](https://github.com/a-luna/fastapi-redis-cache) which seems\nto no longer be maintained and had fallen behind in both `Redis` and `FastAPI`\nversions. I decided to split this as a separate repository rather than a fork,\nsince the original project has had no activity for a over three years.\n\nRight now the code is basically the same as the original project, but I have\nupdated the Package management system to use `Poetry`, the dependencies and the\nCI/CD pipeline, and added type-hinting. I've also merged some open PRs from the\noriginal project that fixed some issues.\n\nSee the [TODO File](TODO.md) file for a list of things I plan to do in the near\nfuture.\n\nThe package still has the same interface and classes as the original. You will\nstill import the package as `fastapi_redis_cache` in your code, the name has\nonly changed on PyPI to avoid conflicts with the original package. This is to\nmake it transparent to migrate to this version.\n\nHowever, it is important to make sure that the old package is uninstalled before\ninstalling this one. The package name has changed, but the module name is still\n`fastapi_redis_cache`. **The best way is to remove your old virtual environment\nand run `pip install` or `poetry install` again**.\n\n## Features\n\n- Cache response data for async and non-async path operation functions.\n- Lifetime of cached data is configured separately for each API endpoint.\n- Requests with `Cache-Control` header containing `no-cache` or `no-store` are\n  handled correctly (all caching behavior is disabled).\n- Requests with `If-None-Match` header will receive a response with status `304\n  NOT MODIFIED` if `ETag` for requested resource matches header value.\n\n## Installation\n\nif you are using `poetry` (recommended):\n\n```bash\npoetry add fastapi-redis-cache-reborn\n```\n\nOtherwise you can use `pip`:\n\n```bash\npip install fastapi-redis-cache-reborn\n```\n\n## Usage\n\n### Redis Server\n\nYou will need access to a Redis server. If you don't have one running locally,\nyou can use `Docker` or even a cloud service like\n[Redis Cloud](https://redis.com/cloud/overview/) or [AWS\nElastiCache](https://aws.amazon.com/elasticache/redis/).\n\nThere is a `docker-compose-redis-only.yml` file in the root of this repository\nthat you can use to start a Redis server locally. Just run:\n\n```bash\ndocker compose -f docker-compose-redis-only.yml up -d\n```\n\nThis will spin up a Redis server on `localhost:6379`, without any password,\nrunning in the background. You can stop it with:\n\n```bash\ndocker compose -f docker-compose-redis-only.yml down\n```\n\nThe image is based on\n[redis/redis-stack](https://redis.io/docs/install/install-stack/docker/) so also\nincludes [RedisInsight](https://redis.io/docs/connect/insight/) running on port\n`8001` that you can use to inspect the Redis server.\n\n**Note that this is a development server and should not be used in production.**\n\n### Initialize Redis in your FastAPI application\n\nCreate a `FastApiRedisCache` instance when your application starts by defining a\n['lifespan' event handler](\u003chttps://fastapi.tiangolo.com/advanced/events/\u003e) as\nshown below. Replace the `REDIS_SERVER_URL` with the address and port of your\nown Redis server.\n\n```python {linenos=table}\nimport os\n\nfrom contextlib import asynccontextmanager\n\nfrom fastapi import FastAPI, Request, Response\nfrom fastapi_redis_cache import FastApiRedisCache, cache\nfrom sqlalchemy.orm import Session\n\nREDIS_SERVER_URL = \"redis://127.0.0.1:6379\"\n\n@asynccontextmanager\nasync def lifespan(app: FastAPI):\n    redis_cache = FastApiRedisCache()\n    redis_cache.init(\n        host_url=os.environ.get(\"REDIS_URL\", REDIS_SERVER_URL),\n        prefix=\"myapi-cache\",\n        response_header=\"X-MyAPI-Cache\",\n        ignore_arg_types=[Request, Response, Session]\n    )\n    yield\n\napp = FastAPI(title=\"FastAPI Redis Cache Example\",lifespan=lifespan)\n\n# routes and more code\n\n```\n\nAfter creating the instance, you must call the `init` method. The only required\nargument for this method is the URL for the Redis database (`host_url`). All\nother arguments are optional:\n\n- `host_url` (`str`) \u0026mdash; Redis database URL. (_**Required**_)\n- `prefix` (`str`) \u0026mdash; Prefix to add to every cache key stored in the Redis\n  database. (_Optional_, defaults to `None`)\n- `response_header` (`str`) \u0026mdash; Name of the custom header field used to\n  identify cache hits/misses. (_Optional_, defaults to `X-FastAPI-Cache`)\n- `ignore_arg_types` (`List[Type[object]]`) \u0026mdash; Cache keys are created (in\n  part) by combining the name and value of each argument used to invoke a path\n  operation function. If any of the arguments have no effect on the response\n  (such as a `Request` or `Response` object), including their type in this list\n  will ignore those arguments when the key is created. (_Optional_, defaults to\n  `[Request, Response]`)\n  - The example shown here includes the `sqlalchemy.orm.Session` type, if your\n    project uses SQLAlchemy as a dependency ([as demonstrated in the FastAPI\n    docs](https://fastapi.tiangolo.com/tutorial/sql-databases/)), you should\n    include `Session` in `ignore_arg_types` in order for cache keys to be\n    created correctly ([More info][cache-keys]).\n\n### `@cache` Decorator\n\nDecorating a path function with `@cache` enables caching for the endpoint.\n**Response data is only cached for `GET` operations**, decorating path functions\nfor other HTTP method types will have no effect. If no arguments are provided,\nresponses will be set to expire after one year, which, historically, is the\ncorrect way to mark data that \"never expires\".\n\n```python\n# WILL NOT be cached\n@app.get(\"/data_no_cache\")\ndef get_data():\n    return {\"success\": True, \"message\": \"this data is not cacheable, for... you know, reasons\"}\n\n# Will be cached for one year\n@app.get(\"/immutable_data\")\n@cache()\nasync def get_immutable_data():\n    return {\"success\": True, \"message\": \"this data can be cached indefinitely\"}\n```\n\nResponse data for the API endpoint at `/immutable_data` will be cached by the\nRedis server. Log messages are written to standard output whenever a response is\nadded to or retrieved from the cache.\n\nIn most situations, response data must expire in a much shorter period of time\nthan one year. Using the `expire` parameter, You can specify the number of\nseconds before data is deleted:\n\n```python\n# Will be cached for thirty seconds\n@app.get(\"/dynamic_data\")\n@cache(expire=30)\ndef get_dynamic_data(request: Request, response: Response):\n    return {\"success\": True, \"message\": \"this data should only be cached temporarily\"}\n```\n\n\u003e [!NOTE]\n\u003e `expire` can be either an `int` value or `timedelta` object. When\n\u003e the TTL is very short (like the example above) this results in a decorator\n\u003e that is expressive and requires minimal effort to parse visually. For\n\u003e durations an hour or longer (e.g., `@cache(expire=86400)`), IMHO, using a\n\u003e `timedelta` object is much easier to grok\n\u003e (`@cache(expire=timedelta(days=1))`).\n\n#### Pre-defined Lifetimes\n\nThe decorators listed below define several common durations and can be used in\nplace of the `@cache` decorator:\n\n- `@cache_one_minute`\n- `@cache_one_hour`\n- `@cache_one_day`\n- `@cache_one_week`\n- `@cache_one_month`\n- `@cache_one_year`\n\nFor example, instead of `@cache(expire=timedelta(days=1))`, you could use:\n\n```python\nfrom fastapi_redis_cache import cache_one_day\n\n@app.get(\"/cache_one_day\")\n@cache_one_day()\ndef partial_cache_one_day(response: Response):\n    return {\"success\": True, \"message\": \"this data should be cached for 24 hours\"}\n```\n\nIf a duration that you would like to use throughout your project is missing from\nthe list, you can easily create your own:\n\n```python\nfrom functools import partial, update_wrapper\nfrom fastapi_redis_cache import cache\n\nONE_HOUR_IN_SECONDS = 3600\n\ncache_two_hours = partial(cache, expire=ONE_HOUR_IN_SECONDS * 2)\nupdate_wrapper(cache_two_hours, cache)\n```\n\nThen, simply import `cache_two_hours` and use it to decorate your API endpoint\npath functions:\n\n```python\n@app.get(\"/cache_two_hours\")\n@cache_two_hours()\ndef partial_cache_two_hours(response: Response):\n    return {\"success\": True, \"message\": \"this data should be cached for two hours\"}\n```\n\n\u003e [!TIP]\n\u003e Please read the full documentation on the [website][website] for more\n\u003e information on the `@cache` decorator and the pre-defined lifetimes.\n\u003e There is also a section on [cache keys][cache-keys] that explains how the\n\u003e cache keys are generated and how to use them properly.\n\n## Questions/Contributions\n\nIf you have any questions, please open an issue. Any suggestions and\ncontributions are absolutely welcome. This is still a very small and young\nproject, I plan on adding a feature roadmap and further documentation in the\nnear future.\n\n[website]: https://seapagan.github.io/fastapi-redis-cache-reborn/\n[cache-keys]: https://seapagan.github.io/fastapi-redis-cache-reborn/usage/#cache-keys\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fseapagan%2Ffastapi-redis-cache-reborn","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fseapagan%2Ffastapi-redis-cache-reborn","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fseapagan%2Ffastapi-redis-cache-reborn/lists"}