Web application with Python + Flask ④

  1. Environment preparation (OS setup)
  2. Environment preparation (setup in OS)
  3. Trace the contents of Flask's QuickStart (installation and minimal setup)
  4. Trace the contents of Flask's Tutorial (learning how to make a basic application) ★
  5. Make original content

Click here for Flask Tutorial. Build a microblogging service called Flaskr. Sqlite is used as the database.

Creating a folder structure

Create a directory to place the application. The name is arbitrary, but static and templates should be used as they are to match the standard. (Don't forget to pluralize with templates)

[root@cnenyuy5l3c ~]# mkdir flaskr
[root@cnenyuy5l3c ~]# cd flaskr
[root@cnenyuy5l3c flaskr]#
[root@cnenyuy5l3c flaskr]# mkdir templates static
[root@cnenyuy5l3c flaskr]#
[root@cnenyuy5l3c flaskr]# virtualenv env
New python executable in /root/flaskr/env/bin/python2.7
Also creating executable in /root/flaskr/env/bin/python
Installing setuptools, pip, wheel...done.
[root@cnenyuy5l3c flaskr]#
[root@cnenyuy5l3c flaskr]# ls
env  static  templates
[root@cnenyuy5l3c flaskr]#

Virtual environment isolation and Flask installation

Enable virtualenv and install flask there.

[root@cnenyuy5l3c flaskr]# . env/bin/activate
(env) [root@cnenyuy5l3c flaskr]#
(env) [root@cnenyuy5l3c flaskr]# pip install flask
Collecting flask
(Omission)
Successfully installed Jinja2-2.9.5 MarkupSafe-0.23 Werkzeug-0.11.15 click-6.7 flask-0.12 itsdangerous-0.24
(env) [root@cnenyuy5l3c flaskr]#

DB creation

First, create a schema.

schema.sql


drop table if exists entries;
create table entries (
  id integer primary key autoincrement,
  title string not null,
  text string not null
);

This schema is not streamed directly, but modularized in Python. The following flaskr.py is the main body of the flaskr application, but here only the initialization part of the DB is created.

flaskr.py


import sqlite3
from flask import Flask, request, session, g, redirect, url_for, \
     abort, render_template, flash
from contextlib import closing    #It wasn't officially here, but it was necessary

# configuration
DATABASE = '/tmp/flaskr.db'
DEBUG = True
SECRET_KEY = 'development key'
USERNAME = 'admin'
PASSWORD = 'default'

# create our little application :)
app = Flask(__name__)
app.config.from_object(__name__)

def connect_db():
    return sqlite3.connect(app.config['DATABASE'])

def init_db():
    with closing(connect_db()) as db:
        with app.open_resource('schema.sql') as f:  #Here schema.Run sql
            db.cursor().executescript(f.read())
        db.commit()

#Various View functions will be added here.

if __name__ == '__main__':
    app.run(host='0.0.0.0')  #Refer to from other than guest local

from_object is a method that reads all uppercase variables in the target. The target here is name, that is, your own file (flaskr.py). Also, in the original, the last app.run does not specify an option, but this time host = '0.0.0.0' is specified for reference from the host machine. Now that we are ready, create a DB.

(flaskr) [root@localhost flaskr]# python
Python 2.7.12 (default, Jan  4 2017, 08:18:28)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-17)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>
>>> from flaskr import init_db
>>> init_db()
>>>

If you get the following error here, sqlite3-devel is missing when compiling python, so you need to re-install it.

>>> from flaskr import init_db
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "flaskr.py", line 5, in <module>
    import sqlite3
  File "/opt/local/lib/python2.7/sqlite3/__init__.py", line 24, in <module>
    from dbapi2 import *
  File "/opt/local/lib/python2.7/sqlite3/dbapi2.py", line 28, in <module>
    from _sqlite3 import *
ImportError: No module named _sqlite3

Check the created database for the time being.

(env) [root@cnenyuy5l3c flaskr]# sqlite3 /tmp/flaskr.db
SQLite version 3.6.20
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> .tables
entries
sqlite>
sqlite> .schema
CREATE TABLE entries (
  id integer primary key autoincrement,
  title string not null,
  text string not null
);
sqlite> .quit

Creating a View function

Add functions from here. The first is the process of creating and closing a connection with the database.

@app.before_request
def before_request():
    g.db = connect_db()

@app.after_request
def after_request(response):
    g.db.close()
    return response

g is a special object provided by flask that stores the connection to the current database. (g only stores information for one request) before_request is called before the request. It has no arguments here.

after_request is called after the request. Here, the connection is closed and the response from the DB is passed to the client. Is it okay to think of this as a cliché? From here, enter the content corresponding to the actual page. Basically, the work of associating a URL with a function called by a route decorator.

@app.route('/')    # http://<hostname>:5000/Define a function to be called when accessing(routing)
def show_entries():
    cur = g.db.execute('select title, text from entries order by id desc')
    entries = [dict(title=row[0], text=row[1]) for row in cur.fetchall()]
    return render_template('show_entries.html', entries=entries)    # show_entries.Embed entries in HTML called html(rendering)

@app.route('/add', methods=['POST'])
def add_entry():
    if not session.get('logged_in'):
        abort(401)
    g.db.execute('insert into entries (title, text) values (?, ?)',
                 [request.form['title'], request.form['text']])
    g.db.commit()
    flash('New entry was successfully posted')
    return redirect(url_for('show_entries'))    #Redirect if you want to skip to a function instead of rendering()use.

@app.route('/login', methods=['GET', 'POST'])
def login():
    error = None
    if request.method == 'POST':
        if request.form['username'] != app.config['USERNAME']:
            error = 'Invalid username'
        elif request.form['password'] != app.config['PASSWORD']:
            error = 'Invalid password'
        else:
            session['logged_in'] = True
            flash('You were logged in')
            return redirect(url_for('show_entries'))
    return render_template('login.html', error=error)

@app.route('/logout')
def logout():
    session.pop('logged_in', None)
    flash('You were logged out')
    return redirect(url_for('show_entries'))

HTML creation

Now that we have created the function part, let's move on to HTML (appearance). In Flask, the original base HTML (often called layout.html) is created and expanded as appropriate.

layout.html


<!doctype html>
<title>Flaskr</title>
<link rel=stylesheet type=text/css href="{{ url_for('static', filename='style.css') }}">
<div class=page>
  <h1>Flaskr</h1>
  <div class=metanav>
  {% if not session.logged_in %}
    <a href="{{ url_for('login') }}">log in</a>
  {% else %}
    <a href="{{ url_for('logout') }}">log out</a>
  {% endif %}
  </div>
  {% for message in get_flashed_messages() %}
    <div class=flash>{{ message }}</div>
  {% endfor %}
  {% block body %}{% endblock %}    <!--This block is replaced on reference-->
</div>

show_entries.html


{% extends "layout.html" %}    <!--Now specify the underlying HTML-->
{% block body %}    <!-- layout.Replace the html body block with:-->
  {% if session.logged_in %}
    <form action="{{ url_for('add_entry') }}" method=post class=add-entry>
      <dl>
        <dt>Title:
        <dd><input type=text size=30 name=title>
        <dt>Text:
        <dd><textarea name=text rows=5 cols=40></textarea>
        <dd><input type=submit value=Share>
      </dl>
    </form>
  {% endif %}
  <ul class=entries>
  {% for entry in entries %}
    <li><h2>{{ entry.title }}</h2>{{ entry.text|safe }}
  {% else %}
    <li><em>Unbelievable.  No entries here so far</em>
  {% endfor %}
  </ul>
{% endblock %}

login.html


{% extends "layout.html" %}
{% block body %}
  <h2>Login</h2>
  {% if error %}<p class=error><strong>Error:</strong> {{ error }}{% endif %}
  <form action="{{ url_for('login') }}" method=post>
    <dl>
      <dt>Username:
      <dd><input type=text name=username>
      <dt>Password:
      <dd><input type=password name=password>
      <dd><input type=submit value=Login>
    </dl>
  </form>
{% endblock %}

Creating CSS

Finally, create a CSS file.

style.css


body            { font-family: sans-serif; background: #eee; }
a, h1, h2       { color: #377BA8; }
h1, h2          { font-family: 'Georgia', serif; margin: 0; }
h1              { border-bottom: 2px solid #eee; }
h2              { font-size: 1.2em; }

.page           { margin: 2em auto; width: 35em; border: 5px solid #ccc;
                  padding: 0.8em; background: white; }
.entries        { list-style: none; margin: 0; padding: 0; }
.entries li     { margin: 0.8em 1.2em; }
.entries li h2  { margin-left: -1em; }
.add-entry      { font-size: 0.9em; border-bottom: 1px solid #ccc; }
.add-entry dl   { font-weight: bold; }
.metanav        { text-align: right; font-size: 0.8em; padding: 0.3em;
                  margin-bottom: 1em; background: #fafafa; }
.flash          { background: #CEE5F5; padding: 0.5em;
                  border: 1px solid #AACBE2; }
.error          { background: #F0D6D6; padding: 0.5em; }

Start, test

Place the above files as follows.

If possible, start the application and check the access.

(env) [root@cnenyuy5l3c flaskr]# python flaskr.py
 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
 * Restarting with stat
 * Debugger is active!
 * Debugger pin code: 602-691-323

20170131_009.jpg 20170131_010.jpg 20170131_011.jpg

There seems to be no problem. With this, the minimum basics have been suppressed (should), so I plan to move on to the original from the next time.

Recommended Posts

Web application with Python + Flask ④
Web application development with Flask
Application development with Docker + Python + Flask
Parse and visualize JSON (Web application ⑤ with Python + Flask)
[Python] A quick web application with Bottle!
Easy web app with Python + Flask + Heroku
Run a Python web application with Docker
Programming with Python Flask
Web application created with Python + Flask (using VScode) # 1-Virtual environment construction-
Launch a web server with Python and Flask
Web scraping with python + JupyterLab
Web application creation with Django
Web API with Python + Falcon
Web scraping beginner with python
Streamline web search with python
Launch a Python web application with Nginx + Gunicorn with Docker
Web application made with Python3.4 + Django (Part.1 Environment construction)
[ES Lab] I tried to develop a WEB application with Python and Flask ②
Web application production course learned with Flask of Python Part 2 Chapter 1 ~ JSON exchange ~
SNS Python basics made with Flask
Creating a web application using Flask ②
Web scraping with Python ① (Scraping prior knowledge)
Web application development memo in python
Getting Started with Python Web Applications
Web scraping with Python First step
I tried web scraping with python.
[Python] Use Basic/Digest authentication with Flask
Monitor Python application performance with Dynatrace ♪
Get web screen capture with python
Build a web application with Django
Creating a web application using Flask ①
Creating a web application using Flask ③
Creating a web application using Flask ④
Python application: Data cleansing # 2: Data cleansing with DataFrame
Python x Flask x Tensorflow.Keras Web application for predicting cat breeds 2
I made a simple book application with python + Flask ~ Introduction ~
Web application with Python3.3.1 + Bottle (1) --Change template engine to jinja2
Easy deep learning web app with NNC and Python + Flask
[Python] Web application from 0! Hands-on (2) -Hello World-
[Python] Web application from 0! Hands-on (3) -API implementation-
FizzBuzz with Python3
Scraping with Python
If you know Python, you can make a web application with Django
The first artificial intelligence. Challenge web output with python. ~ Flask introduction
Let's make a WEB application for phone book with flask Part 1
Statistics with python
Try using the web application framework Flask
Getting Started with Flask with Azure Web Apps
Scraping with Python
Python with Go
Build a Flask / Bottle-like web application on AWS Lambda with Chalice
Python x Flask x PyTorch Easy construction of number recognition web application
Getting Started with Python Web Scraping Practice
POST variously with Python and receive with Flask
Page cache in Python + Flask with Flask-Caching
Twilio with Python
Let's make a WEB application for phone book with flask Part 2
Play with 2016-Python
Daemonize a Python web app with Supervisor
Tested with Python
Flask application settings