flickrapi
flickrapi copied to clipboard
MemcachedKeyCharacterError: Control/space characters not allowed
When trying to use this package with memcached, I get the following error:
memcache.MemcachedKeyCharacterError: Control/space characters not allowed (key=b":1:{'user_id': '86466248@N00', 'extras': 'url_l,url_m', 'per_page': 500, 'page': 1, 'method': 'flickr.favorites.getList', 'format': 'json', 'nojsoncallback': 1}")
It looks like the issue is the space character in the key name, and this seems similar to https://github.com/sybrenstuvel/flickrapi/issues/29
I didn't see any resolution in that issue, but the suggestion of replacing the space character with a $
or similar character seems sound to me.
Any chance that this is a quick fix?
Thanks very much! I've enjoyed using this package so far: it's helped me get up and running quickly!
After spending some time looking in the django and flickrapi source code, I came up with the following solution/workaround. I had to do quite a lot of googling to get memcached to work with this package, so hopefully this is helpful for someone else:
from django.core.cache import cache
from django.conf import settings
def make_memcached_key(key, key_prefix, version):
# Similar to the default key function, except that we translate the key first. The FlickrAPI package
# uses objects as keys, then calls repr() on it to translate it into a string. This means the string will have
# spaces in the name, but memcached won't accept spaces in the key names, so we have to replace those
translated_key = repr(key).replace(' ', '$')
return '%s:%s:%s' % (key_prefix, version, translated_key)
settings.configure(CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': memcached_location,
'KEY_FUNCTION' : make_memcached_key,
}
})
and then I was able to use the django cache as it said in the flickrapi documentation:
flickr = flickrapi.FlickrAPI(flickr_api_key, flickr_api_secret, format='parsed-json', cache=True)
flickr.cache = cache
The crux of the issue seems to be that flickrapi passes a dictionary as the key, whereas django expects a string. This workaround solves my issue, but I wanted to post it here in case it's helpful for someone else.