Flask
A micro web development framework in Python
TrojanHacks Fall 2014
Setup
Installing Python
Both version 2.6+ or 3.3+ works
www.python.org
Install and Setup VirtualEnv
http://flask.pocoo.org/docs/0.10/installation/
First get VirtualEnv...
Setup VirtualEnv...
virtualenv venv
Activate VirtualEnv...
Mac OS / Linux:
Windows:
. venv/bin/activate
venv\scripts\activate
Install Flask
pip install Flask
http://flask.pocoo.org/
Hello World!
Starting simple...
Code
In a file named 'app.py':
from flask import Flask app = Flask(__name__)
@app.route('/') def hello_world(): return 'Hello World!'
if __name__ == '__main__': app.run()
Running the App
$ python app.py
Type in terminal...
And you should see...
* Running on http://127.0.0.1:5000/
Code
In a file named 'app.py':
from flask import Flask app = Flask(__name__)
@app.route('/') def hello_world(): return 'Hello World!'
if __name__ == '__main__': app.run()
Code
from flask import Flask app = Flask(__name__)
In a file named 'app.py':
@app.route('/')
def hello_world():
return 'Hello World!'
if __name__ == '__main__':
app.run()
Defines it to be a Flask Application!
Code
In a file named 'app.py':
from flask import Flask
app = Flask(__name__)
@app.route('/') def hello_world(): return 'Hello World!'
if __name__ == '__main__':
app.run()
Defines a route!
Code
In a file named 'app.py':
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello World!'
if __name__ == '__main__': app.run()
Tells python where to start execution!
Basic Routing
Hello #Your Name Here#!
@app.route("/hello/") def hello(): return "Hello World!" @app.route("/hello/<name>") def hello_name(name): return "Hello %s!" % name
HTML files?
Need to create the following directories...
/static - For CSS/JS/Images /templates - For HTML files
from flask import render_template
Need to add a new import...
and a new route...
@app.route("/") def index(): return render_template("index.html")
CSS files?
Need to add another import...
And change the link to the stylesheet...
<link rel="stylesheet" href= "{{ url_for('static', filename='css/kube.min.css') }}" />
from flask import url_for
Do the same for the about yourself page.
Now...
- Add a new page for about
- Create a link from home to about
- and about back to home in nav bar
Templates
and Layouts
DRY -- Don't Repeat Yourself
Move common code into a layout.html file.
index.html can now look like this...
{% extends "layout.html" %}
{% block body %}
<h1>Home Page</h1>
{% endblock %}
{% block body %}{% endblock %}
Place the following where the content of your page should be
Conditional Page Content
{% extends "layout.html" %}
{% block body %}
{% if name %}
<h1>Hello {{ name }}!</h1>
{% else %}
<h1>Hello World!</h1>
{% endif %}
{% endblock %}
In a new file called 'hello.html':
Conditional Page Content
@app.route("/hello_page/") @app.route("/hello_page/<name>") def hello_page(name=None): return render_template("hello.html", name=name);
And in app.py...
HTTP Methods
GET vs POST
By default, all routes are GET
To change it to a POST...
@app.route("/post_route", methods=["POST"])
One URL, Two Methods
@app.route("/http", methods=['POST', 'GET']) def http_demo(): if request.method == 'POST': return "POST Request" else: return "GET Request"
Databases
Now to the more difficult part...
SQLite
http://www.sqlite.org/
First, install...
Configuring App
First an import to the top:
import sqlite3
Add some configuration data:
DATABASE = "/tmp/todo.db" DEBUG = True SECRET_KEY = "" USERNAME = "admin" PASSWORD = "default"
Then, after app = Flask(__name__), add:
app.config.from_object(__name__)
Setting up the Schema
drop table if exists tasks;
Set the structure for our todo list in 'schema.sql':
create table tasks ( id integer primary key autoincrement, name text not null );
Delete the existing tasks table...
Create a new tasks table...
Connect to Database
def connect_db():
return sqlite3.connect(app.config["DATABASE"])
Initialize the DB
In the terminal:
sqlite3 /tmp/todo.db < schema.sql
-- OR --
The suggestion to create a init_db function:
http://flask.pocoo.org/docs/0.10/tutorial/dbinit/#tutorial-dbinit
Request DB Preparation
@app.before_request def before_request(): g.db = connect_db() @app.teardown_request def teardown_request(exception): db = getattr(g, 'db', None) if db is not None: db.close()
Show TODOs
First, some new imports...
from flask import g
@app.route("/todo")
def todo_show():
cur = g.db.execute('select id, name from tasks')
tasks = [dict(tid=row[0], name=row[1]) for row in cur.fetchall()]
return render_template('todo.html', tasks=tasks)
select id, name from tasks
The SQL statement being called...
The TODO show route...
Show TODOs
Now the html...
{% extends "layout.html" %}
{% block body %}
<ul class=entries>
{% for task in tasks %}
<li><h2>{{ task.name }}</h2>
{% else %}
<li><em>WOOHOO!. No todos here so far</em>
{% endfor %}
</ul>
{% endblock %}
Add a TODO
Create new routes...
@app.route("/todo/new")
def todo_new():
return render_template("new_todo.html")
@app.route("/todo/add", methods=["POST"])
def todo_add():
g.db.execute('insert into tasks (name) values (?)', [request.form['task']])
g.db.commit()
return redirect(url_for('todo_show'))
The Add SQL statement:
insert into tasks (name) values (name)
New imports...
from flask import redirect
Removing a TODO
@app.route("/todo/remove/<int:tid>")
def todo_remove(tid):
sql_command = "delete from tasks where id=%d" % tid
g.db.execute(sql_command)
g.db.commit()
return redirect(url_for('todo_show'))
disclaimer: This really should be a POST... but its 5am...
New Route:
SQL statement:
delete from tasks where id = tid
THE END
Congratulations, you have made a Flask Application.
Suggested resources:
http://flask.pocoo.org/docs/0.10/tutorial/
http://www.w3schools.com/sql/default.asp
Introduction to Flask Framework
By Manoj Pandey
Introduction to Flask Framework
Flask workshop
- 1,929