Git Product home page Git Product logo

Comments (1)

kishvanchee avatar kishvanchee commented on June 12, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.