Build the future of communications.
Start building for free

Choose Your Own Adventure Presentations: Wizard Mode Part 1 of 3


You’ve coded your way through the harrowing challenges of the first Choose Your Own Adventure Presentations tutorial. A sign lies in the road ahead. “PyCon has summoned you to give a Choose Your Own Adventure talk in Montreal!” it reads.


How do you proceed? If you choose to run from the PyCon challenge, close the browser window now. If you accept the challenge, prepare yourself for the dangers ahead with the new Wizard Mode functionality and continuing reading this blog post.


You’re still here, adventurer! Let’s get to work. In this series of three blog posts we’re going to expand the Choose Your Own Adventure Presentations application with new a Wizard Mode. If you haven’t yet worked through the original blog post I highly recommend doing that before working through this series. The section below named “A Clean Starting Point” will get you set up for this tutorial if you’ve already gone through the original Choose Your Own Adventure Presentations post and just need a fresh copy of the code.

What’s this mysterious Wizard Mode we’re building? Think of it as an administrative interface that grants you, the presenting wizard, with new magical powers to control your presentations and how the audience can vote for story choices. The interface will only be accessible by authorized wizards through the sign-in page which will look like the following screenshot.


Once you’re inside the application you’ll be able to manage one or more Choose Your Own Adventure Presentations with a simple screen like this one:


As we go about building our new Wizard Mode you’ll learn about Flask form handling, WebSockets and how to persist presentation data to a PostgreSQL database.

There are three posts in this tutorial series where we will incrementally build out functionality:

  1. Wizards Only: this blog post, where we’ll create a section of the application only authorized wizards can access
  2. Even Wizards Need Web Forms: the next blog post where we expand the wizard only pages to control our presentations
  3. Voting with a Wand, or Smartphone: our third and final post where we add a new magical trick to our presentations – voting via web browser when poor cell service prevents SMS voting

At the end of each post we’ll be able to test what we just built to make sure it’s working properly. If something goes wrong while you’re working through the tutorial, the Git tag tutorial-step-4 tag has the end result for code written in this post.

Let’s get to work!

What We’ll Need

We’ll continue using open source code to build our project including the existing Choose Your Own Adventure Presentations code base, PostgreSQL and several additional Python libraries. Don’t worry about downloading anything just yet – we will grab these tools throughout the tutorial. This list is just so you know ahead of time what’ll be installed along the way:

Finally, time to roll up the magical cloak sleeves and dive into coding.

A Clean Starting Point

If you just worked through the original Choose Your Own Adventure Presentation blog post and have your code ready then you can skip this section and go to “Wizards Only”.

Clone a copy of the Git repository of the code from GitHub:

git clone

Change into the directory of our newly cloned repository.

cd choose-your-own-adventure-presentations

Next, the code we need is found in the tutorial-step-3 tag, so we’ll create a new Git branch with that code to work from.

git checkout -b tutorial tags/tutorial-step-3

Create a virtualenv that will hold our Python dependencies with the following commands. If you already have a directory where you keep your virtualenvs, you can skip the first step and place your new virtualenv in that existing directory.

mkdir ~/Envs/

virtualenv ~/Envs/cyoa

source ~/Envs/cyoa/bin/activate

When you enter the last of those commands above your prompt should change to look something like this:


That prompt means we’re ready to install our dependencies into our new virtualenv using pip:

pip install -r requirements.txt

Finally, there are several environment variables that need to be set so our application runs properly. These variables can be found in the cyoa/ file. Here’s a rundown of what each of these environment variables is for:

  1. DEBUG – True or False for whether Flask should display error messages if something goes wrong
  2. SECRET_KEY – a long key that should be kept secret
  3. REDIS_SERVER – in this case likely to be localhost or wherever Redis is running
  4. REDIS_PORT – generally set to 6379 for the default Redis port
  5. REDIS_DB – set to 0
  6. TWILIO_ACCOUNT_SID – found on your Twilio account dashboard
  7. TWILIO_AUTH_TOKEN – also found on your Twilio account dashboard
  8. TWILIO_NUMBER – a number you’ve purchased on Twilio

Setting up environment variables depends on your operating system. Here are guides for every major operating system, whether you’re using Ubuntu Linux, Mac OS X or Windows.

Great! Now our code and environment is ready to roll for the rest of the tutorial. Let’s write some new Python code.

Wizards Only

We’re going to create the wizard’s panel to control multiple presentations and how our audience can interact with them. First though we need a way to sort wizards from non-wizards in the form of a sign-in screen.

We’re going to use four new Python code libraries in this post so let’s get those added to our project. These new libraries are highlighted below. Update the requirements.txt file so it matches the following code.






Make sure to active your project’s virtualenv and install the new dependencies with pip using these two steps:

source ~/Envs/cyoa/bin/activate

pip install -r requirements.txt

With our new dependencies in place we can create our Wizards Only sign-in page.

Create a new file named within the cyoa/ subdirectory to store information about wizards. The file should have the following contents:

from flask.ext.login import UserMixin
from import generate_password_hash, check_password_hash

from . import db

class Wizard(UserMixin, db.Model):
        Represents a wizard who can access special parts of the application.
    __tablename__ = 'wizards'
    id = db.Column(db.Integer, primary_key=True)
    wizard_name = db.Column(db.String(64), unique=True, index=True)
    password_hash = db.Column(db.String(128))

    def __init__(self, wizard_name, password):
        self.wizard_name = wizard_name
        self.password = password

    def password(self):
        raise AttributeError('password is not readable')

    def password(self, password):
        self.password_hash = generate_password_hash(password)

    def verify_password(self, password):
        return check_password_hash(self.password_hash, password)

    def __repr__(self):
        return '' % self.wizard_name

Next we need to modify the cyoa/ file to create a login manager. The login manager will allow us to control access to wizard settings.

import redis
from flask import Flask
from flask.ext.login import LoginManager
from flask.ext.sqlalchemy import SQLAlchemy
from flask.ext.socketio import SocketIO

app = Flask(__name__, static_url_path='/static')


redis_db = redis.StrictRedis(host=REDIS_SERVER, port=REDIS_PORT, db=REDIS_DB)

socketio = SocketIO(app)
db = SQLAlchemy(app)

login_manager = LoginManager()
login_manager.login_view = 'sign_in'

from . import views
from . import websockets

We need to configure where the database is located in a configuration parameter so our SQLAlchemy database loads properly. Make sure you have PostgreSQL installed on your system. Here are some handy guides and downloads to install PostgreSQL on Ubuntu Linux, Windows and Mac OS X.

Our new configuration variable will reside in our file as highlighted below.

import os

# General Flask app settings
DEBUG = os.environ.get('DEBUG', None)
SECRET_KEY = os.environ.get('SECRET_KEY', None)

# Redis connection
REDIS_SERVER = os.environ.get('REDIS_SERVER', None)
REDIS_PORT = os.environ.get('REDIS_PORT', None)
REDIS_DB = os.environ.get('REDIS_DB', None)

# Twilio API credentials
TWILIO_NUMBER = os.environ.get('TWILIO_NUMBER', None)

In our original Choose Your Own Adventure Presentations blog post we set the other environment variables listed in the above file. Set an environment variable for DATABASE_URL that will be loaded into SQLALCHEMY_DATABASE_URI. The value for this variable will be a URI that points to your running PostgreSQL database. For example, in my local development environment the DATABASE_URL is set to postgresql://matt:password123@localhost/cyoa. And no, that’s not the actual password value I use on my development environment.

We’ll need a form to handle data coming from a wizard. In our application the Flask-WTF library is going to handle form generation and input sanitization. Create a new file named in your cyoa/ subdirectory.

from import Form
from wtforms import StringField, PasswordField, BooleanField, SubmitField, \
                    DateField, IntegerField
from wtforms.validators import Required, Length, Regexp, EqualTo
from wtforms import ValidationError
from .models import Wizard

class LoginForm(Form):
    wizard_name = StringField('Wizard Name',
                              validators=[Required(), Length(1, 32)])
    password = PasswordField('Password', validators=[Required(),
                                                     Length(1, 32)])

    def validate(self):
        if not Form.validate(self):
            return False
        user = Wizard.query.filter_by(wizard_name=self.
        if user is not None and not user.verify_password(
            self.password.errors.append('Incorrect password.')
            return False
        return True

The above code creates a Python representation of the sign-in page form. We add a custom validator within the validate function to ensure the password entered by the user matches what’s stored in the database. If the form input passes the validation function then True is returned and the form processing continues along in our file.

Now in we need a couple of functions to handle signing wizards in and out of their special part of the application.

import cgi
from flask import render_template, abort, request 
from flask import redirect, url_for
from flask.ext.login import login_user, logout_user, login_required, \
from jinja2 import TemplateNotFound
from twilio import twiml
from import TwilioRestClient

from .config import TWILIO_NUMBER
from .forms import LoginForm
from .models import Wizard

from . import app, redis_db, socketio
from . import login_manager

client = TwilioRestClient()

def load_user(userid):
    return Wizard.query.get(int(userid))

@app.route('/<presentation_name>/', methods=['GET'])
def landing(presentation_name):
        return render_template(presentation_name + '.html')
    except TemplateNotFound:

@app.route('/cyoa/twilio/webhook/', methods=['POST'])
def twilio_callback():
    to = request.form.get('To', '')
    from_ = request.form.get('From', '')
    message = request.form.get('Body', '').lower()
    if to == TWILIO_NUMBER:
        socketio.emit('msg', {'div': cgi.escape(message),
                              'val': redis_db.get(message)},
    resp = twiml.Response()
    resp.message("Thanks for your vote!")
    return str(resp)

@app.route('/wizard/', methods=['GET', 'POST'])
def sign_in():
    form = LoginForm()
    if form.validate_on_submit():
        wizard = Wizard.query.filter_by(wizard_name=
        if wizard is not None and wizard.verify_password(
            return redirect(url_for('wizard_landing'))
    return render_template('wizard/sign_in.html', form=form, no_nav=True)

def sign_out():
    return redirect(url_for('sign_in'))

def wizard_landing():
    return render_template('wizard/presentations.html')

What we’re doing in the code above is including our new login manager we created in the file. We then implement a login manager callback function named load_user which reloads a Wizard object from the user ID stored in the session. There are three additional functions:

  • sign_in: authenticate a user as a valid wizard to get into the app
  • sign_out: deauthenticate a logged in wizard’s session
  • wizard_landing: a simple stub page only accessible to wizards to prove the authentication is working properly

We have the code to run the app but there are no templates to render yet. Let’s create those now so we can test this thing out. Under the cyoa/templates/ folder create a new file named base.html with the following template code:

<!DOCTYPE html>
<html lang="en">
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="Matt Makai">
    <title>{% block title %}{% endblock %}CYOA Presentations</title>
    <link rel="stylesheet" href="">
    <link rel="stylesheet" href="/static/css/wizard.css">
    {% block css_head %}{% endblock %}
    <!--[if lt IE 9]>
      <script src="">
      <script src="">
  <body{% block body_class %}{% endblock %}>
    {% block nav %}{% endblock %}
    {% block content %}{% endblock %}
    {% block js_body %}{% endblock %}

The above template serves as a base HTML template file that other templates can extend. Our sign-in page and our wizard landing page will both extend base.html.

You’ll notice we have a new wizard.css file included in our base.html file. There are a few extra styles and a background image we will include in our app. Rather than having you type out all that code you’ll want to download the file cyoa-tutorial-step-4.tar.gz and extract it under the cyoa/static/ directory so those files can be served up when we run our application.

base.html eliminates the boilerplate code we don’t want to write in every template, but we can go even further with our Don’t Repeat Yourself (DRY) principle by using a helper to render forms. Make a subdirectory named partials under the cyoa/templates/ directory. Within partials construct a file named _formhelpers.html and put the following template code inside:

{% macro render_field(field) %}
    <dt style="text-align: left;" class="admin-field">{{ field.label }}
    {% if field.errors %}
        <ul class="errors">
            {% for error in field.errors %}
                <li style="color: red;">{{ error }}</li>
            {% endfor %}
    {% endif %}
    <dd>{{ field(class_="form-control", **kwargs)|safe }}
{% endmacro %}

Every time we render a form field in future templates we can include the above file and it will insert the boilerplate code for a single field into the template.

Next, create a new directory under your templates folder named wizard/. Within the wizard/ directory create a new file named sign_in.html with the following template:

{% extends "base.html" %}

{% block css_head %}
    <link href="/static/css/signin.css" rel="stylesheet">
{% endblock %}

{% block body_class %} class="wizard-bg" {% endblock %}

{% block content %}
<div class="container sign-in">
    <div class="col-md-12">
        <div id="login">
            <h1>Wizards Only!</h1>
            {% from "partials/_formhelpers.html" import render_field %}
            <form method="post" action="{{ url_for('sign_in') }}" 
                {{ form.csrf_token }}
                {{ render_field(form.wizard_name, required=True) }}
                {{ render_field(form.password, required=True) }}
                <div style="margin-top: 10px; text-align: right;">
                    <input class="btn btn-primary" 
                           type="submit" value="Sign in" />
<footer class="footer">
    <div class="container">
        <p class="text-muted pull-right">
            Photo by <a href="">JD Hancock</a>
{% endblock %}

The template renders a page with a nice wizard background image for some extra flavor. We’re close to running our app, but we need a page to render once the wizard gets past the sign-in page.

Create a new file named wizard/presentations.html that will store a stub page that we’ll expand upon in part 2 of this tutorial.

{% extends "base.html" %}

{% block content %}
<div class="container">
    <div class="row">
        <div class="col-md-10">
            <h1>Wizards Only Stuff Here</h1>
            <a href="{{ url_for('sign_out') }}">Sign out</a>
{% endblock %}

With our application code and templates in place we just have one more file to update so we can run the application. Change the existing file with the following highlighted lines.

from gevent import monkey

import os
import redis

from cyoa import app, redis_db, socketio
from cyoa import db
from cyoa.models import Wizard
from flask.ext.script import Manager, Shell

manager = Manager(app)

def make_shell_context():
    return dict(app=app, redis_db=redis_db, db=db, Wizard=Wizard)

manager.add_command("shell", Shell(make_context=make_shell_context))

def syncdb():

def runserver():, "", port=5001)

def clear_redis():
    redis_cli = redis.StrictRedis(host='localhost', port='6379', db='0')

if __name__ == '__main__':

We’re itching to get this application running but we need to make sure our database is created along with our Wizard table. On the command line create PostgreSQL database using this command:

createdb cyoa

With our updated script we can create the database tables necessary for storing wizards.

python syncdb

Also we need to populate our first authorized wizard. Start up the shell and enter the following code to create and save a wizard. You can modify the credentials as you see fit.

python shell
>>> db.session.add(Wizard('gandalf', 'thegrey'))
>>> db.session.commit()
>>> exit()

Finally, time to test out our new wizard sign-in screen! Within the base directory of our application run the built-in server using the following command:

python runserver

Head to http://localhost:5001/wizard/ in a web browser to bring up our application. Now we can authenticate as a wizard with the name and password we just added to the database.


After entering our credentials and hitting the Sign in button we’ll see the following landing page.


Click the Sign out button to test out the sign_out function and ensure that we eliminate any trace of our wizard-ness to the application.

Wizards Only Engaged

Our Wizards Only sign-in page is complete, but there’s more work to be done. In part two of the Wizard Mode tutorial, we’ll enable better control over presentations by building out our wizard pages. Tune back in shortly for the second story in this three part tutorial.

Confused over steps in this tutorial or think it should be built a different way? Let me know how you’d like to see the Choose Your Own Adventure Presentations tutorial evolve after the Wizard Mode tutorial series is finished. Contact me via:

  • Email:
  • GitHub: Follow makaimc for repository updates
  • Twitter: @mattmakai
Sign up and start building
Not ready yet? Talk to an expert.