long2ice / fastapi-cache

fastapi-cache is a tool to cache fastapi response and function result, with backends support redis and memcached.
https://github.com/long2ice/fastapi-cache
Apache License 2.0
1.37k stars 167 forks source link

Cache support vercel fastapi 0.95.2 #177

Open srcortez45 opened 1 year ago

srcortez45 commented 1 year ago

hello, im trying to setup fastapi with cache support in vercel but i get this error

[ERROR] AssertionError: You must call init first! Traceback (most recent call last):   File "/var/task/vchandlerpython.py", line 305, in vc_handler     response = asgi_cycle(vc_module.app, body)   File "/var/task/vchandlerpython.py", line 208, in call     loop.run_until_complete(asgi_task)   File "/var/lang/lib/python3.9/asyncio/base_events.py", line 647, in run_until_complete     return future.result()   File "/var/task/fastapi/applications.py", line 276, in call     await super().call(scope, receive, send)   File "/var/task/starlette/applications.py", line 122, in call     await self.middleware_stack(scope, receive, send)   File "/var/task/starlette/middleware/errors.py", line 184, in call     raise exc   File "/var/task/starlette/middleware/errors.py", line 162, in call     await self.app(scope, receive, _send)   File "/var/task/starlette/middleware/gzip.py", line 26, in call     await self.app(scope, receive, send)   File "/var/task/starlette/middleware/base.py", line 108, in call     response = await self.dispatch_func(request, call_next)   File "/var/task/app/init.py", line 57, in some_middleware     response = await call_next(request)   File "/var/task/starlette/middleware/base.py", line 84, in call_next     raise app_exc   File "/var/task/starlette/middleware/base.py", line 70, in coro     await self.app(scope, receive_or_disconnect, send_no_error)   File "/var/task/starlette/middleware/sessions.py", line 86, in call     await self.app(scope, receive, send_wrapper)   File "/var/task/starlette/middleware/base.py", line 108, in call     response = await self.dispatch_func(request, call_next)   File "/var/task/app/init.py", line 46, in add_process_time_header     response = await call_next(request)   File "/var/task/starlette/middleware/base.py", line 84, in call_next     raise app_exc   File "/var/task/starlette/middleware/base.py", line 70, in coro     await self.app(scope, receive_or_disconnect, send_no_error)   File "/var/task/starlette/middleware/exceptions.py", line 79, in call     raise exc   File "/var/task/starlette/middleware/exceptions.py", line 68, in call     await self.app(scope, receive, sender)   File "/var/task/fastapi/middleware/asyncexitstack.py", line 21, in call     raise e   File "/var/task/fastapi/middleware/asyncexitstack.py", line 18, in call     await self.app(scope, receive, send)   File "/var/task/starlette/routing.py", line 718, in call     await route.handle(scope, receive, send)   File "/var/task/starlette/routing.py", line 276, in handle     await self.app(scope, receive, send)   File "/var/task/starlette/routing.py", line 66, in app     response = await func(request)   File "/var/task/fastapi/routing.py", line 237, in app     raw_response = await run_endpoint_function(   File "/var/task/fastapi/routing.py", line 163, in run_endpoint_function     return await dependant.call(**values)   File "/var/task/fastapi_cache/decorator.py", line 113, in inner     coder = coder or FastAPICache.get_coder()   File "/var/task/fastapi_cache/init__.py", line 63, in get_coder     assert cls._coder, "You must call init first!" # nosec: B101

this is the code


@asynccontextmanager
async def lifespan(app: FastAPI):
    print('starting db session')
    redis = aioredis.from_url( url=cnf.REDIS,
                               encoding="utf8", 
                               decode_responses=True)
    FastAPICache.init(RedisBackend(redis), prefix="fastapi-cache", coder=JsonCoder)

    yield
    await redis.close()
    print('shutdown db session')

def get_application():

    app = FastAPI(
        title = cnf.TITLE,
        description = cnf.APP_CONFIG.DESCRIPTION,
        version = cnf.APP_CONFIG.VERSION,
        openapi_tags=cnf.APP_CONFIG.tags_metadata,
        openapi_url = cnf.openapi_url,
        docs_url=cnf.docs_url,
        lifespan=lifespan
        )
    app.include_router(router=user_router,
                       prefix='/session')
    return app

app = get_application()

@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
    start_time = time.time()
    response = await call_next(request)
    process_time = time.time() - start_time
    response.headers["X-Process-Time"] = str(process_time)
    return response

app.add_middleware(SessionMiddleware, secret_key="some-random-string", max_age=None)

@app.middleware("http")
async def some_middleware(request: Request, call_next):
    response = await call_next(request)
    session = request.cookies.get('session')
    if session:
        response.set_cookie(key='session',
                            value=request.cookies.get('session'),
                            httponly=True)
    return response

app.add_middleware(GZipMiddleware, minimum_size=1000)

@app.get("/", tags=["Root"])
@cache(expire=180)
async def read_root():
  return { 
    "message": "Welcome to my notes application, use the /docs route to proceed"
   }

is anything im doing wrong?

Foldren commented 3 months ago

decode_responses=False and remove coder=JsonCoder param