librelist archives

« back to archive

Request for extension: Flask-Cache

Request for extension: Flask-Cache

From:
Dan Jacob
Date:
2010-07-25 @ 17:33
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.

Re: [flask] Request for extension: Flask-Cache

From:
LeafStorm
Date:
2010-07-25 @ 21:21
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/

Re: [flask] Request for extension: Flask-Cache

From:
Dan Jacob
Date:
2010-07-25 @ 21:28
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/
>