Comments (1)
Hey @joelthill I had the same use case. Yes you would have to explicitly update/delete the cache using PUT/DELETE. This is how I modified the code in https://github.com/a-luna/fastapi-redis-cache/blob/main/src/fastapi_redis_cache/cache.py#L46 . I have used Python 3.10 as an example here. If you use earlier versions then you should work with if else
instead of pattern matching with match case
.
client.py
https://github.com/a-luna/fastapi-redis-cache/blob/main/src/fastapi_redis_cache/client.py#L14
ALLOWED_HTTP_TYPES = ["GET", "POST", "PUT", "DELETE"]
router.py
@router.put("/")
@router.delete("/")
@router.get("/")
@cache()
def your_endpoint():
pass
cache.py
def cache(*, expire: Union[int, timedelta] = ONE_YEAR_IN_SECONDS): # type: ignore
"""Enable caching behavior for the decorated function.
Args:
expire (Union[int, timedelta], optional): The number of seconds
from now when the cached response should expire. Defaults to 31,536,000
seconds (i.e., the number of seconds in one year).
"""
def outer_wrapper(func): # type: ignore
@wraps(func)
async def inner_wrapper(*args, **kwargs): # type: ignore # pylint: disable=too-many-return-statements
"""Return cached value if one exists, otherwise evaluate the wrapped function and cache the result."""
func_kwargs = kwargs.copy()
request = func_kwargs.pop("request", None)
response = func_kwargs.pop("response", None)
create_response_directly = not response
if create_response_directly:
response = Response()
redis_cache = FastApiRedisCache()
if redis_cache.not_connected or redis_cache.request_is_not_cacheable(request):
# if the redis client is not connected or request is not cacheable, no caching behavior is performed.
return await get_api_response_async(func, *args, **kwargs)
key = redis_cache.get_cache_key(func, *args, **kwargs)
match request.method:
case "GET" | "POST":
ttl, in_cache = redis_cache.check_cache(key)
if in_cache:
redis_cache.set_response_headers(response, True, deserialize_json(in_cache), ttl)
if redis_cache.requested_resource_not_modified(request, in_cache):
response.status_code = int(HTTPStatus.NOT_MODIFIED)
return (
Response(
content=None,
status_code=response.status_code,
media_type="application/json",
headers=response.headers,
)
if create_response_directly
else response
)
return (
Response(content=in_cache, media_type="application/json", headers=response.headers)
if create_response_directly
else deserialize_json(in_cache)
)
response_data = await get_api_response_async(func, *args, **kwargs)
ttl = calculate_ttl(expire)
cached = redis_cache.add_to_cache(key, response_data, ttl)
if cached:
redis_cache.set_response_headers(
response,
cache_hit=False,
response_data=response_data,
ttl=ttl,
)
return (
Response(
content=serialize_json(response_data),
media_type="application/json",
headers=response.headers,
)
if create_response_directly
else response_data
)
return response_data
case "PUT":
redis_cache.delete_from_cache(key)
response_data = await get_api_response_async(func, *args, **kwargs)
ttl = calculate_ttl(expire)
_ = redis_cache.add_to_cache(key, response_data, ttl)
return
case "DELETE":
_ = redis_cache.delete_from_cache(key)
return
case _:
return Response(
content="Invalid method",
status_code=status.HTTP_405_METHOD_NOT_ALLOWED,
media_type="application/json",
)
return inner_wrapper
return outer_wrapper
from fastapi-redis-cache.
Related Issues (20)
- eTag generation should be optional and configured via a global setting AND a setting per-endpoint
- cache-control: no-cache behavior is wrong HOT 1
- user can add must-revalidate directive to responses
- add support for if-modified-since directive
- ttl expired -> request contains eTag/last-mod -> current behavior is wrong
- feature: provide method on `FastApiRedisCache` object that allows user to delete single cache items by key HOT 1
- Object of type <class '...'> is not JSON-serializable HOT 3
- Nothing being cached HOT 2
- coroutine '<method that is cached>' was never awaited HOT 1
- Use cache() decorator outside of fastapi HOT 3
- How can I cache POST requests? HOT 4
- [Question] How to manually expire an entry ? HOT 1
- Add support for authentication to a remote redis HOT 2
- Feature request - async Redis client
- "Too much data for declared Content-Length" error when activating caching HOT 5
- Can't Cache List of serialized data HOT 1
- add async support for redis HOT 1
- @cache Decorator Not Working
- A Rebuild Maybe ?! ....
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from fastapi-redis-cache.