Browse Source

Adds in blueprints and an application factory

pull/2228/head
Kyle Lawlor 8 years ago
parent
commit
8cf32bca51
  1. 1
      examples/flaskr/flaskr/__init__.py
  2. 3
      examples/flaskr/flaskr/_cliapp.py
  3. 0
      examples/flaskr/flaskr/blueprints/__init__.py
  4. 55
      examples/flaskr/flaskr/blueprints/flaskr.py
  5. 52
      examples/flaskr/flaskr/factory.py
  6. 4
      examples/flaskr/flaskr/templates/layout.html
  7. 2
      examples/flaskr/flaskr/templates/login.html
  8. 2
      examples/flaskr/flaskr/templates/show_entries.html
  9. 4
      examples/flaskr/setup.py
  10. 34
      examples/flaskr/tests/test_flaskr.py

1
examples/flaskr/flaskr/__init__.py

@ -1 +0,0 @@
from .flaskr import app

3
examples/flaskr/flaskr/_cliapp.py

@ -0,0 +1,3 @@
from flaskr.factory import create_app
app = create_app()

0
examples/flaskr/flaskr/blueprints/__init__.py

55
examples/flaskr/flaskr/flaskr.py → examples/flaskr/flaskr/blueprints/flaskr.py

@ -10,29 +10,18 @@
:license: BSD, see LICENSE for more details. :license: BSD, see LICENSE for more details.
""" """
import os
from sqlite3 import dbapi2 as sqlite3 from sqlite3 import dbapi2 as sqlite3
from flask import Flask, request, session, g, redirect, url_for, abort, \ from flask import Blueprint, request, session, g, redirect, url_for, abort, \
render_template, flash render_template, flash, current_app
# create our little application :) # create our blueprint :)
app = Flask(__name__) bp = Blueprint('flaskr', __name__)
# Load default config and override config from an environment variable
app.config.update(dict(
DATABASE=os.path.join(app.root_path, 'flaskr.db'),
DEBUG=True,
SECRET_KEY='development key',
USERNAME='admin',
PASSWORD='default'
))
app.config.from_envvar('FLASKR_SETTINGS', silent=True)
def connect_db(): def connect_db():
"""Connects to the specific database.""" """Connects to the specific database."""
rv = sqlite3.connect(app.config['DATABASE']) rv = sqlite3.connect(current_app.config['DATABASE'])
rv.row_factory = sqlite3.Row rv.row_factory = sqlite3.Row
return rv return rv
@ -40,18 +29,11 @@ def connect_db():
def init_db(): def init_db():
"""Initializes the database.""" """Initializes the database."""
db = get_db() db = get_db()
with app.open_resource('schema.sql', mode='r') as f: with current_app.open_resource('schema.sql', mode='r') as f:
db.cursor().executescript(f.read()) db.cursor().executescript(f.read())
db.commit() db.commit()
@app.cli.command('initdb')
def initdb_command():
"""Creates the database tables."""
init_db()
print('Initialized the database.')
def get_db(): def get_db():
"""Opens a new database connection if there is none yet for the """Opens a new database connection if there is none yet for the
current application context. current application context.
@ -61,14 +43,7 @@ def get_db():
return g.sqlite_db return g.sqlite_db
@app.teardown_appcontext @bp.route('/')
def close_db(error):
"""Closes the database again at the end of the request."""
if hasattr(g, 'sqlite_db'):
g.sqlite_db.close()
@app.route('/')
def show_entries(): def show_entries():
db = get_db() db = get_db()
cur = db.execute('select title, text from entries order by id desc') cur = db.execute('select title, text from entries order by id desc')
@ -76,7 +51,7 @@ def show_entries():
return render_template('show_entries.html', entries=entries) return render_template('show_entries.html', entries=entries)
@app.route('/add', methods=['POST']) @bp.route('/add', methods=['POST'])
def add_entry(): def add_entry():
if not session.get('logged_in'): if not session.get('logged_in'):
abort(401) abort(401)
@ -85,26 +60,26 @@ def add_entry():
[request.form['title'], request.form['text']]) [request.form['title'], request.form['text']])
db.commit() db.commit()
flash('New entry was successfully posted') flash('New entry was successfully posted')
return redirect(url_for('show_entries')) return redirect(url_for('flaskr.show_entries'))
@app.route('/login', methods=['GET', 'POST']) @bp.route('/login', methods=['GET', 'POST'])
def login(): def login():
error = None error = None
if request.method == 'POST': if request.method == 'POST':
if request.form['username'] != app.config['USERNAME']: if request.form['username'] != current_app.config['USERNAME']:
error = 'Invalid username' error = 'Invalid username'
elif request.form['password'] != app.config['PASSWORD']: elif request.form['password'] != current_app.config['PASSWORD']:
error = 'Invalid password' error = 'Invalid password'
else: else:
session['logged_in'] = True session['logged_in'] = True
flash('You were logged in') flash('You were logged in')
return redirect(url_for('show_entries')) return redirect(url_for('flaskr.show_entries'))
return render_template('login.html', error=error) return render_template('login.html', error=error)
@app.route('/logout') @bp.route('/logout')
def logout(): def logout():
session.pop('logged_in', None) session.pop('logged_in', None)
flash('You were logged out') flash('You were logged out')
return redirect(url_for('show_entries')) return redirect(url_for('flaskr.show_entries'))

52
examples/flaskr/flaskr/factory.py

@ -0,0 +1,52 @@
import os
from flask import Flask, g
from werkzeug.utils import find_modules, import_string
from flaskr.blueprints.flaskr import init_db
def create_app(config=None):
app = Flask(__name__)
app.config.update(dict(
DATABASE=os.path.join(app.root_path, 'flaskr.db'),
DEBUG=True,
SECRET_KEY='development key',
USERNAME='admin',
PASSWORD='default'
))
app.config.update(config or {})
app.config.from_envvar('FLASKR_SETTINGS', silent=True)
register_blueprints(app)
register_cli(app)
register_teardowns(app)
return app
def register_blueprints(app):
"""Register all blueprint modules
Reference: Armin Ronacher, "Flask for Fun and for Profit" PyBay 2016.
"""
for name in find_modules('flaskr.blueprints'):
mod = import_string(name)
if hasattr(mod, 'bp'):
app.register_blueprint(mod.bp)
return None
def register_cli(app):
@app.cli.command('initdb')
def initdb_command():
"""Creates the database tables."""
init_db()
print('Initialized the database.')
def register_teardowns(app):
@app.teardown_appcontext
def close_db(error):
"""Closes the database again at the end of the request."""
if hasattr(g, 'sqlite_db'):
g.sqlite_db.close()

4
examples/flaskr/flaskr/templates/layout.html

@ -5,9 +5,9 @@
<h1>Flaskr</h1> <h1>Flaskr</h1>
<div class="metanav"> <div class="metanav">
{% if not session.logged_in %} {% if not session.logged_in %}
<a href="{{ url_for('login') }}">log in</a> <a href="{{ url_for('flaskr.login') }}">log in</a>
{% else %} {% else %}
<a href="{{ url_for('logout') }}">log out</a> <a href="{{ url_for('flaskr.logout') }}">log out</a>
{% endif %} {% endif %}
</div> </div>
{% for message in get_flashed_messages() %} {% for message in get_flashed_messages() %}

2
examples/flaskr/flaskr/templates/login.html

@ -2,7 +2,7 @@
{% block body %} {% block body %}
<h2>Login</h2> <h2>Login</h2>
{% if error %}<p class="error"><strong>Error:</strong> {{ error }}{% endif %} {% if error %}<p class="error"><strong>Error:</strong> {{ error }}{% endif %}
<form action="{{ url_for('login') }}" method="post"> <form action="{{ url_for('flaskr.login') }}" method="post">
<dl> <dl>
<dt>Username: <dt>Username:
<dd><input type="text" name="username"> <dd><input type="text" name="username">

2
examples/flaskr/flaskr/templates/show_entries.html

@ -1,7 +1,7 @@
{% extends "layout.html" %} {% extends "layout.html" %}
{% block body %} {% block body %}
{% if session.logged_in %} {% if session.logged_in %}
<form action="{{ url_for('add_entry') }}" method="post" class="add-entry"> <form action="{{ url_for('flaskr.add_entry') }}" method="post" class="add-entry">
<dl> <dl>
<dt>Title: <dt>Title:
<dd><input type="text" size="30" name="title"> <dd><input type="text" size="30" name="title">

4
examples/flaskr/setup.py

@ -1,8 +1,8 @@
from setuptools import setup from setuptools import setup, find_packages
setup( setup(
name='flaskr', name='flaskr',
packages=['flaskr'], packages=find_packages(),
include_package_data=True, include_package_data=True,
install_requires=[ install_requires=[
'flask', 'flask',

34
examples/flaskr/tests/test_flaskr.py

@ -12,20 +12,24 @@
import os import os
import tempfile import tempfile
import pytest import pytest
from flaskr import flaskr from flaskr.factory import create_app
from flaskr.blueprints.flaskr import init_db
test_app = create_app()
@pytest.fixture @pytest.fixture
def client(request): def client(request):
db_fd, flaskr.app.config['DATABASE'] = tempfile.mkstemp() db_fd, test_app.config['DATABASE'] = tempfile.mkstemp()
flaskr.app.config['TESTING'] = True test_app.config['TESTING'] = True
client = flaskr.app.test_client() client = test_app.test_client()
with flaskr.app.app_context(): with test_app.app_context():
flaskr.init_db() init_db()
def teardown(): def teardown():
os.close(db_fd) os.close(db_fd)
os.unlink(flaskr.app.config['DATABASE']) os.unlink(test_app.config['DATABASE'])
request.addfinalizer(teardown) request.addfinalizer(teardown)
return client return client
@ -50,23 +54,23 @@ def test_empty_db(client):
def test_login_logout(client): def test_login_logout(client):
"""Make sure login and logout works""" """Make sure login and logout works"""
rv = login(client, flaskr.app.config['USERNAME'], rv = login(client, test_app.config['USERNAME'],
flaskr.app.config['PASSWORD']) test_app.config['PASSWORD'])
assert b'You were logged in' in rv.data assert b'You were logged in' in rv.data
rv = logout(client) rv = logout(client)
assert b'You were logged out' in rv.data assert b'You were logged out' in rv.data
rv = login(client, flaskr.app.config['USERNAME'] + 'x', rv = login(client,test_app.config['USERNAME'] + 'x',
flaskr.app.config['PASSWORD']) test_app.config['PASSWORD'])
assert b'Invalid username' in rv.data assert b'Invalid username' in rv.data
rv = login(client, flaskr.app.config['USERNAME'], rv = login(client, test_app.config['USERNAME'],
flaskr.app.config['PASSWORD'] + 'x') test_app.config['PASSWORD'] + 'x')
assert b'Invalid password' in rv.data assert b'Invalid password' in rv.data
def test_messages(client): def test_messages(client):
"""Test that messages work""" """Test that messages work"""
login(client, flaskr.app.config['USERNAME'], login(client, test_app.config['USERNAME'],
flaskr.app.config['PASSWORD']) test_app.config['PASSWORD'])
rv = client.post('/add', data=dict( rv = client.post('/add', data=dict(
title='<Hello>', title='<Hello>',
text='<strong>HTML</strong> allowed here' text='<strong>HTML</strong> allowed here'

Loading…
Cancel
Save