|
1 |
| -# `fastapi-redis-cache` |
| 1 | +## `fastapi-redis-cache` |
2 | 2 |
|
3 |
| -[](https://badge.fury.io/py/fastapi-redis-cache)    [](https://codeclimate.com/github/a-luna/fastapi-redis-cache/maintainability) [](https://codeclimate.com/github/a-luna/fastapi-redis-cache/test_coverage) |
| 3 | +[](https://badge.fury.io/py/fastapi-redis-cache) |
| 4 | + |
| 5 | + |
| 6 | + |
| 7 | +[](https://codeclimate.com/github/a-luna/fastapi-redis-cache/maintainability) |
| 8 | +[](https://codeclimate.com/github/a-luna/fastapi-redis-cache/test_coverage) |
| 9 | + |
| 10 | +### Features |
4 | 11 |
|
5 | 12 | - Cache response data for async and non-async path operation functions.
|
6 |
| - - Response data is only cached for `GET` operations, applying `@cache` decorator to path functions for other HTTP method types will have no effect. |
7 | 13 | - Lifetime of cached data is configured separately for each API endpoint.
|
8 |
| -- Requests with `Cache-Control` header containing `no-cache` or `no-store`are handled correctly (all caching behavior is disabled). |
| 14 | +- Requests with `Cache-Control` header containing `no-cache` or `no-store` are handled correctly (all caching behavior is disabled). |
9 | 15 | - Requests with `If-None-Match` header will receive a response with status `304 NOT MODIFIED` if `ETag` for requested resource matches header value.
|
10 | 16 |
|
11 |
| -## Installation |
| 17 | +### Installation |
12 | 18 |
|
13 | 19 | `pip install fastapi-redis-cache`
|
14 | 20 |
|
15 |
| -## Usage |
| 21 | +### Usage |
16 | 22 |
|
17 |
| -### Initialize Redis |
| 23 | +#### Initialize Redis |
18 | 24 |
|
19 | 25 | Create a `FastApiRedisCache` instance when your application starts by [defining an event handler for the `"startup"` event](https://fastapi.tiangolo.com/advanced/events/) as shown below:
|
20 | 26 |
|
@@ -48,9 +54,9 @@ After creating the instance, you must call the `init` method. The only required
|
48 | 54 | - `ignore_arg_types` (`List[Type[object]]`) — Cache keys are created (in part) by combining the name and value of each argument used to invoke a path operation function. If any of the arguments have no effect on the response (such as a `Request` or `Response` object), including their type in this list will ignore those arguments when the key is created. (_Optional_, defaults to `[Request, Response]`)
|
49 | 55 | - The example shown here includes the `sqlalchemy.orm.Session` type, if your project uses SQLAlchemy as a dependency ([as demonstrated in the FastAPI docs](https://fastapi.tiangolo.com/tutorial/sql-databases/)), you should include `Session` in `ignore_arg_types` in order for cache keys to be created correctly ([More info](#cache-keys)).
|
50 | 56 |
|
51 |
| -### `@cache` Decorator |
| 57 | +#### `@cache` Decorator |
52 | 58 |
|
53 |
| -Decorating a path function with `@cache` enables caching for the endpoint. If no arguments are provided, responses will be set to expire after 1 year, which, historically, is the correct way to mark data that "never expires". |
| 59 | +Decorating a path function with `@cache` enables caching for the endpoint. **Response data is only cached for `GET` operations**, decorating path functions for other HTTP method types will have no effect. If no arguments are provided, responses will be set to expire after 1 year, which, historically, is the correct way to mark data that "never expires". |
54 | 60 |
|
55 | 61 | ```python
|
56 | 62 | # WILL NOT be cached
|
@@ -87,7 +93,7 @@ def get_dynamic_data(request: Request, response: Response):
|
87 | 93 | return {"success": True, "message": "this data should only be cached temporarily"}
|
88 | 94 | ```
|
89 | 95 |
|
90 |
| -### Response Headers |
| 96 | +#### Response Headers |
91 | 97 |
|
92 | 98 | Below is the HTTP response for the `/dynamic_data` endpoint. The `cache-control`, `etag`, `expires`, and `x-fastapi-cache` headers are added because of the `@cache` decorator:
|
93 | 99 |
|
@@ -117,9 +123,9 @@ If this request was made from a web browser, and a request for the same resource
|
117 | 123 |
|
118 | 124 | Similarly, if a request is sent with the `cache-control` header containing `no-cache` or `no-store`, all caching behavior will be disabled and the response will be generated and sent as if endpoint had not been decorated with `@cache`.
|
119 | 125 |
|
120 |
| -### Cache Keys |
| 126 | +#### Cache Keys |
121 | 127 |
|
122 |
| -Consider the `/get_item` API route defined below. This is the first path function we have seen where the response depends on the value of an argument (`user_id: int`). This is a typical CRUD operation where `user_id` is used to retrieve a `User` record from a SQLAlchemy database. |
| 128 | +Consider the `/get_user` API route defined below. This is the first path function we have seen where the response depends on the value of an argument (`user_id: int`). This is a typical CRUD operation where `user_id` is used to retrieve a `User` record from a SQLAlchemy database. |
123 | 129 |
|
124 | 130 | ```python
|
125 | 131 | @app.get("/get_user", response_model=schemas.User)
|
@@ -177,6 +183,6 @@ INFO:fastapi_redis_cache.client: 04/23/2021 07:04:12 PM | KEY_FOUND_IN_CACHE: ke
|
177 | 183 | INFO: 127.0.0.1:50761 - "GET /get_user?user_id=1 HTTP/1.1" 200 OK
|
178 | 184 | ```
|
179 | 185 |
|
180 |
| -## Questions/Contributions |
| 186 | +### Questions/Contributions |
181 | 187 |
|
182 | 188 | If you have any questions, please open an issue. Any suggestions and contributions are absolutely welcome. This is still a very small and young project, I plan on adding a feature roadmap and further documentation in the near future.
|
0 commit comments