If anyone has time (I certainly don't !) I'd like to suggest a Flask-Cache extension - I have this requirement in a current project that I'm sure others have as well. 1. A Cache() object you can initialize with Flask, as cache = Cache(app) or cache.init_app(app). This would have simple get/set methods and would use the underlying werkzeug cache API. 2. A @cache.memoize decorator for caching a function result (see example in Flask docs) 3. A way of caching all views, with certain exceptions, e.g. HTTP POSTs or a query string, probably using before/after request functions. 4. A way of overriding the above with additional app-specific conditions, perhaps a @cache.cache_on decorator - for example cache only if users are logged out. Per-view rules with e.g. @cache.always or @cache.never. 5. Use of config e.g. TESTING = NullCache, DEBUG= SimpleCache, various memcached settings etc.
On 07/25/2010 01:33 PM, Dan Jacob wrote: > If anyone has time (I certainly don't !) I'd like to suggest a > Flask-Cache extension - I have this requirement in a current project > that I'm sure others have as well. I have been working on one of these for a while, but right now I'm trying to get my released extensions approved before I finish this one. I should be able to finish it soon, though. > 1. A Cache() object you can initialize with Flask, as cache = > Cache(app) or cache.init_app(app). This would have simple get/set > methods and would use the underlying werkzeug cache API. Mine uses a 'setup_cache', which attaches the cache to an application. 'flaskext.cache.cache' is a LocalProxy to the current app's cache instance, so you can do: from flaskext.cache import cache cache.get('my-view') > 2. A @cache.memoize decorator for caching a function result (see > example in Flask docs) I have that. It also takes a 'variant' keyword argument (or something similarly named), so you can pass in 'variant=lambda: getattr(g.user, "id")' and have it cache separately for each user ID. > 3. A way of caching all views, with certain exceptions, e.g. HTTP > POSTs or a query string, probably using before/after request > functions. I'm not really planning to put that in. Explicit is better than implicit. > 4. A way of overriding the above with additional app-specific > conditions, perhaps a @cache.cache_on decorator - for example cache > only if users are logged out. Per-view rules with e.g. @cache.always > or @cache.never. If #3 isn't in, then this won't work. However, what might be interesting is an 'unless' keyword argument that will *always* execute the view if 'unless' returns True (i.e. 'unless=lambda: g.user is not None' will always run the view if the user is logged in) > 5. Use of config e.g. TESTING = NullCache, DEBUG= SimpleCache, various > memcached settings etc. Right now there's just CACHE_SYSTEM (the import name of the cache) and CACHE_OPTIONS (keyword arguments to pass to the cache). I don't think it's a good idea to set it to SimpleCache for DEBUG, but the TESTING thing could work. It also includes a 'cache' macro for templates you can do "{% call cache(fragment_name) %}stuff{% endcall %}" with. -- Regards, Matthew "LeafStorm" Frazier http://leafstorm.us/
On 25 July 2010 22:21, LeafStorm <leafstormrush@gmail.com> wrote: > On 07/25/2010 01:33 PM, Dan Jacob wrote: >> If anyone has time (I certainly don't !) I'd like to suggest a >> Flask-Cache extension - I have this requirement in a current project >> that I'm sure others have as well. > > I have been working on one of these for a while, but right now I'm > trying to get my released extensions approved before I finish this one. > I should be able to finish it soon, though. > >> 1. A Cache() object you can initialize with Flask, as cache = >> Cache(app) or cache.init_app(app). This would have simple get/set >> methods and would use the underlying werkzeug cache API. > > Mine uses a 'setup_cache', which attaches the cache to an application. > 'flaskext.cache.cache' is a LocalProxy to the current app's cache > instance, so you can do: > "init_app" seems to be an unofficial pattern - doesn't really matter though. > from flaskext.cache import cache > cache.get('my-view') > >> 2. A @cache.memoize decorator for caching a function result (see >> example in Flask docs) > > I have that. It also takes a 'variant' keyword argument (or something > similarly named), so you can pass in 'variant=lambda: getattr(g.user, > "id")' and have it cache separately for each user ID. > >> 3. A way of caching all views, with certain exceptions, e.g. HTTP >> POSTs or a query string, probably using before/after request >> functions. > > I'm not really planning to put that in. Explicit is better than implicit. > It is useful to have a blanket default cache for your site, especially large sites. Having a CACHE_ALL setting would be handy. However I do see your point. >> 4. A way of overriding the above with additional app-specific >> conditions, perhaps a @cache.cache_on decorator - for example cache >> only if users are logged out. Per-view rules with e.g. @cache.always >> or @cache.never. > > If #3 isn't in, then this won't work. However, what might be interesting > is an 'unless' keyword argument that will *always* execute the view if > 'unless' returns True (i.e. 'unless=lambda: g.user is not None' will > always run the view if the user is logged in) > You might want a variation on @memoize - I'm not sure a Response can be easily cached/pickled. >> 5. Use of config e.g. TESTING = NullCache, DEBUG= SimpleCache, various >> memcached settings etc. > > Right now there's just CACHE_SYSTEM (the import name of the cache) and > CACHE_OPTIONS (keyword arguments to pass to the cache). I don't think > it's a good idea to set it to SimpleCache for DEBUG, but the TESTING > thing could work. > SimpleCache could be the default (unless you are in unit tests) and memcached (or other caches) only used if the relevant config settings are present. > It also includes a 'cache' macro for templates you can do "{% call > cache(fragment_name) %}stuff{% endcall %}" with. > That would be handy. > -- > Regards, Matthew "LeafStorm" Frazier > http://leafstorm.us/ >