Way to dynamically disable/deactivate caching functionality?
Description
I'm having an issue where I want to debug certain endpoints locally. But since those responses are cached, my breakpoints are never getting reached.
What's the best way to temporarily disable if I want to set to development/debug mode?
What I've tried
I added this condition to only add FastApiCache if in production:
@app.on_event("startup")
async def startup():
"""Start up FastAPI server"""
app.state.graph = TccmGraph()
app.state.graph.connect()
redis = aioredis.from_url(
url=get_settings().redis_url,
encoding="utf8",
decode_responses=True)
if get_settings().environment_name == 'production':
FastAPICache.init(
backend=RedisBackend(redis),
prefix="fastapi-cache")
But I'm getting the following error, expectedly:
File "/Users/joeflack4/virtualenvs/ccdh-terminology-service/lib/python3.9/site-packages/fastapi_cache/__init__.py", line 35, in get_backend
assert cls._backend, "You must call init first!" # nosec: B101
AssertionError: You must call init first!
Possible solutions
What's the best way to handle this?
- Create my own
cachedecorator wrapper w/ custom logic around FastAPI's? - Initialize
FastAPICache.init()but do it differently?
That's actual a scene, how other frameworks solve that?
My workaround
I think that it would be good if the framework (FastApi-Cache2) had a native solution for this, but here's what I did to solve this for now:
app.py: Left it the normal way
@app.on_event("startup")
async def startup():
"""Start up FastAPI server"""
app.state.graph = TccmGraph()
app.state.graph.connect()
redis = aioredis.from_url(
url=get_settings().redis_url,
encoding="utf8",
decode_responses=True)
FastAPICache.init(
backend=RedisBackend(redis),
prefix="fastapi-cache")
New file (called "ccdh.api.cache" in my app)
"""Wrapper around the FastApiCache-2 library"""
from fastapi_cache.decorator import cache
from ccdh.config import get_settings
def nocache(*args, **kwargs):
def decorator(func):
return func
return decorator
# I have an .env file, and my get_settings() reads the .env file
if get_settings().environment_name == 'production':
cache = cache
else:
cache = nocache
Import from new file:
# import from wherever you created your new file; in my app, `ccdh.api.cache` is the path
from ccdh.api.cache import cache
@cache() usage remains unchanged
# example of one of our routes:
@router.get('/{model}', response_model=Model, operation_id='get_model', response_model_exclude_none=True,
responses={
"200": {
"links": {
"Entities": {
"operationId": "get_model_entities",
"parameters": {
"model": "$request.path.model"
}
}
}
}
})
@cache() # <---- nothing needs to change here
async def get_model(model: str):
"""Get a single model"""
return Model(name=model)
That's good
This would make a nice example in the documentation at some point.