This is a tutorial for a mini data science quiz app that we will deploy to Heroku. You'll find the completed code here.
This simple app is based on the gettting started tutorial from the framework's creators, Pocoo.
If you're an Anaconda user, run:
conda install flask
Or if you prefer pip
,
pip install flask
/quizr
/quizr
/static
/templates
mkdir quizr
cd quizr
mkdir quizr
cd quizr
mkdir static
mkdir templates
Just kidding. We don't need a database. We're going to use Google docs! The spreadsheet we will use lives here.
In quizr/quizr.py
copy and paste the following code:
import os
import pandas as pd
import numpy as np
from flask import Flask, request, session, g, redirect, url_for, abort, \
render_template, flash
app = Flask(__name__) # create the application instance :)
app.config.from_object(__name__) # load config from this file , quizr.py
app.config.update(dict(
SECRET_KEY='development key',
))
app.config.from_envvar('QUIZR_SETTINGS', silent=True)
def get_vocab():
base = "https://docs.google.com/spreadsheets/d/"
doc_id = "13uFW3lriigsAKJTAn_Ilo3fo7ZdeLUKbtqOe65Bf4iw"
export_sheet = "/export?gid=577814466&format=csv"
url = base + doc_id + export_sheet
vocab = pd.read_csv(url,index_col=False)
sample = vocab.sample(10)
return sample.to_dict(orient = "records")
@app.route('/')
def index():
vocab = get_vocab()
return render_template('index.html', vocab=vocab)
/quizr
/quizr
__init__.py
/static
/templates
quizr.py
setup.py
MANIFEST.in
Create the setup file.
touch setup.py
Copy and paste this content.
from setuptools import setup
setup(
name='quizr',
packages=['quizr'],
include_package_data=True,
install_requires=[
'flask',
],
)
Create the manifest file.
touch MANIFEST.in
Copy and paste this content.
graft quizr/templates
graft quizr/static
Create the init file.
touch quizr/__init__.py
Copy and paste this content.
from .quizr import app
touch quizr/templates/index.html
Paste this content. We're making a single page app, so we only need one template.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Quizr</title>
<!-- Bootstrap core CSS -->
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='bootstrap.css') }}">
<!-- Custom styles for this template -->
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='jumbotron-narrow.css') }}">
</head>
<body>
<div class="container">
<div class="header clearfix">
<h3 class="text-muted">Quizr</h3>
</div>
<div class="jumbotron">
<h1>Data Science Quizr</h1>
<p class="lead">Get your DS quiz fix at home. Your welcome.</p>
<p><a class="btn btn-lg btn-success" href="{{ url_for('index') }}" role="button">Refresh the list</a></p>
</div>
{% for item in vocab %}
<div class="panel panel-default">
<div class="panel-heading">
<div class="pull-right">
<button class="btn btn-info btn-sm" type="button" data-toggle="collapse" href="#collapseExample{{loop.index0}}" aria-expanded="false" aria-controls="collapseExample">
Show Definition
</button>
</div>
<h3 class="panel-title">{{ item.term }}</h3>
<br/>
</div>
<div class="panel-body">
<div class="collapse" id="collapseExample{{loop.index0}}">
<div class="well">
{{ item.definition }}
</div>
</div>
</div>
</div>
{% endfor %}
<footer class="footer">
<p>© 2016 Rosie, Inc.</p>
</footer>
</div>
<script src="https://code.jquery.com/jquery-2.2.4.js" integrity_no="sha256-iT6Q9iMJYuQiMWNd9lDyBUStIq/8PuOW33aOqmvFpqI=" crossorigin="anonymous"></script>
<script src="{{ url_for('static', filename='bootstrap.min.js') }}"></script>
</body>
</html>
Drop these file into quizr/static
. We're using the core Bootstrap library as well as a Bootstrap theme and layout. Though it is true that adding the whole Bootstrap libray adds a huge pile of code that we won't be using, for the sake of keeping the creation of this app simple, we're just going to grab the whole thing.
Bootstrap Jumbo Narrow Layout Theme
pip install --editable .
export FLASK_APP=quizr
export FLASK_DEBUG=true
flask run
Your app should now be running locally. Let's take a look. Open a web browser and go to localhost:5000.
http://localhost:5000/
Don't forget to create a new Github repo and commit your changes.
git init
git add .
git commit -m 'created new awesome flask app'
git push
After you've created a Heroku account and installed the Heroku toolbelt, you're ready to create an app in the cloud. Log into your account from the command line and run:
heroku apps:create metis-quizr
Note that the name of the app must be unique. metis-quizr
is already taken, so use a variation.
Heroku requires a few more things to be included in your app before deployment.
Create a Procfile
in the root of your app.
touch Procfile
Copy and paste this content.
web: gunicorn quizr:app
Next we need to create a requirements.txt
file with all of the dependencies. pipreqs
will help us do this. To install, this package, run:
pip install pipreqs
Then to automatically create this file, run this from the root of your app:
pipreqs .
This will included most of our dependencies. We'll be using gunicorn
on Heroku, so add it to your requirements.txt
file as well. The setuptools
entry is not required for deployment. That can be removed. It should now look like this:
Flask==0.12
gunicorn==19.0.0
numpy==1.11.3
pandas==0.19.1
We also need to tell Heroku what version of python we are using. Create a runtime.txt
file also in the root of your app to do this.
touch runtime.txt
And paste your version of python.
python-3.5.2
Now, we can commit our changes, push to Github.
git add .
git commit -m "added files for deployment to Heroku"
git push
We're ready to deploy our cool app to the new Heroku instance we made in step 8. This is easy, just run:
git push heroku master
Almost done. Now, scale upto one web dyno.
heroku ps:scale web=1
Restart Heroku:
heroku restart
And open up your shiny new app!
heroku open
TADA!! You should have a shiny new application running on Heroku.
More Resources on deployment:
Here's instructions from Heroku.
Here's another approach from a tutorial.
The approach I take here is a simplied version.
Have an app with more dependencies? Try using a buildpack.
heroku config:add BUILDPACK_URL=https://github.com/buildingspeak/conda-buildpack.git