BogoToBogo
  • Home
  • About
  • Big Data
  • Machine Learning
  • AngularJS
  • Python
  • C++
  • go
  • DevOps
  • Kubernetes
  • Algorithms
  • More...
    • Qt 5
    • Linux
    • FFmpeg
    • Matlab
    • Django 1.8
    • Ruby On Rails
    • HTML5 & CSS

Flask blog app tutorial 1 : Signup page

Python-Flask.png




Bookmark and Share





bogotobogo.com site search:



Files and Git

Here are the files we'll be creating in this tutorial part-1:

Fiels-Part1.png

They are available from FlaskApp/p1





Note

This tutorial is based on Creating a Web App From Scratch Using Python Flask and MySQL






virtualenvwrapper

We're going to use virtualenvwrapper" and create our virtualenv venv1 that we'll work on:

k@laptop:~/MySites/etaman$ mkvirtualenv venv1
New python executable in /home/k/Envs/venv1/bin/python
Installing setuptools, pip, wheel...done.
virtualenvwrapper.user_scripts creating /home/k/Envs/venv1/bin/predeactivate
virtualenvwrapper.user_scripts creating /home/k/Envs/venv1/bin/postdeactivate
virtualenvwrapper.user_scripts creating /home/k/Envs/venv1/bin/preactivate
virtualenvwrapper.user_scripts creating /home/k/Envs/venv1/bin/postactivate
virtualenvwrapper.user_scripts creating /home/k/Envs/venv1/bin/get_env_details






Install Flask

Let's install Flask with pip package manager:

(venv1) k@laptop:~/MySites/etaman$ pip install flask

Once the Flask is installed, we want to make a folder, FlaskApp:

(venv1) k@laptop:~/MySites/etaman$ mkdir -p FlaskApp/p1
(venv1) k@laptop:~/MySites/etaman$ cd FlaskApp/p1

Then, let's create a file called app.py: that looks like this:

from flask import Flask
app = Flask(__name__)

# basic route
@app.route("/")
def main():
   return "Hello from etaman.com"

if __name__ == "__main__":
   app.run()

We import the flask module and create an app using Flask. Then, we defined the basic route / and its corresponding request handler. Next, we checked if the executed file is the main program and run the app.


Let's execute the app:

(venv1) k@laptop:~/MySites/etaman/FlaskApp/p1$ python app.py

Go to browser, type in http://localhost:5000/. Then, we should have the welcome page:

HelloFromEtaman.png



Home Page

Our home page should show the latest posts added by users. Since Flask looks for template files inside the templates folder. So, we need to create the folder and under that folder, we should create index.html that looks like this:

<!DOCTYPE html>
<html lang="en">
 
<head>
    <title>Python Flask Blog App</title>
  
    <link href="//getbootstrap.com/dist/css/bootstrap.min.css" rel="stylesheet">
    <link href="//getbootstrap.com/examples/jumbotron-narrow/jumbotron-narrow.css" rel="stylesheet">
 
</head>
 
<body>
 
    <div class="container">
        <div class="header">
            <nav>
                <ul class="nav nav-pills pull-right">
                    <li role="presentation" class="active"><a href="#">Home</a>
                    </li>
                    <li role="presentation"><a href="#">Sign In</a>
                    </li>
                    <li role="presentation"><a href="showSignUp">Sign Up</a>
                    </li>
                </ul>
            </nav>
            <h3 class="text-muted">Python Flask App</h3>
        </div>
 
        <div class="jumbotron">
            <h1>Blog App</h1>
            <p class="lead"></p>
            <p><a class="btn btn-lg btn-success" href="showSignUp" role="button">Sign Up</a>
            </p>
        </div>
 
        <div class="row marketing">
            <div class="col-lg-6">
                <h4>Blog 1</h4>
                <p>No man has a good enough memory to be a successful liar - Abraham Lincoln</p>
 
                <h4>Blog 2</h4>
                <p>A successful man is one who makes more money than his wife can spend. A successful woman is one who can find such a man.</p>
 
                <h4>Blog 3</h4>
                <p>I can resist everything except temptation.</p>

            <br>
            <hr>

            <div class="col-lg-6">
                <h4>Blog 1</h4>
                <p>No man has a good enough memory to be a successful liar - Abraham Lincoln</p>
 
                <h4>Blog 2</h4>
                <p>A successful man is one who makes more money than his wife can spend. A successful woman is one who can find such a man.</p>
 
                <h4>Blog 3</h4>
                <p>I can resist everything except temptation.</p>
            </div>
        </div>
 
        <footer class="footer">
            <p>© etaman.com 2017</p>
        </footer>
 
    </div>
</body>
 
</html>

To reflect the change, let's import render_template into app.py, which we'll use to render the template files and we also need to make the main() method to return the rendered template file.

app.py:

from flask import Flask, render_template
app = Flask(__name__)

@app.route("/")
def main():
   return render_template('index.html')

if __name__ == "__main__":
   app.run()

BlogAppHomePage.png



Database Setup - creating database and table

We'll use MySQL db.

Let's go into MySQL and create a database for our app, FlaskBlogApp:

(venv1) k@laptop:~/MySites/etaman/FlaskApp/p1$ mysql -u root -p
...
Server version: 5.7.16-0ubuntu0.16.04.1 (Ubuntu)
...
mysql> CREATE DATABASE FlaskBlogApp;
Query OK, 1 row affected (0.07 sec)

We need to create a table (blog_user) as well:

CREATE TABLE `FlaskBlogApp`.`blog_user` (
  `user_id` BIGINT NOT NULL AUTO_INCREMENT,
  `user_name` VARCHAR(45) NULL,
  `user_username` VARCHAR(45) NULL,
  `user_password` VARCHAR(85) NULL,
  PRIMARY KEY (`user_id`));

Check what we've done with our db:

mysql> use FlaskBlogApp
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables;
+------------------------+
| Tables_in_FlaskBlogApp |
+------------------------+
| blog_user              |
+------------------------+
1 row in set (0.00 sec)

mysql> describe blog_user;
+---------------+-------------+------+-----+---------+----------------+
| Field         | Type        | Null | Key | Default | Extra          |
+---------------+-------------+------+-----+---------+----------------+
| user_id       | bigint(20)  | NO   | PRI | NULL    | auto_increment |
| user_name     | varchar(45) | YES  |     | NULL    |                |
| user_username | varchar(45) | YES  |     | NULL    |                |
| user_password | varchar(85) | YES  |     | NULL    |                |
+---------------+-------------+------+-----+---------+----------------+
4 rows in set (0.03 sec)




Database Setup - stored procedure

We're going to use "stored procedures" for our Flask app to interact with the MySQL database. Since we've already created the table blog_user, we may want to create a stored procedure called sp_createUser to sign up a user.

In MySQL, let's run the following to make a stored procedure called sp_createUser:

DELIMITER $$
CREATE DEFINER=`root`@`localhost` PROCEDURE `sp_createUser`(
    IN p_name VARCHAR(20),
    IN p_username VARCHAR(20),
    IN p_password VARCHAR(85)
)
BEGIN
    IF ( select exists (select 1 from blog_user where user_username = p_username) ) THEN
     
        select 'Username Exists !!';
     
    ELSE
     
        insert into blog_user
        (
            user_name,
            user_username,
            user_password
        )
        values
        (
            p_name,
            p_username,
            p_password
        );
     
    END IF;
END$$
DELIMITER ;

Note that we set the p_password length = 85 since it will be hashed and it could be long.

When we create a stored procedure to create a user in the blog_user table, first we check if a user with the same username already exists. If it exists we throw an error to the user, otherwise we'll create the user in the user table.


We can check the stored procedure we created:

mysql> SHOW PROCEDURE STATUS WHERE db = 'FlaskBlogApp';
+--------------+-----------------------------+-----------+----------------+---------------------+---------------------+---------------+---------+----------------------+----------------------+--------------------+
| Db           | Name                        | Type      | Definer        | Modified            | Created             | Security_type | Comment | character_set_client | collation_connection | Database Collation |
+--------------+-----------------------------+-----------+----------------+---------------------+---------------------+---------------+---------+----------------------+----------------------+--------------------+
| FlaskBlogApp | sp_createUser               | PROCEDURE | root@localhost | 2016-12-02 09:07:41 | 2016-12-02 09:07:41 | DEFINER       |         | utf8                 | utf8_general_ci      | latin1_swedish_ci  |
+--------------+-----------------------------+-----------+----------------+---------------------+---------------------+---------------+---------+----------------------+----------------------+--------------------+
1 row in set (0.08 sec)

To drop the procedure:

mysql> use FlaskBlogApp;
mysql> DROP PROCEDURE IF EXISTS sp_createUser;




signup.html

Here is FlaskBlogApp/templates/signup.html file:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Python Flask Blog App</title>    

    <link href="//getbootstrap.com/dist/css/bootstrap.min.css" rel="stylesheet"> 
    <link href="//getbootstrap.com/examples/jumbotron-narrow/jumbotron-narrow.css" rel="stylesheet">
    <link href="/static/css/signup.css" rel="stylesheet">    
  </head>
 
  <body>
 
    <div class="container">
      <div class="header">
        <nav>
          <ul class="nav nav-pills pull-right">
            <li role="presentation" ><a href="main">Home</a></li>
            <li role="presentation"><a href="#">Sign In</a></li>
            <li role="presentation" class="active"><a href="#">Sign Up</a></li>
          </ul>
        </nav>
        <img src="/static/images/Flask_Icon.png" alt="Flask_Icon.png"/>
      </div>

      <div class="jumbotron">
        <h1>Blog App</h1>
        <form class="form-signin">
        <label for="inputName" class="sr-only">Name</label>
        <input type="name" name="inputName" id="inputName" class="form-control" placeholder="Name" required autofocus>
        <label for="inputEmail" class="sr-only">Email address</label>
        <input type="email" name="inputEmail" id="inputEmail" class="form-control" placeholder="Email address" required autofocus>
        <label for="inputPassword" class="sr-only">Password</label>
        <input type="password" name="inputPassword" id="inputPassword" class="form-control" placeholder="Password" required>
         
        <button id="btnSignUp" class="btn btn-lg btn-primary btn-block" type="button">Sign up</button>
      </form>
      </div>
 
      <footer class="footer">
        <p>©etaman.com 2017</p>
      </footer>
 
    </div>
  </body>
</html>




signup.css

static/css/signup.css:

body {
  padding-top: 40px;
  padding-bottom: 40px;
}
 
.form-signin {
  max-width: 330px;
  padding: 15px;
  margin: 0 auto;
}
.form-signin .form-signin-heading,
.form-signin .checkbox {
  margin-bottom: 10px;
}
.form-signin .checkbox {
  font-weight: normal;
}
.form-signin .form-control {
  position: relative;
  height: auto;
  -webkit-box-sizing: border-box;
     -moz-box-sizing: border-box;
          box-sizing: border-box;
  padding: 10px;
  font-size: 16px;
}
.form-signin .form-control:focus {
  z-index: 2;
}
.form-signin input[type="email"] {
  margin-bottom: -1px;
  border-bottom-right-radius: 0;
  border-bottom-left-radius: 0;
}
.form-signin input[type="password"] {
  margin-bottom: 10px;
  border-top-left-radius: 0;
  border-top-right-radius: 0;
}




Updating app.py for Sign-Up page

Let's add showSignUpIn() to app.py so that we can render the signup page once a request comes to /showSignUp():

from flask import Flask, render_template
app = Flask(__name__)

@app.route("/")
def main():
   return render_template('index.html')

@app.route('/showSignUp')
def showSignUp():
   return render_template('signup.html')

if __name__ == "__main__":
   app.run()

When we click on the Sign Up button on the home page and we should have the following signup page:

SignUpPageAtSignUpButton.png



Implementing server-side method for Sign-Up

Now that we have Sign-up page, we need a server-side method for the form to interact with the MySQL database.

In app.py, let's create a new method signUp() and also add a route /signUp.

from flask import Flask, render_template, request, json
...
@app.route('/signUp',methods=['POST'])
def signUp():
 
    # read the posted values from the UI
    _name = request.form['inputName']
    _email = request.form['inputEmail']
    _password = request.form['inputPassword']
 
    # validate the received values
    if _name and _email and _password:
        return json.dumps({'html':'<span>All fields good !!</span>'})
    else:
        return json.dumps({'html':'<span>Enter the required fields</span>'})

We're going to use jQuery AJAX to post our signup data to the signUp() method, so we need to specify the method in the route definition. Note that in order to read the posted values we need to import request from Flask.

Once the values are read, we check the rceivd values are valid. At this stage, we're just return a simple message. Note also, we import json to return messages.





Signup request - signUp.js

In order to send the signup request to the Python method, we're going to use jQuery AJAX. Download and place jQuery inside static/js:

(venv1) k@laptop:~/MySites/etaman/FlaskApp/p1/static/js$ wget https://code.jquery.com/jquery-3.1.1.min.js
(venv1) k@laptop:~/MySites/etaman/FlaskApp/p1/static/js$ wget https://code.jquery.com/jquery-3.1.1.js

(venv1) k@laptop:~/MySites/etaman/FlaskApp/p1/static/js$ wget https://code.jquery.com/jquery-3.1.1.min.map

We also need to add a link to it from the signup page. Once jQuery has been included, we'll add a jQuery POST request when the user clicks the Sign Up button.

Here is our js file FlaskApp/p1/static/js/signUp.js:

$(function() {
    $('#btnSignUp').click(function() {
 
        $.ajax({
            url: '/signUp',
            data: $('form').serialize(),
            type: 'POST',
            success: function(response) {
                console.log(response);
            },
            error: function(error) {
                console.log(error);
            }
        });
    });
});

Once jQuery has been included, we added a jQuery POST request to prepare for the usern's click on the Sign Up button.

After filling out all fields, we get the following output from the browser console when the user push "Sign up" button:

ConsoleOutputAllFieldsGood.png



Calling the MySQL Stored Procedure

Once we have the sign-up data: name, email address and password, we make a call to the MySQL stored procedure to create the new user.

To connect with MySQL from Flask, we need to install Flask-MySQL:

(venv1) k@laptop:~/MySites/etaman/FlaskApp/p1$ pip install flask-mysql
...
Successfully installed PyMySQL-0.7.9 flask-mysql-1.4.0

In app.py, we need to import, configure MySQL and get connected to it:

from flask import Flask, render_template, json, request
from flaskext.mysql import MySQL
from werkzeug import generate_password_hash, check_password_hash

mysql = MySQL()
app = Flask(__name__)

# MySQL configurations

app.config['MYSQL_DATABASE_USER'] = 'khong'
app.config['MYSQL_DATABASE_PASSWORD'] = 'khong'
app.config['MYSQL_DATABASE_DB'] = 'FlaskBlogApp'
app.config['MYSQL_DATABASE_HOST'] = 'localhost'
mysql.init_app(app)

@app.route('/')
def main():
    return render_template('index.html')

@app.route('/showSignUp')
def showSignUp():
    return render_template('signup.html')

@app.route('/signUp',methods=['POST','GET'])
def signUp():
    try:
        _name = request.form['inputName']
        _email = request.form['inputEmail']
        _password = request.form['inputPassword']

        # validate the received values
        if _name and _email and _password:
            
            # All Good, let's call MySQL
            
            conn = mysql.connect()
            cursor = conn.cursor()
            _hashed_password = generate_password_hash(_password)
            cursor.callproc('sp_createUser',(_name,_email,_hashed_password))
            data = cursor.fetchall()

            if len(data) is 0:
                conn.commit()
                return json.dumps({'message':'User created successfully !'})
            else:
                return json.dumps({'error':str(data[0])})
        else:
            return json.dumps({'html':'<span>Enter the required fields</span>'})

    except Exception as e:
        return json.dumps({'error':str(e)})
    finally:
        cursor.close() 
        conn.close()

if __name__ == "__main__":
    app.run(port=5000)

As we can se from the code above, we create the MySQL connection:

conn = mysql.connect()

Once the connection is created, we require a cursor to query our stored procedure. So, using conn connection, create a cursor:

cursor = conn.cursor()

Before calling the create user stored procedure, we make our password salted using a helper provided by Werkzeug which is imported module which allows us to create the hashed password.


Then, we call the procedure sp_createUser:

cursor.callproc('sp_createUser',(_name,_email,_hashed_password))

If the procedure is executed successfully, swe can commit the changes and return the success message.

data = cursor.fetchall()
 
if len(data) is 0:
    conn.commit()
    return json.dumps({'message':'User created successfully !'})
else:
    return json.dumps({'error':str(data[0])})




Sign-up - creating a new user

Here is our output for the user signup:

UserCreatedSuccessfully.png

We can check if it was really successful directly on MySQL:

mysql> use FlaskBlogApp;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables;
+------------------------+
| Tables_in_FlaskBlogApp |
+------------------------+
| blog_user              |
+------------------------+
1 row in set (0.00 sec)

mysql> select * from blog_user;
+---------+-----------+----------------+--------------------------------------------------------------------+
| user_id | user_name | user_username  | user_password                                                      |
+---------+-----------+----------------+--------------------------------------------------------------------+
|       1 | K Hong    | k.hong@aol.com | pbkdf2:sha1:1000$xqS4d2GM$1f38b71fb7613bc8085f61db6c5b00ecc25deaf0 |
+---------+-----------+----------------+--------------------------------------------------------------------+
1 row in set (0.00 sec)








Ph.D. / Golden Gate Ave, San Francisco / Seoul National Univ / Carnegie Mellon / UC Berkeley / DevOps / Deep Learning / Visualization

YouTubeMy YouTube channel

Sponsor Open Source development activities and free contents for everyone.

Thank you.

- K Hong








Flask



Deploying Flask Hello World App with Apache WSGI on Ubuntu 14

Flask Micro blog "Admin App" with Postgresql

Flask "Blog App" with MongoDB - Part 1 (Local via Flask server)

Flask "Blog App" with MongoDB on Ubuntu 14 - Part 2 (Local Apache WSGI)

Flask "Blog App" with MongoDB on CentOS 7 - Part 3 (Production Apache WSGI )

Flask word count app 1 with PostgreSQL and Flask-SQLAlchemy

Flask word count app 2 via BeautifulSoup, and Natural Language Toolkit (NLTK) with Gunicorn/PM2/Apache

Flask word count app 3 with Redis task queue

Flask word count app 4 with AngularJS polling the back-end

Flask word count app 5 with AngularJS front-end updates and submit error handling

Flask word count app 0 - Errors and Fixes

Flask with Embedded Machine Learning I : Serializing with pickle and DB setup

Flask with Embedded Machine Learning II : Basic Flask App

Flask with Embedded Machine Learning III : Embedding Classifier

Flask with Embedded Machine Learning IV : Deploy

Flask with Embedded Machine Learning V : Updating the classifier

Flask AJAX with jQuery

Flask blog app with Dashboard 1 - SignUp page

Flask blog app with Dashboard 2 - Sign-In / Sign-Out

Flask blog app with Dashboard 3 - Adding blog post item

Flask blog app with Dashboard 4 - Update / Delete

Flask blog app with Dashboard 5 - Uploading an image

Flask blog app with Dashboard 6 - Dash board

Flask blog app with Dashboard 7 - Like button

Flask blog app with Dashboard 8 - Deploy

Flask blog app with Dashboard - Appendix (tables and mysql stored procedures/functions

Sponsor Open Source development activities and free contents for everyone.

Thank you.

- K Hong






Python tutorial



Python Home

Introduction

Running Python Programs (os, sys, import)

Modules and IDLE (Import, Reload, exec)

Object Types - Numbers, Strings, and None

Strings - Escape Sequence, Raw String, and Slicing

Strings - Methods

Formatting Strings - expressions and method calls

Files and os.path

Traversing directories recursively

Subprocess Module

Regular Expressions with Python

Regular Expressions Cheat Sheet

Object Types - Lists

Object Types - Dictionaries and Tuples

Functions def, *args, **kargs

Functions lambda

Built-in Functions

map, filter, and reduce

Decorators

List Comprehension

Sets (union/intersection) and itertools - Jaccard coefficient and shingling to check plagiarism

Hashing (Hash tables and hashlib)

Dictionary Comprehension with zip

The yield keyword

Generator Functions and Expressions

generator.send() method

Iterators

Classes and Instances (__init__, __call__, etc.)

if__name__ == '__main__'

argparse

Exceptions

@static method vs class method

Private attributes and private methods

bits, bytes, bitstring, and constBitStream

json.dump(s) and json.load(s)

Python Object Serialization - pickle and json

Python Object Serialization - yaml and json

Priority queue and heap queue data structure

Graph data structure

Dijkstra's shortest path algorithm

Prim's spanning tree algorithm

Closure

Functional programming in Python

Remote running a local file using ssh

SQLite 3 - A. Connecting to DB, create/drop table, and insert data into a table

SQLite 3 - B. Selecting, updating and deleting data

MongoDB with PyMongo I - Installing MongoDB ...

Python HTTP Web Services - urllib, httplib2

Web scraping with Selenium for checking domain availability

REST API : Http Requests for Humans with Flask

Blog app with Tornado

Multithreading ...

Python Network Programming I - Basic Server / Client : A Basics

Python Network Programming I - Basic Server / Client : B File Transfer

Python Network Programming II - Chat Server / Client

Python Network Programming III - Echo Server using socketserver network framework

Python Network Programming IV - Asynchronous Request Handling : ThreadingMixIn and ForkingMixIn

Python Coding Questions I

Python Coding Questions II

Python Coding Questions III

Python Coding Questions IV

Python Coding Questions V

Python Coding Questions VI

Python Coding Questions VII

Python Coding Questions VIII

Python Coding Questions IX

Python Coding Questions X

Image processing with Python image library Pillow

Python and C++ with SIP

PyDev with Eclipse

Matplotlib

Redis with Python

NumPy array basics A

NumPy Matrix and Linear Algebra

Pandas with NumPy and Matplotlib

Celluar Automata

Batch gradient descent algorithm

Longest Common Substring Algorithm

Python Unit Test - TDD using unittest.TestCase class

Simple tool - Google page ranking by keywords

Google App Hello World

Google App webapp2 and WSGI

Uploading Google App Hello World

Python 2 vs Python 3

virtualenv and virtualenvwrapper

Uploading a big file to AWS S3 using boto module

Scheduled stopping and starting an AWS instance

Cloudera CDH5 - Scheduled stopping and starting services

Removing Cloud Files - Rackspace API with curl and subprocess

Checking if a process is running/hanging and stop/run a scheduled task on Windows

Apache Spark 1.3 with PySpark (Spark Python API) Shell

Apache Spark 1.2 Streaming

bottle 0.12.7 - Fast and simple WSGI-micro framework for small web-applications ...

Flask app with Apache WSGI on Ubuntu14/CentOS7 ...

Selenium WebDriver

Fabric - streamlining the use of SSH for application deployment

Ansible Quick Preview - Setting up web servers with Nginx, configure enviroments, and deploy an App

Neural Networks with backpropagation for XOR using one hidden layer

NLP - NLTK (Natural Language Toolkit) ...

RabbitMQ(Message broker server) and Celery(Task queue) ...

OpenCV3 and Matplotlib ...

Simple tool - Concatenating slides using FFmpeg ...

iPython - Signal Processing with NumPy

iPython and Jupyter - Install Jupyter, iPython Notebook, drawing with Matplotlib, and publishing it to Github

iPython and Jupyter Notebook with Embedded D3.js

Downloading YouTube videos using youtube-dl embedded with Python

Machine Learning : scikit-learn ...

Django 1.6/1.8 Web Framework ...









Contact

BogoToBogo
contactus@bogotobogo.com

Follow Bogotobogo

About Us

contactus@bogotobogo.com

YouTubeMy YouTube channel
Pacific Ave, San Francisco, CA 94115

Pacific Ave, San Francisco, CA 94115

Copyright © 2024, bogotobogo
Design: Web Master