Redis Server Sessions in Python

09.18.2021

Intro

Sessions are usually short lived data, or at least have an expiration date, used to transfer state accross RESTful applications. REST applications are stateless per their spec, yet sometimes we need to pass stateful data accross requests. Request sessions were used a lot before the days of single page applications, but they are still used in mostly application today.

For example, two main use case today are user sessions, where we allow a user to be logged in for a set duration, and OAuth, where we need to track state over a number of requests to log a user into an OAuth server.

For session management, you will need some database abstracted from your restful server so that you can scale the server on different machines. Redis is a great choice for this as it allows for you to easily expire data and is very fast, keeping your request response time quick.

In this article, we will learn how to use Redis to manage user sessions.

Getting Setup

Let's start by creating a folder and initializing our package.

touch express-session-example
cd express-session-example
touch index.py

Install the Require Modules

pip install Flask Flask-Session redis

Creating the Basic Server

Next, open up our index.py file, and add a standard Flask route.

Let's import all the libraries we will use in this tutorial

import redis
from flask import Flask, session

Then create a standard flask route.

app = Flask(__name__)

@app.route('/')
def hello():
    return 'Hello'

if __name__ == '__main__':
    app.run()

Adding Flask Session

Now, let's add the Flask session package and configure our server to use it.

We can add a secret to our app for the session to use. In practice, you will want to generate this securly and randomly. Then we can update our hello world route to use the session object from flask to set an object. If you visit the url the first time the session will not exist, but visit the second time and you the session will be printed.

import redis
from flask import Flask, session

app = Flask(__name__)
app.secret_key = 'GENERATE_A_SECRET_THEN_PLACE_HERE'

@app.route('/')
def hello():
    if 'code' in session:
      print(session['code'])
    session['code'] = 'my-code'

    return 'Hello'

if __name__ == '__main__':
    app.run()

Adding in Redis

Now that we have the basic session set up, we can connect our session config to redis to store session information. The benfit to this is that if your server restarts or you scale horitzontally, the sessions will be persisted and reused when you come back online.

We can replace the session code above with the following. This will allow us to store session data in our redis server instead.

import redis
from flask import Flask, session

app = Flask(__name__)

app.secret_key = 'GENERATE_A_SECRET_THEN_PLACE_HERE'

# Configure Redis for storing the session data on the server-side
app.config['SESSION_TYPE'] = 'redis'
app.config['SESSION_REDIS'] = redis.from_url('redis://localhost:6379')

@app.route('/')
def hello():
    if 'code' in session:
      print(session['code'])
    session['code'] = 'my-code'

    return 'Hello'


if __name__ == '__main__':
    app.run()

If you don't have redis ready, you can create a new file called docker-compose.yml and put the following code in.

version: "3.2"
services:
  redis:
    image: "redis:alpine"
    command: redis-server
    ports:
      - "6379:6379"
    volumes:
      - $PWD/redis-data:/var/lib/redis
      - $PWD/redis.conf:/usr/local/etc/redis/redis.conf
    environment:
      - REDIS_REPLICATION_MODE=master

Then you can start the redis instance by docker-compose up