Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flask cache set method throwing KeyError?

In order to cache some data, I am calling cache.set method. However it is throwing KeyError. The error log:

 File "D:\Sample_Project\SomeRouter.py", line 176, in run
    FetchFeed._prepareCache(f_content, cache, _program, _sprint)
  File "D:\Sample_Project\SomeRouter.py", line 197, in _prepareCache
    cache.set(cKey, data[last_index:last_index + MAX_DATA_PER_PAGE])
  File "c:\python\lib\site-packages\flask_caching\__init__.py", line 254, in set
    return self.cache.set(*args, **kwargs)
  File "c:\python\lib\site-packages\flask_caching\__init__.py", line 246, in cache
    return app.extensions["cache"][self]
KeyError: <flask_caching.Cache object at 0x04F9C8D0>

The server module looks like :

cache_type = 'simple' if 'FLASK_ENV' in os.environ and os.environ['FLASK_ENV'] == 'development' else 'uwsgi'
cache = Cache(config={'CACHE_TYPE': cache_type})
app = Flask("MY_PROJECT")
cache.init_app(app)

# some api.route functions
# goes here ....

if __name__ == "__main__":
    with app.app_context():
        cache.clear()
    app.run(host="0.0.0.0")

And SomeRouter module:

from server import cache

@staticmethod
def _prepareCache(data, cache, program):
    total_records = len(data)
    if total_records > 0:
        cKey = FetchFeed \
            ._constructCacheKey(program)
        cache.set(cKey, data)
    else:
        print("data size is empty.")

Note: I have removed unnecessary codes.

I also put breakpoints, and called cache.set(some_key, some_value) in server module itself. It is returning True, but same cache object is throwing KeyError when imported and used in SomeRouter module. Can it be that the way I am importing an object is wrong? I also tried importing the cache object right before using it, but it did not work. Any idea what is going on here?

like image 773
TheLittleNaruto Avatar asked Oct 15 '22 07:10

TheLittleNaruto


1 Answers

The problem was I was accessing cache object outside request context i.e. in "SomeRouter" module, and because of which it was unaware that under which context it is been used.

In server module where request has been received, the cache knows about the app application, but during cache.set(cKey, data) in SomeRouter module, it throws KeyError. This error is justified as mentioned above.

The resolution is to push the application context as below:

from server import app, cache

# Using context
with app.app_context():
    cache.set(cKey, data)

This will push a new application context (using the application of app).

All thanks to Mark Hildreth, for his great answer on context in flask

like image 79
TheLittleNaruto Avatar answered Oct 19 '22 12:10

TheLittleNaruto