Posted by: Eric Hansen
In a recent project I needed an easy-to-use lookup, but cachable, system to store information for periods at a time. I wasn’t really feeling the use of a strictly file-based cache system (i.e.: writing data to a file, reading form it, etc…) as most of the work is already I/O bound as is. A friend of mine then introduced me to Redis, which is basically a memory-cache system that works based on key-value (or name-value) pair.
There’s two benefits for KVP with this project: (1) it’s easy to store and read data without having to worry about handles and such, and (2) with it being a memory-storing cache system it improves the I/O performance of my other tasks, as it only periodically dumps memory contents to a file. This in turn has the added benefit that if the redis server is restarted or stopped for any reason I don’t have to worry about much (if any) data loss. Also, it helps that data thrashing is non-existent now.
There’s a de-facto module for Python called redis-py, which is easily installed using pip (pip install redis-py). Note that this also requires installing the Redis server (for Ubuntu/Debian systems it’s apt-get install redis-server). However, once you have those two things installed using Redis is easy as pie.
What I want to provide in this article, however, is a small wrapper I wrote for redis-py that makes interfacing with it a little (or a lot) easier. Even though the usage of redis-py is pretty easy as is, I felt I could make it a bit easier for myself. The script itself is found here: https://github.com/SecurityForUs/redisr/blob/master/redisr.py (the other Python script is one I wrote to test accessing class variables via decorations).
If you look at the first class you’ll see it’s being used as a decorator in the Redisr class. The reason for this is to simply avoid writing a bunch of if connected_to_redis: [do code] else: return False. The first time @rcheck is called the __init__() method is called, and any time after that __get__() is called instead, which makes this much easier.
The Redis class itself is pretty simple as it really only contains 3 methods: __init__(), save() and load(). The __init__() class initializes a connection to the Redis server (default settings should be good for most), while save() stores a key/value pair in the server, while load() returns the value at a specific key. There’s another two functions, write() and read() that act the same as save() and load(). Lastly, there’s __getitem__(), which is yet again another load(). __getitem__() was added in to this so instead of having to call a method to get a value, just call an overridden operator (i.e.: redis_class['key'] is the same as redis_class.read(‘key’) or redis_class.load(‘key’)).
This really does not do the redis-py module justice if you’re looking to use it for more than a quick caching mechanism. If you’re looking for something to get you started at least, however, you should be just fine with this.