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

Mickey Mouse as a wizard. Photo by JD Hancock.

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.

sign-in-preview.jpg

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:

wizard-panel.png

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 git@github.com:makaimc/choose-your-own-adventure-presentations

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:

(cyoa)$

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/config.py 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 models.py within the cyoa/ subdirectory to store information about wizards. The file should have the following contents:

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

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 config.py file as highlighted below.

In our original Choose Your Own Adventure Presentations blog post we set the other environment variables listed in the above config.py 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 forms.py in your cyoa/ subdirectory.

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 views.py file.

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

What we’re doing in the code above is including our new login manager we created in the __init__.py 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:

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:

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:

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.

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 manage.py file with the following highlighted lines.

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 manage.py script we can create the database tables necessary for storing wizards.

python manage.py 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.

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 manage.py 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.

wizards-credentials.jpg

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

wizards-only.png

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: makai@twilio.com
  • GitHub: Follow makaimc for repository updates
  • Twitter: @mattmakai