Recently, I have tried using Redis for my Flask webapp and I have found an interesting use case for it. In this short article I wanted to share it with you.
1. Setting up Redis
First thing that you want to do is to get the latest Redis docker image and run it within your virtual box or on your server. To do that simply type:
sudo docker pull redis:latest
The command above will pull the latest image of the redis server. Now you want to run it and expose its port, so that you can connect from python to it.
sudo docker run -p 6379:6379 redis:latest
This will start the server and expose its ports. If you are running within a virtual box be sure to set its connection to a bridged network, otherwise you will not be able to connect to it. Now that you have a redis server running let us move onto how to use it from python.
2. Setting up python
To use Redis within Python you will need to install redis-py package. To do that simply type:
pip install redis
Now that you have installed a redis client you can start using it. Just create a new client
import contextlib
import redis
REDIS_HOST = 'this will be the hostname of the server on which you are running your Redis instance'
REDIS_PORT = 6379
with contextlib.closing(redis.Redis(REDIS_HOST, REDIS_PORT, db=0)) as r: # Make sure that you will close the connection
r.set('foo', 'bar')
x = r.get('foo')
assert x == 'bar'
3. Use case
Great! Now that you have set up your Redis server and your Python client you will be able to use some more advanced features. I have found that Redis transactions are the most interesting thing with Redis. Mostly because they are so much different from the usual SQL transactions. In Redis the typical approach is to assume optimistically that your operations will succeed.
To make it more concise the first thing you do is register your interest in some variables. You do that through the watch calls. Now Redis will know that you are interested in all of the changes that are made to a certain variable. Then usually you will check whether your condition is met and if it is you will create a multi transaction. This transaction will only describe how you want to update our variable if nothing has changed your variable that you are watching.
If something has changed your variable then you will automatically receive a redis.WatchError Exception. The usual approach to deal with such exception in Redis is to just retry your transaction.
Okay, but how can you use that within your code? It is rather simple, so let us go through this simple example that will show us how to find a variable matching our preference and increment it (we are assuming that increment operation does not exist in Redis...).
def increment_some_var(some_var):
with contextlib.closing(redis.Redis(REDIST_HOST, REDIS_PORT, db=0)) as r:
while True:
pipe = r.pipeline() # Create a pipeline execution
try:
pipe.watch(some_var)
some_var_val = pipe.get(some_var)
if some_condition_happens(some_var):
r.multi() # Register a transaction
r.set(some_var, some_var_val + 1)
r.execute()
break
else:
break # Possibly you want to break if your condition is not fulfilled and return to some default
except redis.WatchError:
continue # This will only happen if someone has modified your variable of interest
finally:
pipe.reset() # This will indicate that you are no longer 'watching' the variable
And that is essentially how you can use Redis within Python. You can always try to run some Lua scripts that are supported within Redis internally, but I would recommend keeping interactions with the database as simple as possible.