SlideShare a Scribd company logo
1 of 71
Download to read offline
FILLING THE FLASK
Created by /Jason A Myers @jasonamyers
OUR EMPTY FLASK
I have two files setup: flaskfilled/__init__.py and config.py
__INIT__.PY
from flask import Flask
from config import config
def create_app(config_name):
app = Flask(__name__)
app.config.from_object(config[config_name])
return app
CONFIG.PY
import os
basedir = os.path.abspath(os.path.dirname(__file__))
class Config:
SECRET_KEY = 'development key'
ADMINS = frozenset(['jason@jasonamyers.com', ])
class DevelopmentConfig(Config):
DEBUG = True
config = {
'development': DevelopmentConfig,
MANAGEMENT COMMANDS
FLASK-SCRIPT
Commands for running a development server, a customised
Python shell, etc
pip install flask-script
MANAGE.PY
#! /usr/bin/env python
import os
from flask.ext.script import Manager
from flaskfilled import create_app
app = create_app(os.getenv('FLASK_CONFIG') or 'default')
manager = Manager(app)
if __name__ == '__main__':
manager.run()
SHELL WITH CONTEXT
from flask.ext.script import Shell
def make_shell_context():
return dict(app=app)
manager.add_command('shell', Shell(make_context=make_shell_context))
$ python manage.py
usage: manage.py [-?] {runserver,shell} ...
positional arguments:
{runserver,shell}
runserver Runs the Flask development server i.e. app.run()
shell Runs a Python shell inside Flask application context.
optional arguments:
-?, --help show this help message and exit
$ python manage.py shell
In [1]: app.config['DEBUG']
Out[1]: True
DATABASE ACCESS
FLASK-SQLALCHEMY
Single wrapper for most of SQLAlchemy
Preconfigured scope session
Sessions are tied to the page lifecycle
pip install flask-sqlalchemy
__INIT__.PY
from flask.ext.sqlalchemy import SQLAlchemy
db = SQLAlchemy()
def create_app(config_name):
app = Flask(__name__)
app.config.from_object(config[config_name])
db.init_app(app)
return app
CONFIG.PY
class DevelopmentConfig(Config):
DEBUG = True
SQLALCHEMY_DATABASE_URI = "sqlite:////tmp/dev.db"
FLASKFILLED/MODELS.PY
from flaskfilled import db
class Cookie(db.Model):
__tablename__ = 'cookies'
cookie_id = db.Column(db.Integer(), primary_key=True)
cookie_name = db.Column(db.String(50), index=True)
cookie_recipe_url = db.Column(db.String(255))
quantity = db.Column(db.Integer())
MANAGE.PY
from flask.ext.script import Command
from flaskfilled import db
from flaskfilled.models import Cookies
def make_shell_context():
return dict(app=app, db=db)
class DevDbInit(Command):
'''Creates database tables from sqlalchemy models'''
def __init__(self, db):
self.db = db
def run(self):
self.db.create_all()
$ python manage.py db_init
$ python manage.py shell
In [1]: db.metadata.tables
Out[1]: immutabledict({'cookies': Table('cookies', 'stuff')})
In [2]: from flaskfilled.models import Cookie
c = Cookie(cookie_name="Chocolate Chip",
cookie_recipe_url="http://zenofthecookie.com/chocolatechip.html"
quantity=2)
db.session.add(c)
db.session.commit()
MIGRATIONS
FLASK-MIGRATE
Ties Alembic into flask-script!
pip install flask-migrate
MANAGE.PY
from flask.ext.migrate import Migrate, MigrateCommand
migrate = Migrate(app, db)
manager.add_command('db', MigrateCommand)
INITIALIZING ALEMBIC
$ python manage.py db init
GENERATING A MIGRATION
$ python manage.py db migrate -m "initial migration"
INFO [alembic.migration] Context impl SQLiteImpl.
INFO [alembic.migration] Will assume non-transactional DDL.
Generating flask-filled/migrations/versions/586131216f6_initial_migration.p
RUNNING MIGRATIONS
$ python manage.py db upgrade
INFO [alembic.migration] Context impl SQLiteImpl.
INFO [alembic.migration] Will assume non-transactional DDL.
INFO [alembic.migration] Running upgrade -> 586131216f6, initial migration
USER AUTHENTICATION
FLASK-LOGIN
Simplifies logging users in and out
Secures view functions with decorators
Protects session cookies
pip install flask-login
FLASKFILLED/__INIT__.PY
from flask.ext.login import LoginManager
login_manager = LoginManager()
def create_app(config_name):
app = Flask(__name__)
app.config.from_object(config[config_name])
db.init_app(app)
login_manager.setup_app(app)
from .main import main as main_blueprint
app.register_blueprint(main_blueprint)
from .auth import auth as auth_blueprint
app.register_blueprint(auth_blueprint, url_prefix='/auth')
MODELS.PY
from werkzeug.security import generate_password_hash, check_password_hash
from flaskfilled import login_manager
class User(db.Model, UserMixin):
__tablename__ = 'users'
id = db.Column(db.Integer(), primary_key=True)
username = db.Column(db.String, primary_key=True)
password = db.Column(db.String)
authenticated = db.Column(db.Boolean, default=False)
USER MODEL REQUIRED METHODS
PROVIDED BY USERMIXIN
def is_active(self):
return True
def get_id(self):
return self.id
def is_authenticated(self):
return self.authenticated
def is_anonymous(self):
return False
USER MODEL PASSWORD HANDLING
@property
def password(self):
raise AttributeError('password is not a readable attribute')
@password.setter
def password(self, password):
self.password_hash = generate_password_hash(password)
def verify_password(self, password):
return check_password_hash(self.password_hash, password)
SETTING UP THE AUTH BLUEPRINT
AUTH/__INIT__.PY
from flask import Blueprint
auth = Blueprint('auth', __name__)
from . import views
AUTH/VIEWS.PY
from flask import render_template, redirect, request, url_for, flash
from flask.ext.login import login_user, logout_user, login_required
from . import auth
from flaskfilled.models import User
LOGIN
@auth.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
username = request.form.get('username', '')
password = request.form.get('password', '')
user = User.query.filter_by(username=username).first()
if user is not None and user.verify_password(password):
login_user(user)
next = request.args.get('next')
return redirect(next or url_for('main.index'))
else:
flash('Wrong username or password.')
return render_template('auth/login.html')
LOGOUT
@auth.route('/logout')
@login_required
def logout():
logout_user()
flash('You have been logged out.')
return redirect(url_for('main.index'))
LOGIN TEMPLATE
{% extends "base.html" %}
{% block title %}Login{% endblock %}
{% block page_content %}
<div class="page-header">
<h1>Login</h1>
</div>
<div class="col-md-4">
<form action="">
Username: <input type="text" name="username"><br>
Password: <input type="password" name="password"><br>
<input type="submit">
</form>
<br>
<p>Forgot your password? <a href="{{ url_for('auth.password_reset_request
<p>New user? <a href="{{ url_for('auth.register') }}">Click here to regis
MAIN/VIEWS.PY
from flask import render_template
from . import main
@main.route('/', methods=['GET'])
def index():
return render_template('main/index.html')
INDEX TEMPLATE
{% extends "base.html" %}
{% block title %}The Index{% endblock %}
{% block page_content %}
{% if not current_user.is_authenticated() %}
<p><a href="{{ url_for('auth.login') }}">Click here to login</a>.</p
{% else %}
<p><a href="{{ url_for('auth.logout') }}">Click here to logout</a>.</
{% endif %}
{% endblock %}
CREATE USERS MIGRATION AND
APPLY IT
$ python manage.py db migrate -m "User"
Generating /Users/jasonamyers/dev/flask-filled/migrations/versions/8d9327f0
$ python manage.py db upgrade
INFO [alembic.migration] Running upgrade 586131216f6 -> 8d9327f04f, User
RUN SERVER
$ python manage.py runserver
FORMS...
FLASK-WTF
Validation
CSRF protection
File Uploads
pip install flask-wtf
AUTH/FORMS.PY
from flask.ext.wtf import Form
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import Required, Length
class LoginForm(Form):
username = StringField('username', validators=[Required(),
Length(1, 64)])
password = PasswordField('Password', validators=[Required()])
submit = SubmitField('Log In')
AUTH/VIEWS.PY
@auth.route('/login', methods=['GET', 'POST'])
def login():
form = LoginForm()
if form.validate_on_submit():
user = User.query.filter_by(username=form.username.data).first()
if user is not None and user.verify_password(form.password.data):
login_user(user)
next = request.args.get('next')
return redirect(next or url_for('main.index'))
else:
flash('Wrong username or password.')
return render_template('auth/login.html', form=form)
TEMPLATES/AUTH/LOGIN.HTML
{% block page_content %}
<div class="col-md-4">
<form action="" method="POST">
{{ form.csrf_token }}
{% if form.csrf_token.errors %}
<div class="warning">You have submitted an invalid CSRF token</
{% endif %}
{{form.username.label }}: {{ form.username }}
{% if form.username.errors %}
{% for error in form.username.errors %}
{{ error }}
{% endfor %}
{% endif %}<br>
{{form.password.label }}: {{ form.password }}
{% if form.password.errors %}
{% for error in form.password.errors %}
{{ error }}
AUTHORIZATION
FLASK-PRINCIPAL
pip install flask-principal
__INIT__.PY
from flask.ext.principal import Principal
principal = Principal()
def create_app(config_name):
principal.init_app(app)
MODELS.PY
roles_users = db.Table('roles_users',
db.Column('user_id', db.Integer(),
db.ForeignKey('users.user_id')),
db.Column('role_id', db.Integer(),
db.ForeignKey('roles.id')))
class Role(db.Model):
__tablename__ = 'roles'
id = db.Column(db.Integer(), primary_key=True)
name = db.Column(db.String(80), unique=True)
description = db.Column(db.String(255))
MODELS.PY - USER CLASS
class User(db.Model, UserMixin):
roles = db.relationship('Role', secondary=roles_users,
primaryjoin=user_id == roles_users.c.user_id
backref='users')
MODELS.PY - IDENTITY LOADER
@identity_loaded.connect
def on_identity_loaded(sender, identity):
# Set the identity user object
identity.user = current_user
# Add the UserNeed to the identity
if hasattr(current_user, 'id'):
identity.provides.add(UserNeed(current_user.id))
# Assuming the User model has a list of roles, update the
# identity with the roles that the user provides
if hasattr(current_user, 'roles'):
for role in current_user.roles:
identity.provides.add(RoleNeed(role.name))
AUTH/VIEWS.PY
from flask import current_app
from flask.ext.principal import identity_changed, Identity
@auth.route('/login', methods=['GET', 'POST'])
def login():
form = LoginForm()
if form.validate_on_submit():
user = User.query.filter_by(username=form.username.data).first()
if user is not None and user.verify_password(form.password.data):
login_user(user)
identity_changed.send(current_app._get_current_object(),
identity=Identity(user.user_id))
next = request.args.get('next')
return redirect(next or url_for('main.index'))
else:
AUTH/__INIT__.PY
from flask.ext.principal import Permission, RoleNeed
admin_permission = Permission(RoleNeed('admin'))
MAIN/VIEWS.PY
from flaskfilled.auth import admin_permission
@main.route('/settings', methods=['GET'])
@admin_permission.require()
def settings():
return render_template('main/settings.html')
SENDING MAIL
FLASK-MAIL
Works with Flask config
Simplies Message Construction
__INIT__.PY
from flask.ext.mail import Mail
mail = Mail()
def create_app(config_name):
mail.init_app(app)
__INIT__.PY
from flask.ext.mail import Mail
mail = Mail()
def create_app(config_name):
mail.init_app(app)
MAIN/VIEWS.PY
from flask_mail import Message
@main.route('/mailme', methods=['GET'])
def mail():
msg = Message('COOKIES!',
sender='from@example.com',
recipients=['to@example.com'])
msg.body = 'There all mine!'
msg.html = '<b>There all mine!</b>'
mail.send(msg)
WHAT OTHER THINGS ARE OUT
THERE?
flask-security
flask-moment
https://github.com/humiaozuzu/awesome-flask
QUESTIONS
Jason Myers / @jasonamyers / Essential SQLAlchemy 2nd Ed
O'Reilly

More Related Content

What's hot

Flask RESTful Flask HTTPAuth
Flask RESTful Flask HTTPAuthFlask RESTful Flask HTTPAuth
Flask RESTful Flask HTTPAuthEueung Mulyana
 
#30.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...
#30.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...#30.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...
#30.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...탑크리에듀(구로디지털단지역3번출구 2분거리)
 
Flask Introduction - Python Meetup
Flask Introduction - Python MeetupFlask Introduction - Python Meetup
Flask Introduction - Python MeetupAreski Belaid
 
Phpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friendsPhpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friendsMichael Peacock
 
Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5Elena Kolevska
 
Dance for the puppet master: G6 Tech Talk
Dance for the puppet master: G6 Tech TalkDance for the puppet master: G6 Tech Talk
Dance for the puppet master: G6 Tech TalkMichael Peacock
 
OSCON Google App Engine Codelab - July 2010
OSCON Google App Engine Codelab - July 2010OSCON Google App Engine Codelab - July 2010
OSCON Google App Engine Codelab - July 2010ikailan
 
Php Unit With Zend Framework Zendcon09
Php Unit With Zend Framework   Zendcon09Php Unit With Zend Framework   Zendcon09
Php Unit With Zend Framework Zendcon09Michelangelo van Dam
 
The Enterprise Wor/d/thy/Press
The Enterprise Wor/d/thy/PressThe Enterprise Wor/d/thy/Press
The Enterprise Wor/d/thy/PressJeroen van Dijk
 
Learn flask in 90mins
Learn flask in 90minsLearn flask in 90mins
Learn flask in 90minsLarry Cai
 
A Little Backbone For Your App
A Little Backbone For Your AppA Little Backbone For Your App
A Little Backbone For Your AppLuca Mearelli
 
WordPress REST API hacking
WordPress REST API hackingWordPress REST API hacking
WordPress REST API hackingJeroen van Dijk
 
#31.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...
#31.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...#31.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...
#31.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...탑크리에듀(구로디지털단지역3번출구 2분거리)
 
Datagrids with Symfony 2, Backbone and Backgrid
Datagrids with Symfony 2, Backbone and BackgridDatagrids with Symfony 2, Backbone and Backgrid
Datagrids with Symfony 2, Backbone and Backgrideugenio pombi
 

What's hot (20)

Flask RESTful Flask HTTPAuth
Flask RESTful Flask HTTPAuthFlask RESTful Flask HTTPAuth
Flask RESTful Flask HTTPAuth
 
Flask SQLAlchemy
Flask SQLAlchemy Flask SQLAlchemy
Flask SQLAlchemy
 
#30.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...
#30.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...#30.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...
#30.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...
 
Getting Started-with-Laravel
Getting Started-with-LaravelGetting Started-with-Laravel
Getting Started-with-Laravel
 
Flask Introduction - Python Meetup
Flask Introduction - Python MeetupFlask Introduction - Python Meetup
Flask Introduction - Python Meetup
 
CodeIgniter 3.0
CodeIgniter 3.0CodeIgniter 3.0
CodeIgniter 3.0
 
Phpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friendsPhpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friends
 
Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5
 
Dance for the puppet master: G6 Tech Talk
Dance for the puppet master: G6 Tech TalkDance for the puppet master: G6 Tech Talk
Dance for the puppet master: G6 Tech Talk
 
OSCON Google App Engine Codelab - July 2010
OSCON Google App Engine Codelab - July 2010OSCON Google App Engine Codelab - July 2010
OSCON Google App Engine Codelab - July 2010
 
New in php 7
New in php 7New in php 7
New in php 7
 
Php Unit With Zend Framework Zendcon09
Php Unit With Zend Framework   Zendcon09Php Unit With Zend Framework   Zendcon09
Php Unit With Zend Framework Zendcon09
 
The Enterprise Wor/d/thy/Press
The Enterprise Wor/d/thy/PressThe Enterprise Wor/d/thy/Press
The Enterprise Wor/d/thy/Press
 
Learn flask in 90mins
Learn flask in 90minsLearn flask in 90mins
Learn flask in 90mins
 
A Little Backbone For Your App
A Little Backbone For Your AppA Little Backbone For Your App
A Little Backbone For Your App
 
WordPress REST API hacking
WordPress REST API hackingWordPress REST API hacking
WordPress REST API hacking
 
#31.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...
#31.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...#31.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...
#31.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...
 
Django
DjangoDjango
Django
 
Phinx talk
Phinx talkPhinx talk
Phinx talk
 
Datagrids with Symfony 2, Backbone and Backgrid
Datagrids with Symfony 2, Backbone and BackgridDatagrids with Symfony 2, Backbone and Backgrid
Datagrids with Symfony 2, Backbone and Backgrid
 

Viewers also liked

Quattro passi tra le nuvole (e non scordate il paracadute)
Quattro passi tra le nuvole (e non scordate il paracadute)Quattro passi tra le nuvole (e non scordate il paracadute)
Quattro passi tra le nuvole (e non scordate il paracadute)Nicola Iarocci
 
Hands on django part 1
Hands on django part 1Hands on django part 1
Hands on django part 1MicroPyramid .
 
Intro python-object-protocol
Intro python-object-protocolIntro python-object-protocol
Intro python-object-protocolShiyao Ma
 
Fuga dalla Comfort Zone
Fuga dalla Comfort ZoneFuga dalla Comfort Zone
Fuga dalla Comfort ZoneNicola Iarocci
 
Diabetes and Me: My Journey So Far
Diabetes and Me: My Journey So FarDiabetes and Me: My Journey So Far
Diabetes and Me: My Journey So FarJason Myers
 
Python Static Analysis Tools
Python Static Analysis ToolsPython Static Analysis Tools
Python Static Analysis ToolsJason Myers
 
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic MigrationsIntroduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic MigrationsJason Myers
 
Coderfaire Data Networking for Developers
Coderfaire Data Networking for DevelopersCoderfaire Data Networking for Developers
Coderfaire Data Networking for DevelopersJason Myers
 
Flask - Python microframework
Flask - Python microframeworkFlask - Python microframework
Flask - Python microframeworkAndré Mayer
 
RESTful Web API and MongoDB go for a pic nic
RESTful Web API and MongoDB go for a pic nicRESTful Web API and MongoDB go for a pic nic
RESTful Web API and MongoDB go for a pic nicNicola Iarocci
 
Eve - REST API for Humans™
Eve - REST API for Humans™Eve - REST API for Humans™
Eve - REST API for Humans™Nicola Iarocci
 
Introduction to SQLAlchemy ORM
Introduction to SQLAlchemy ORMIntroduction to SQLAlchemy ORM
Introduction to SQLAlchemy ORMJason Myers
 
We Are All Remote Workers
We Are All Remote WorkersWe Are All Remote Workers
We Are All Remote WorkersNicola Iarocci
 
REST Web API with MongoDB
REST Web API with MongoDBREST Web API with MongoDB
REST Web API with MongoDBMongoDB
 
Impact of Restful Web Architecture on Performance and Scalability
Impact of Restful Web Architecture on Performance and ScalabilityImpact of Restful Web Architecture on Performance and Scalability
Impact of Restful Web Architecture on Performance and ScalabilitySanchit Gera
 
Web develop in flask
Web develop in flaskWeb develop in flask
Web develop in flaskJim Yeh
 
Selenium testing
Selenium testingSelenium testing
Selenium testingJason Myers
 
Django channels
Django channelsDjango channels
Django channelsAndy Dai
 

Viewers also liked (20)

Quattro passi tra le nuvole (e non scordate il paracadute)
Quattro passi tra le nuvole (e non scordate il paracadute)Quattro passi tra le nuvole (e non scordate il paracadute)
Quattro passi tra le nuvole (e non scordate il paracadute)
 
Hands on django part 1
Hands on django part 1Hands on django part 1
Hands on django part 1
 
Intro python-object-protocol
Intro python-object-protocolIntro python-object-protocol
Intro python-object-protocol
 
Fuga dalla Comfort Zone
Fuga dalla Comfort ZoneFuga dalla Comfort Zone
Fuga dalla Comfort Zone
 
CoderDojo Romagna
CoderDojo RomagnaCoderDojo Romagna
CoderDojo Romagna
 
Diabetes and Me: My Journey So Far
Diabetes and Me: My Journey So FarDiabetes and Me: My Journey So Far
Diabetes and Me: My Journey So Far
 
Python Static Analysis Tools
Python Static Analysis ToolsPython Static Analysis Tools
Python Static Analysis Tools
 
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic MigrationsIntroduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
 
Online / Offline
Online / OfflineOnline / Offline
Online / Offline
 
Coderfaire Data Networking for Developers
Coderfaire Data Networking for DevelopersCoderfaire Data Networking for Developers
Coderfaire Data Networking for Developers
 
Flask - Python microframework
Flask - Python microframeworkFlask - Python microframework
Flask - Python microframework
 
RESTful Web API and MongoDB go for a pic nic
RESTful Web API and MongoDB go for a pic nicRESTful Web API and MongoDB go for a pic nic
RESTful Web API and MongoDB go for a pic nic
 
Eve - REST API for Humans™
Eve - REST API for Humans™Eve - REST API for Humans™
Eve - REST API for Humans™
 
Introduction to SQLAlchemy ORM
Introduction to SQLAlchemy ORMIntroduction to SQLAlchemy ORM
Introduction to SQLAlchemy ORM
 
We Are All Remote Workers
We Are All Remote WorkersWe Are All Remote Workers
We Are All Remote Workers
 
REST Web API with MongoDB
REST Web API with MongoDBREST Web API with MongoDB
REST Web API with MongoDB
 
Impact of Restful Web Architecture on Performance and Scalability
Impact of Restful Web Architecture on Performance and ScalabilityImpact of Restful Web Architecture on Performance and Scalability
Impact of Restful Web Architecture on Performance and Scalability
 
Web develop in flask
Web develop in flaskWeb develop in flask
Web develop in flask
 
Selenium testing
Selenium testingSelenium testing
Selenium testing
 
Django channels
Django channelsDjango channels
Django channels
 

Similar to Filling the Flask: A Guide to Flask Configuration and Setup

LvivPy - Flask in details
LvivPy - Flask in detailsLvivPy - Flask in details
LvivPy - Flask in detailsMax Klymyshyn
 
What The Flask? and how to use it with some Google APIs
What The Flask? and how to use it with some Google APIsWhat The Flask? and how to use it with some Google APIs
What The Flask? and how to use it with some Google APIsBruno Rocha
 
WordPress Security - ওয়ার্ডপ্রেসের সিকিউরিটি
WordPress Security - ওয়ার্ডপ্রেসের সিকিউরিটিWordPress Security - ওয়ার্ডপ্রেসের সিকিউরিটি
WordPress Security - ওয়ার্ডপ্রেসের সিকিউরিটিFaysal Shahi
 
Python from zero to hero (Twitter Explorer)
Python from zero to hero (Twitter Explorer)Python from zero to hero (Twitter Explorer)
Python from zero to hero (Twitter Explorer)Yuriy Senko
 
Pyramid Deployment and Maintenance
Pyramid Deployment and MaintenancePyramid Deployment and Maintenance
Pyramid Deployment and MaintenanceJazkarta, Inc.
 
Web development automatisation for fun and profit (Artem Daniliants)
Web development automatisation for fun and profit (Artem Daniliants)Web development automatisation for fun and profit (Artem Daniliants)
Web development automatisation for fun and profit (Artem Daniliants)LumoSpark
 
WordPress Plugin development
WordPress Plugin developmentWordPress Plugin development
WordPress Plugin developmentMostafa Soufi
 
Python Flask Tutorial For Beginners | Flask Web Development Tutorial | Python...
Python Flask Tutorial For Beginners | Flask Web Development Tutorial | Python...Python Flask Tutorial For Beginners | Flask Web Development Tutorial | Python...
Python Flask Tutorial For Beginners | Flask Web Development Tutorial | Python...Edureka!
 
Burn down the silos! Helping dev and ops gel on high availability websites
Burn down the silos! Helping dev and ops gel on high availability websitesBurn down the silos! Helping dev and ops gel on high availability websites
Burn down the silos! Helping dev and ops gel on high availability websitesLindsay Holmwood
 
Large scale machine learning projects with R Suite
Large scale machine learning projects with R SuiteLarge scale machine learning projects with R Suite
Large scale machine learning projects with R SuiteWLOG Solutions
 
Large scale machine learning projects with r suite
Large scale machine learning projects with r suiteLarge scale machine learning projects with r suite
Large scale machine learning projects with r suiteWit Jakuczun
 
Djangoアプリのデプロイに関するプラクティス / Deploy django application
Djangoアプリのデプロイに関するプラクティス / Deploy django applicationDjangoアプリのデプロイに関するプラクティス / Deploy django application
Djangoアプリのデプロイに関するプラクティス / Deploy django applicationMasashi Shibata
 
The Enterprise Wor/d/thy/Press
The Enterprise Wor/d/thy/PressThe Enterprise Wor/d/thy/Press
The Enterprise Wor/d/thy/PressJeroen van Dijk
 
Pyramid Lighter/Faster/Better web apps
Pyramid Lighter/Faster/Better web appsPyramid Lighter/Faster/Better web apps
Pyramid Lighter/Faster/Better web appsDylan Jay
 
BP501 - Building and deploying custom IBM sametime connect client installatio...
BP501 - Building and deploying custom IBM sametime connect client installatio...BP501 - Building and deploying custom IBM sametime connect client installatio...
BP501 - Building and deploying custom IBM sametime connect client installatio...Carl Tyler
 
Spring Boot Actuator
Spring Boot ActuatorSpring Boot Actuator
Spring Boot ActuatorRowell Belen
 
Flask intro - ROSEdu web workshops
Flask intro - ROSEdu web workshopsFlask intro - ROSEdu web workshops
Flask intro - ROSEdu web workshopsAlex Eftimie
 
Oa Framework Tutorial
Oa Framework TutorialOa Framework Tutorial
Oa Framework Tutorialnolimit797
 

Similar to Filling the Flask: A Guide to Flask Configuration and Setup (20)

LvivPy - Flask in details
LvivPy - Flask in detailsLvivPy - Flask in details
LvivPy - Flask in details
 
What The Flask? and how to use it with some Google APIs
What The Flask? and how to use it with some Google APIsWhat The Flask? and how to use it with some Google APIs
What The Flask? and how to use it with some Google APIs
 
WordPress Security - ওয়ার্ডপ্রেসের সিকিউরিটি
WordPress Security - ওয়ার্ডপ্রেসের সিকিউরিটিWordPress Security - ওয়ার্ডপ্রেসের সিকিউরিটি
WordPress Security - ওয়ার্ডপ্রেসের সিকিউরিটি
 
Pyramid deployment
Pyramid deploymentPyramid deployment
Pyramid deployment
 
Python from zero to hero (Twitter Explorer)
Python from zero to hero (Twitter Explorer)Python from zero to hero (Twitter Explorer)
Python from zero to hero (Twitter Explorer)
 
Pyramid Deployment and Maintenance
Pyramid Deployment and MaintenancePyramid Deployment and Maintenance
Pyramid Deployment and Maintenance
 
Web development automatisation for fun and profit (Artem Daniliants)
Web development automatisation for fun and profit (Artem Daniliants)Web development automatisation for fun and profit (Artem Daniliants)
Web development automatisation for fun and profit (Artem Daniliants)
 
WordPress Plugin development
WordPress Plugin developmentWordPress Plugin development
WordPress Plugin development
 
Python Flask Tutorial For Beginners | Flask Web Development Tutorial | Python...
Python Flask Tutorial For Beginners | Flask Web Development Tutorial | Python...Python Flask Tutorial For Beginners | Flask Web Development Tutorial | Python...
Python Flask Tutorial For Beginners | Flask Web Development Tutorial | Python...
 
Burn down the silos! Helping dev and ops gel on high availability websites
Burn down the silos! Helping dev and ops gel on high availability websitesBurn down the silos! Helping dev and ops gel on high availability websites
Burn down the silos! Helping dev and ops gel on high availability websites
 
Large scale machine learning projects with R Suite
Large scale machine learning projects with R SuiteLarge scale machine learning projects with R Suite
Large scale machine learning projects with R Suite
 
Large scale machine learning projects with r suite
Large scale machine learning projects with r suiteLarge scale machine learning projects with r suite
Large scale machine learning projects with r suite
 
Djangoアプリのデプロイに関するプラクティス / Deploy django application
Djangoアプリのデプロイに関するプラクティス / Deploy django applicationDjangoアプリのデプロイに関するプラクティス / Deploy django application
Djangoアプリのデプロイに関するプラクティス / Deploy django application
 
The Enterprise Wor/d/thy/Press
The Enterprise Wor/d/thy/PressThe Enterprise Wor/d/thy/Press
The Enterprise Wor/d/thy/Press
 
Pyramid Lighter/Faster/Better web apps
Pyramid Lighter/Faster/Better web appsPyramid Lighter/Faster/Better web apps
Pyramid Lighter/Faster/Better web apps
 
BP501 - Building and deploying custom IBM sametime connect client installatio...
BP501 - Building and deploying custom IBM sametime connect client installatio...BP501 - Building and deploying custom IBM sametime connect client installatio...
BP501 - Building and deploying custom IBM sametime connect client installatio...
 
Spring Boot Actuator
Spring Boot ActuatorSpring Boot Actuator
Spring Boot Actuator
 
Symfony2 revealed
Symfony2 revealedSymfony2 revealed
Symfony2 revealed
 
Flask intro - ROSEdu web workshops
Flask intro - ROSEdu web workshopsFlask intro - ROSEdu web workshops
Flask intro - ROSEdu web workshops
 
Oa Framework Tutorial
Oa Framework TutorialOa Framework Tutorial
Oa Framework Tutorial
 

Recently uploaded

Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024The Digital Insurer
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr LapshynFwdays
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Wonjun Hwang
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 

Recently uploaded (20)

Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 

Filling the Flask: A Guide to Flask Configuration and Setup

  • 1. FILLING THE FLASK Created by /Jason A Myers @jasonamyers
  • 2.
  • 3.
  • 4.
  • 5.
  • 6. OUR EMPTY FLASK I have two files setup: flaskfilled/__init__.py and config.py
  • 7. __INIT__.PY from flask import Flask from config import config def create_app(config_name): app = Flask(__name__) app.config.from_object(config[config_name]) return app
  • 8. CONFIG.PY import os basedir = os.path.abspath(os.path.dirname(__file__)) class Config: SECRET_KEY = 'development key' ADMINS = frozenset(['jason@jasonamyers.com', ]) class DevelopmentConfig(Config): DEBUG = True config = { 'development': DevelopmentConfig,
  • 10. FLASK-SCRIPT Commands for running a development server, a customised Python shell, etc pip install flask-script
  • 11. MANAGE.PY #! /usr/bin/env python import os from flask.ext.script import Manager from flaskfilled import create_app app = create_app(os.getenv('FLASK_CONFIG') or 'default') manager = Manager(app) if __name__ == '__main__': manager.run()
  • 12. SHELL WITH CONTEXT from flask.ext.script import Shell def make_shell_context(): return dict(app=app) manager.add_command('shell', Shell(make_context=make_shell_context))
  • 13. $ python manage.py usage: manage.py [-?] {runserver,shell} ... positional arguments: {runserver,shell} runserver Runs the Flask development server i.e. app.run() shell Runs a Python shell inside Flask application context. optional arguments: -?, --help show this help message and exit
  • 14. $ python manage.py shell In [1]: app.config['DEBUG'] Out[1]: True
  • 16. FLASK-SQLALCHEMY Single wrapper for most of SQLAlchemy Preconfigured scope session Sessions are tied to the page lifecycle pip install flask-sqlalchemy
  • 17. __INIT__.PY from flask.ext.sqlalchemy import SQLAlchemy db = SQLAlchemy() def create_app(config_name): app = Flask(__name__) app.config.from_object(config[config_name]) db.init_app(app) return app
  • 18. CONFIG.PY class DevelopmentConfig(Config): DEBUG = True SQLALCHEMY_DATABASE_URI = "sqlite:////tmp/dev.db"
  • 19. FLASKFILLED/MODELS.PY from flaskfilled import db class Cookie(db.Model): __tablename__ = 'cookies' cookie_id = db.Column(db.Integer(), primary_key=True) cookie_name = db.Column(db.String(50), index=True) cookie_recipe_url = db.Column(db.String(255)) quantity = db.Column(db.Integer())
  • 20. MANAGE.PY from flask.ext.script import Command from flaskfilled import db from flaskfilled.models import Cookies def make_shell_context(): return dict(app=app, db=db) class DevDbInit(Command): '''Creates database tables from sqlalchemy models''' def __init__(self, db): self.db = db def run(self): self.db.create_all()
  • 21. $ python manage.py db_init $ python manage.py shell In [1]: db.metadata.tables Out[1]: immutabledict({'cookies': Table('cookies', 'stuff')}) In [2]: from flaskfilled.models import Cookie
  • 22. c = Cookie(cookie_name="Chocolate Chip", cookie_recipe_url="http://zenofthecookie.com/chocolatechip.html" quantity=2) db.session.add(c) db.session.commit()
  • 24. FLASK-MIGRATE Ties Alembic into flask-script! pip install flask-migrate
  • 25. MANAGE.PY from flask.ext.migrate import Migrate, MigrateCommand migrate = Migrate(app, db) manager.add_command('db', MigrateCommand)
  • 26. INITIALIZING ALEMBIC $ python manage.py db init
  • 27. GENERATING A MIGRATION $ python manage.py db migrate -m "initial migration" INFO [alembic.migration] Context impl SQLiteImpl. INFO [alembic.migration] Will assume non-transactional DDL. Generating flask-filled/migrations/versions/586131216f6_initial_migration.p
  • 28. RUNNING MIGRATIONS $ python manage.py db upgrade INFO [alembic.migration] Context impl SQLiteImpl. INFO [alembic.migration] Will assume non-transactional DDL. INFO [alembic.migration] Running upgrade -> 586131216f6, initial migration
  • 30. FLASK-LOGIN Simplifies logging users in and out Secures view functions with decorators Protects session cookies pip install flask-login
  • 31. FLASKFILLED/__INIT__.PY from flask.ext.login import LoginManager login_manager = LoginManager() def create_app(config_name): app = Flask(__name__) app.config.from_object(config[config_name]) db.init_app(app) login_manager.setup_app(app) from .main import main as main_blueprint app.register_blueprint(main_blueprint) from .auth import auth as auth_blueprint app.register_blueprint(auth_blueprint, url_prefix='/auth')
  • 32. MODELS.PY from werkzeug.security import generate_password_hash, check_password_hash from flaskfilled import login_manager class User(db.Model, UserMixin): __tablename__ = 'users' id = db.Column(db.Integer(), primary_key=True) username = db.Column(db.String, primary_key=True) password = db.Column(db.String) authenticated = db.Column(db.Boolean, default=False)
  • 33. USER MODEL REQUIRED METHODS PROVIDED BY USERMIXIN def is_active(self): return True def get_id(self): return self.id def is_authenticated(self): return self.authenticated def is_anonymous(self): return False
  • 34. USER MODEL PASSWORD HANDLING @property def password(self): raise AttributeError('password is not a readable attribute') @password.setter def password(self, password): self.password_hash = generate_password_hash(password) def verify_password(self, password): return check_password_hash(self.password_hash, password)
  • 35. SETTING UP THE AUTH BLUEPRINT AUTH/__INIT__.PY from flask import Blueprint auth = Blueprint('auth', __name__) from . import views
  • 36. AUTH/VIEWS.PY from flask import render_template, redirect, request, url_for, flash from flask.ext.login import login_user, logout_user, login_required from . import auth from flaskfilled.models import User
  • 37. LOGIN @auth.route('/login', methods=['GET', 'POST']) def login(): if request.method == 'POST': username = request.form.get('username', '') password = request.form.get('password', '') user = User.query.filter_by(username=username).first() if user is not None and user.verify_password(password): login_user(user) next = request.args.get('next') return redirect(next or url_for('main.index')) else: flash('Wrong username or password.') return render_template('auth/login.html')
  • 38. LOGOUT @auth.route('/logout') @login_required def logout(): logout_user() flash('You have been logged out.') return redirect(url_for('main.index'))
  • 39. LOGIN TEMPLATE {% extends "base.html" %} {% block title %}Login{% endblock %} {% block page_content %} <div class="page-header"> <h1>Login</h1> </div> <div class="col-md-4"> <form action=""> Username: <input type="text" name="username"><br> Password: <input type="password" name="password"><br> <input type="submit"> </form> <br> <p>Forgot your password? <a href="{{ url_for('auth.password_reset_request <p>New user? <a href="{{ url_for('auth.register') }}">Click here to regis
  • 40. MAIN/VIEWS.PY from flask import render_template from . import main @main.route('/', methods=['GET']) def index(): return render_template('main/index.html')
  • 41. INDEX TEMPLATE {% extends "base.html" %} {% block title %}The Index{% endblock %} {% block page_content %} {% if not current_user.is_authenticated() %} <p><a href="{{ url_for('auth.login') }}">Click here to login</a>.</p {% else %} <p><a href="{{ url_for('auth.logout') }}">Click here to logout</a>.</ {% endif %} {% endblock %}
  • 42. CREATE USERS MIGRATION AND APPLY IT $ python manage.py db migrate -m "User" Generating /Users/jasonamyers/dev/flask-filled/migrations/versions/8d9327f0 $ python manage.py db upgrade INFO [alembic.migration] Running upgrade 586131216f6 -> 8d9327f04f, User
  • 43. RUN SERVER $ python manage.py runserver
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 51. AUTH/FORMS.PY from flask.ext.wtf import Form from wtforms import StringField, PasswordField, SubmitField from wtforms.validators import Required, Length class LoginForm(Form): username = StringField('username', validators=[Required(), Length(1, 64)]) password = PasswordField('Password', validators=[Required()]) submit = SubmitField('Log In')
  • 52. AUTH/VIEWS.PY @auth.route('/login', methods=['GET', 'POST']) def login(): form = LoginForm() if form.validate_on_submit(): user = User.query.filter_by(username=form.username.data).first() if user is not None and user.verify_password(form.password.data): login_user(user) next = request.args.get('next') return redirect(next or url_for('main.index')) else: flash('Wrong username or password.') return render_template('auth/login.html', form=form)
  • 53. TEMPLATES/AUTH/LOGIN.HTML {% block page_content %} <div class="col-md-4"> <form action="" method="POST"> {{ form.csrf_token }} {% if form.csrf_token.errors %} <div class="warning">You have submitted an invalid CSRF token</ {% endif %} {{form.username.label }}: {{ form.username }} {% if form.username.errors %} {% for error in form.username.errors %} {{ error }} {% endfor %} {% endif %}<br> {{form.password.label }}: {{ form.password }} {% if form.password.errors %} {% for error in form.password.errors %} {{ error }}
  • 56. __INIT__.PY from flask.ext.principal import Principal principal = Principal() def create_app(config_name): principal.init_app(app)
  • 57. MODELS.PY roles_users = db.Table('roles_users', db.Column('user_id', db.Integer(), db.ForeignKey('users.user_id')), db.Column('role_id', db.Integer(), db.ForeignKey('roles.id'))) class Role(db.Model): __tablename__ = 'roles' id = db.Column(db.Integer(), primary_key=True) name = db.Column(db.String(80), unique=True) description = db.Column(db.String(255))
  • 58. MODELS.PY - USER CLASS class User(db.Model, UserMixin): roles = db.relationship('Role', secondary=roles_users, primaryjoin=user_id == roles_users.c.user_id backref='users')
  • 59. MODELS.PY - IDENTITY LOADER @identity_loaded.connect def on_identity_loaded(sender, identity): # Set the identity user object identity.user = current_user # Add the UserNeed to the identity if hasattr(current_user, 'id'): identity.provides.add(UserNeed(current_user.id)) # Assuming the User model has a list of roles, update the # identity with the roles that the user provides if hasattr(current_user, 'roles'): for role in current_user.roles: identity.provides.add(RoleNeed(role.name))
  • 60. AUTH/VIEWS.PY from flask import current_app from flask.ext.principal import identity_changed, Identity @auth.route('/login', methods=['GET', 'POST']) def login(): form = LoginForm() if form.validate_on_submit(): user = User.query.filter_by(username=form.username.data).first() if user is not None and user.verify_password(form.password.data): login_user(user) identity_changed.send(current_app._get_current_object(), identity=Identity(user.user_id)) next = request.args.get('next') return redirect(next or url_for('main.index')) else:
  • 61. AUTH/__INIT__.PY from flask.ext.principal import Permission, RoleNeed admin_permission = Permission(RoleNeed('admin'))
  • 62. MAIN/VIEWS.PY from flaskfilled.auth import admin_permission @main.route('/settings', methods=['GET']) @admin_permission.require() def settings(): return render_template('main/settings.html')
  • 63.
  • 64.
  • 66. FLASK-MAIL Works with Flask config Simplies Message Construction
  • 67. __INIT__.PY from flask.ext.mail import Mail mail = Mail() def create_app(config_name): mail.init_app(app)
  • 68. __INIT__.PY from flask.ext.mail import Mail mail = Mail() def create_app(config_name): mail.init_app(app)
  • 69. MAIN/VIEWS.PY from flask_mail import Message @main.route('/mailme', methods=['GET']) def mail(): msg = Message('COOKIES!', sender='from@example.com', recipients=['to@example.com']) msg.body = 'There all mine!' msg.html = '<b>There all mine!</b>' mail.send(msg)
  • 70. WHAT OTHER THINGS ARE OUT THERE? flask-security flask-moment https://github.com/humiaozuzu/awesome-flask
  • 71. QUESTIONS Jason Myers / @jasonamyers / Essential SQLAlchemy 2nd Ed O'Reilly