Skip to content

cache_middleware

from pulsefire.middlewares import cache_middleware

Cache middleware.

Recommended to be placed before response deserialization middlewares.

Example:

cache = MemoryCache()
cache_middleware(cache, [
    (lambda inv: inv.invoker.__name__ == "get_lol_v1_champion", 3600),
    (lambda inv: inv.invoker.__name__ ..., float("inf")), # cache indefinitely.
    (lambda inv: inv.url ..., 3600),
    (lambda inv: inv.params ..., 3600),
])

Parameters:

Name Type Description Default
cache BaseCache

Cache instance.

required
rules list[tuple[Callable[[Invocation], bool], float]]

Cache rules, defined by a list of (condition, ttl).

required
Source code in pulsefire/middlewares.py
def cache_middleware(cache: BaseCache, rules: list[tuple[Callable[[Invocation], bool], float]]):
    """Cache middleware.

    Recommended to be placed before response deserialization middlewares.

    Example:
    ```python
    cache = MemoryCache()
    cache_middleware(cache, [
        (lambda inv: inv.invoker.__name__ == "get_lol_v1_champion", 3600),
        (lambda inv: inv.invoker.__name__ ..., float("inf")), # cache indefinitely.
        (lambda inv: inv.url ..., 3600),
        (lambda inv: inv.params ..., 3600),
    ])
    ```

    Parameters:
        cache: Cache instance.
        rules: Cache rules, defined by a list of (condition, ttl).
    """

    rules.append((lambda _: True, 0)) # Add default

    def constructor(next: MiddlewareCallable):

        async def middleware(invocation: Invocation):
            key = f"{invocation.method} {invocation.url}"
            for cond, ttl in rules:
                if not cond(invocation):
                    continue
                try:
                    value = await cache.get(key)
                except KeyError:
                    value = await next(invocation)
                    await cache.set(key, value, ttl)
                return value
            raise RuntimeError("rules out of range")

        return middleware

    return constructor