Merge pull request #98 from vvanglro/feat/cache_response_obj

Feat/cache response obj
This commit is contained in:
long2ice
2023-01-11 17:23:47 +08:00
committed by GitHub
6 changed files with 33 additions and 3 deletions

View File

@@ -5,6 +5,10 @@
### 0.2.1 ### 0.2.1
- Support cache jinja2 template response. - Support cache jinja2 template response.
- Support cache `JSONResponse`
- Add `py.typed` file and type hints
- Add TestCase
- Fix cache decorate sync function
- Transparently handle backend connection failures. - Transparently handle backend connection failures.
### 0.2.0 ### 0.2.0

View File

@@ -2,7 +2,7 @@ import pendulum
import uvicorn import uvicorn
from fastapi import FastAPI from fastapi import FastAPI
from starlette.requests import Request from starlette.requests import Request
from starlette.responses import Response from starlette.responses import Response, JSONResponse
from fastapi_cache import FastAPICache from fastapi_cache import FastAPICache
from fastapi_cache.backends.inmemory import InMemoryBackend from fastapi_cache.backends.inmemory import InMemoryBackend
@@ -51,6 +51,12 @@ def sync_me():
return 42 return 42
@app.get("/cache_response_obj")
@cache(namespace="test", expire=5)
async def cache_response_obj():
return JSONResponse({"a": 1})
@app.on_event("startup") @app.on_event("startup")
async def startup(): async def startup():
FastAPICache.init(InMemoryBackend()) FastAPICache.init(InMemoryBackend())

View File

@@ -4,6 +4,7 @@ import pendulum
import redis.asyncio as redis import redis.asyncio as redis
import uvicorn import uvicorn
from fastapi import FastAPI from fastapi import FastAPI
from starlette.responses import JSONResponse
from fastapi.responses import HTMLResponse from fastapi.responses import HTMLResponse
from fastapi.staticfiles import StaticFiles from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates from fastapi.templating import Jinja2Templates
@@ -73,6 +74,12 @@ async def cache_html(request: Request):
return templates.TemplateResponse("index.html", {"request": request, "ret": await get_ret()}) return templates.TemplateResponse("index.html", {"request": request, "ret": await get_ret()})
@app.get("/cache_response_obj")
@cache(namespace="test", expire=5)
async def cache_response_obj():
return JSONResponse({"a": 1})
@app.on_event("startup") @app.on_event("startup")
async def startup(): async def startup():
pool = ConnectionPool.from_url(url="redis://redis") pool = ConnectionPool.from_url(url="redis://redis")

View File

@@ -6,6 +6,7 @@ from typing import Any
import pendulum import pendulum
from fastapi.encoders import jsonable_encoder from fastapi.encoders import jsonable_encoder
from starlette.responses import JSONResponse
from starlette.templating import _TemplateResponse as TemplateResponse from starlette.templating import _TemplateResponse as TemplateResponse
CONVERTERS = { CONVERTERS = {
@@ -51,6 +52,8 @@ class Coder:
class JsonCoder(Coder): class JsonCoder(Coder):
@classmethod @classmethod
def encode(cls, value: Any) -> str: def encode(cls, value: Any) -> str:
if isinstance(value, JSONResponse):
return value.body
return json.dumps(value, cls=JsonEncoder) return json.dumps(value, cls=JsonEncoder)
@classmethod @classmethod

View File

@@ -77,9 +77,9 @@ def cache(
# if the wrapped function does NOT have request or response in its function signature, # if the wrapped function does NOT have request or response in its function signature,
# make sure we don't pass them in as keyword arguments # make sure we don't pass them in as keyword arguments
if not request_param: if not request_param:
kwargs.pop("request") kwargs.pop("request", None)
if not response_param: if not response_param:
kwargs.pop("response") kwargs.pop("response", None)
if inspect.iscoroutinefunction(func): if inspect.iscoroutinefunction(func):
# async, return as is. # async, return as is.

View File

@@ -57,3 +57,13 @@ def test_sync() -> None:
with TestClient(app) as client: with TestClient(app) as client:
response = client.get("/sync-me") response = client.get("/sync-me")
assert response.json() == 42 assert response.json() == 42
def test_cache_response_obj() -> None:
with TestClient(app) as client:
cache_response = client.get("cache_response_obj")
assert cache_response.json() == {"a": 1}
get_cache_response = client.get("cache_response_obj")
assert get_cache_response.json() == {"a": 1}
assert get_cache_response.headers.get("cache-control")
assert get_cache_response.headers.get("etag")