article

Saturday, February 29, 2020

Python Flask CRUD Simple application with authentication


Python Flask CRUD Simple application with authentication

Python Flask CRUD (Create, read, update and delete) Simple application with authentication and Mysql, bootstrap

Table `user_flask`

CREATE TABLE `user_flask` (
  `id` int(11) NOT NULL,
  `name` varchar(255) NOT NULL,
  `email` varchar(150) NOT NULL,
  `username` varchar(100) NOT NULL,
  `password` varchar(200) NOT NULL

) ENGINE=InnoDB DEFAULT CHARSET=latin1;

ALTER TABLE `user_flask`
  ADD PRIMARY KEY (`id`);

ALTER TABLE `user_flask`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=3;
COMMIT;

Table structure for table `articles`

CREATE TABLE `articles` (
  `id` int(8) NOT NULL,
  `title` varchar(255) NOT NULL,
  `body` text NOT NULL,
  `create_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `author` varchar(200) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

--
-- Indexes for table `articles`
--
ALTER TABLE `articles`
  ADD PRIMARY KEY (`id`),
  ADD KEY `date` (`create_date`);

ALTER TABLE `articles`
  MODIFY `id` int(8) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=4;
COMMIT;
 
#app.py
from flask import Flask, render_template, flash, redirect, url_for, session, request, logging
from flaskext.mysql import MySQL
import pymysql
from wtforms import Form, StringField, TextAreaField, PasswordField, validators
from passlib.hash import sha256_crypt
from functools import wraps

app = Flask(__name__)
app.secret_key = "Cairocoders-Ednalan"
 
mysql = MySQL()
  
# MySQL configurations
app.config['MYSQL_DATABASE_USER'] = 'root'
app.config['MYSQL_DATABASE_PASSWORD'] = ''
app.config['MYSQL_DATABASE_DB'] = 'testingdb'
app.config['MYSQL_DATABASE_HOST'] = 'localhost'
mysql.init_app(app)
 
# Register Form Class
class RegisterForm(Form):
    name = StringField('Name', [validators.Length(min=1, max=50)])
    username = StringField('Username', [validators.Length(min=4, max=25)])
    email = StringField('Email', [validators.Length(min=6, max=50)])
    password = PasswordField('Password', [
        validators.DataRequired(),
        validators.EqualTo('confirm', message='Passwords do not match')
    ])
    confirm = PasswordField('Confirm Password')

# Article Form Class
class ArticleForm(Form):
    title = StringField('Title', [validators.Length(min=1, max=200)])
    body = TextAreaField('Body', [validators.Length(min=30)])
 
# Index
@app.route('/')
def index():
    return render_template('home.html')
 
# About
@app.route('/about')
def about():
    return render_template('about.html')

# Articles
@app.route('/articles')
def articles():
    # Create cursor
    conn = mysql.connect()
    cur = conn.cursor(pymysql.cursors.DictCursor)
 
    # Get articles
    result = cur.execute("SELECT * FROM articles")
    articles = cur.fetchall()
    if result > 0:
        return render_template('articles.html', articles=articles)
    else:
        msg = 'No Articles Found'
        return render_template('articles.html', msg=msg)
    # Close connection
    cur.close()

#Single Article
@app.route('/article//')
def article(id):
    # Create cursor
    conn = mysql.connect()
    cur = conn.cursor(pymysql.cursors.DictCursor)
 
    # Get article
    result = cur.execute("SELECT * FROM articles WHERE id = %s", [id])
    article = cur.fetchone()
    return render_template('article.html', article=article)
 
# User Register
@app.route('/register', methods=['GET', 'POST'])
def register():
    form = RegisterForm(request.form)
    if request.method == 'POST' and form.validate():
        name = form.name.data
        email = form.email.data
        username = form.username.data
        password = sha256_crypt.encrypt(str(form.password.data))
         
        conn = mysql.connect()
        cur = conn.cursor(pymysql.cursors.DictCursor)
        # Execute query
        cur.execute("INSERT INTO user_flask(name, email, username, password) VALUES(%s, %s, %s, %s)", (name, email, username, password))
        # Commit to DB
        conn.commit()
        # Close connection
        cur.close()
        flash('You are now registered and can log in', 'success')
        return redirect(url_for('login'))
    return render_template('register.html', form=form)

# User login
@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        # Get Form Fields
        username = request.form['username']
        password_candidate = request.form['password']
 
        conn = mysql.connect()
        cur = conn.cursor(pymysql.cursors.DictCursor)
 
        # Get user by username
        result = cur.execute("SELECT * FROM user_flask WHERE username = %s", [username])
 
        if result > 0:
            # Get stored hash
            data = cur.fetchone()
            password = data['password']
 
            # Compare Passwords
            if sha256_crypt.verify(password_candidate, password):
                # Passed
                session['logged_in'] = True
                session['username'] = username
 
                flash('You are now logged in', 'success')
                return redirect(url_for('dashboard'))
            else:
                error = 'Invalid login'
                return render_template('login.html', error=error)
            # Close connection
            cur.close()
        else:
            error = 'Username not found'
            return render_template('login.html', error=error)
 
    return render_template('login.html')

# Check if user logged in
def is_logged_in(f):
    @wraps(f)
    def wrap(*args, **kwargs):
        if 'logged_in' in session:
            return f(*args, **kwargs)
        else:
            flash('Unauthorized, Please login', 'danger')
            return redirect(url_for('login'))
    return wrap

# Logout
@app.route('/logout')
@is_logged_in
def logout():
    session.clear()
    flash('You are now logged out', 'success')
    return redirect(url_for('login'))
 
# Dashboard
@app.route('/dashboard')
@is_logged_in
def dashboard():
    # Create cursor
    conn = mysql.connect()
    cur = conn.cursor(pymysql.cursors.DictCursor)
 
    # Get articles
    #result = cur.execute("SELECT * FROM articles")
    # Show articles only from the user logged in 
    result = cur.execute("SELECT * FROM articles WHERE author = %s", [session['username']])
 
    articles = cur.fetchall()
 
    if result > 0:
        return render_template('dashboard.html', articles=articles)
    else:
        msg = 'No Articles Found'
        return render_template('dashboard.html', msg=msg)
    # Close connection
    cur.close()

# Add Article
@app.route('/add_article', methods=['GET', 'POST'])
@is_logged_in
def add_article():
    form = ArticleForm(request.form)
    if request.method == 'POST' and form.validate():
        title = form.title.data
        body = form.body.data
 
        # Create Cursor
        conn = mysql.connect()
        cur = conn.cursor(pymysql.cursors.DictCursor)
 
        # Execute
        cur.execute("INSERT INTO articles(title, body, author) VALUES(%s, %s, %s)",(title, body, session['username']))
        # Commit to DB
        conn.commit()
        #Close connection
        cur.close()
        flash('Article Created', 'success')
        return redirect(url_for('dashboard'))
    return render_template('add_article.html', form=form)

# Edit Article
@app.route('/edit_article/', methods=['GET', 'POST'])
@is_logged_in
def edit_article(id):
    # Create cursor
    conn = mysql.connect()
    cur = conn.cursor(pymysql.cursors.DictCursor)
 
    # Get article by id
    result = cur.execute("SELECT * FROM articles WHERE id = %s", [id])
    article = cur.fetchone()
    cur.close()
    # Get form
    form = ArticleForm(request.form)
    # Populate article form fields
    form.title.data = article['title']
    form.body.data = article['body']
 
    if request.method == 'POST' and form.validate():
        title = request.form['title']
        body = request.form['body']
        # Create Cursor
        cur = conn.cursor(pymysql.cursors.DictCursor)
        app.logger.info(title)
        # Execute
        cur.execute ("UPDATE articles SET title=%s, body=%s WHERE id=%s",(title, body, id))
        # Commit to DB
        conn.commit()
        #Close connection
        cur.close()
        flash('Article Updated', 'success')
        return redirect(url_for('dashboard'))
    return render_template('edit_article.html', form=form)
 
 
# Delete Article
@app.route('/delete_article/', methods=['POST'])
@is_logged_in
def delete_article(id):
    # Create cursor
    conn = mysql.connect()
    cur = conn.cursor(pymysql.cursors.DictCursor)
 
    # Execute
    cur.execute("DELETE FROM articles WHERE id = %s", [id])
    # Commit to DB
    conn.commit()
    #Close connection
    cur.close()
    flash('Article Deleted', 'success')
    return redirect(url_for('dashboard'))
 
if __name__ == '__main__':
 app.run(debug=True)
//home.html
{% extends 'layout.html' %}

{% block body %}
  <div class="jumbotron text-center">
    <h2>Python Flask CRUD (Create, read, update and delete) Simple application with authentication and Mysql</h2>
    <p class="lead">Python Flask CRUD (Create, read, update and delete) Simple application with authentication and Mysql</p>
    {% if session.logged_in == NULL %}
      <a href="/register" class="btn btn-primary btn-lg">Register</a>
      <a href="/login" class="btn btn-success btn-lg">Login</a>
    {% endif %}
  </div>
{% endblock %}
//layout.php
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Python Flask CRUD Simple application with authentication</title>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> 
<script src="https://cdn.datatables.net/1.10.16/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/1.10.16/js/dataTables.bootstrap4.min.js"></script>
  </head>
  <body>
 {% include 'includes/_navbar.html' %}
 <div class="container">
      {% include 'includes/_messages.html' %}
      {% block body %}{% endblock %}
    </div>
<style>
.container {padding-top:50px;}
</style>
<script type="text/javascript">
$(document).ready(function() {
    $('#articles').DataTable({     
      "aLengthMenu": [[3, 5, 10, 25, -1], [3, 5, 10, 25, "All"]],
        "iDisplayLength": 3
       } 
    );
} );

CKEDITOR.replace('editor')
</script>
  </body>
</html>
//templates/includes/_navbar.html
<nav class="navbar navbar-expand-lg navbar-light bg-light">
  <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarTogglerDemo01" aria-controls="navbarTogglerDemo01" aria-expanded="false" aria-label="Toggle navigation">
    <span class="navbar-toggler-icon"></span>
  </button>
  <div class="collapse navbar-collapse" id="navbarTogglerDemo01">
    <a class="navbar-brand" href="#">Cairocoders</a>
    <ul class="navbar-nav mr-auto mt-2 mt-lg-0">
      <li class="nav-item active">
        <a class="nav-link" href="/">Home <span class="sr-only">(current)</span></a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="/about">About</a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="/articles">Articles</a>
      </li>
    </ul>
     <ul class="nav navbar-nav navbar-right">
            {% if session.logged_in %}
              <li class="nav-item"><a class="nav-link" href="/dashboard">Dashboard</a></li>
              <li class="nav-item"><a class="nav-link" href="/logout">Logout</a></li>
            {% else %}
              <li class="nav-item"><a class="nav-link" href="/register">Register</a></li>
              <li class="nav-item"><a class="nav-link" href="/login">Login</a></li>
            {% endif %}

          </ul>
  </div>
</nav>
//templates/includes/_messages.html
{% with messages = get_flashed_messages(with_categories=true) %}
  {% if messages %}
    {% for category, message in messages %}
      <div class="alert alert-{{ category }}">{{ message }}</div>
    {% endfor %}
  {% endif %}
{% endwith %}

{% if error %}
  <div class="alert alert-danger">{{error}}</div>
{% endif %}

{% if msg %}
  <div class="alert alert-success">{{msg}}</div>
{% endif %}
//templates/includes/_formhelpers.html
{% macro render_field(field) %}
  {{ field.label }}
  {{ field(**kwargs)|safe }}
  {% if field.errors %}
    {% for error in field.errors %}
      <span class="help-inline">{{ error }}</span>
    {% endfor %}
  {% endif %}
{% endmacro %}
//templates/about.html
{% extends 'layout.html' %}

{% block body %}
  <h1>About Us</h1>
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
{% endblock %}
//templates/articles.html
{% extends 'layout.html' %}

{% block body %}
  <h1>Articles</h1>
  <ul class="list-group">
    {% for article in articles %}
      <li class="list-group-item"><a href="article/{{article.id}}">{{article.title}}</a></li>
    {% endfor %}
  </ul>
{% endblock %}
//templates/article.html
{% extends 'layout.html' %}

{% block body %}
  <h1>{{article.title}}</h1>
  <small>Written by {{article.author}} on {{article.create_date}}</small>
  <hr>
  <div>
    {{article.body | safe}}
  </div>
{% endblock %}
//templates/register.html
{% extends 'layout.html' %}

{% block body %}
  <h1>Register</h1>
  {% from "includes/_formhelpers.html" import render_field %}
  <form method="POST" action="">
    <div class="form-group">
      {{render_field(form.name, class_="form-control")}}
    </div>
    <div class="form-group">
      {{render_field(form.email, class_="form-control")}}
    </div>
    <div class="form-group">
      {{render_field(form.username, class_="form-control")}}
    </div>
    <div class="form-group">
      {{render_field(form.password, class_="form-control")}}
    </div>
    <div class="form-group">
      {{render_field(form.confirm, class_="form-control")}}
    </div>
    <p><input type="submit" class="btn btn-primary" value="Submit"></p>
  </form>
{% endblock %}
//templates/login.html
{% extends 'layout.html' %}

{% block body %}
  <h1>Login</h1>
  <form action="" method="POST">
    <div class="form-group">
      <label>Username</label>
      <input type="text" name="username" class="form-control" value={{request.form.username}}>
    </div>
    <div class="form-group">
      <label>Password</label>
      <input type="password" name="password" class="form-control" value={{request.form.password}}>
    </div>
    <button type="submit" class="btn btn-primary">Submit</button>
  </form>
{% endblock %}
//templates/dashboard.html
{% extends 'layout.html' %}

{% block body %}
  <h1>Dashboard <small> Welcome {{session.username}}</small></h1>
  <a class="btn btn-success" href="/add_article"> Add Article</a>
  <hr>
  <table class="table table-striped">
    <tr>
      <th>ID</th>
      <th>Title</th>
      <th>Author</th>
      <th>Date</th>
      <th></th>
      <th></th>
    </tr>
    {% for article in articles %}
      <tr>
        <td>{{article.id}}</td>
        <td>{{article.title}}</td>
        <td>{{article.author}}</td>
        <td>{{article.create_date}}</td>
        <td><a href="edit_article/{{article.id}}" class="btn btn-default pull-right">Edit</a></td>
        <td>
          <form action="{{url_for('delete_article', id=article.id)}}" method="post">
            <input type="hidden" name="_method" value="DELETE">
            <input type="submit" value="Delete" class="btn btn-danger">
          </form>
        </td>
      </tr>
    {% endfor %}
  </table>
{% endblock %}
//templates/add_article.html
{% extends 'layout.html' %}

{% block body %}
  <h1>Add Article</h1>
  {% from "includes/_formhelpers.html" import render_field %}
  <form method="POST" action="">
    <div class="form-group">
      {{ render_field(form.title, class_="form-control") }}
    </div>
    <div class="form-group">
      {{ render_field(form.body, class_="form-control", id="editor") }}
    </div>
    <p><input class="btn btn-primary" type="submit" value="Submit">
  </form>
{% endblock %}
//templates/edit_article.html
{% extends 'layout.html' %}

{% block body %}
  <h1>Edit Article</h1>
  {% from "includes/_formhelpers.html" import render_field %}
  <form method="POST" action="">
    <div class="form-group">
      {{ render_field(form.title, class_="form-control") }}
    </div>
    <div class="form-group">
      {{ render_field(form.body, class_="form-control", id="editor") }}
    </div>
    <p><input class="btn btn-primary" type="submit" value="Submit">
  </form>
{% endblock %}

Friday, February 28, 2020

Python Flask Multiple Files Upload


Python Flask Multiple Files Upload

#app.py
from flask import Flask, render_template, flash, request, redirect
from werkzeug.utils import secure_filename
import os
#import magic
import urllib.request

app = Flask(__name__)

UPLOAD_FOLDER = 'C:/flaskmyproject/demoapp/static'

app.secret_key = "Cairocoders-Ednalan"
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024

ALLOWED_EXTENSIONS = set(['txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'])

def allowed_file(filename):
 return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
 
@app.route('/')
def upload_form():
 return render_template('upload.html')

@app.route('/', methods=['POST'])
def upload_file():
 if request.method == 'POST':
        # check if the post request has the files part
  if 'files[]' not in request.files:
   flash('No file part')
   return redirect(request.url)
  files = request.files.getlist('files[]')
  for file in files:
   if file and allowed_file(file.filename):
    filename = secure_filename(file.filename)
    file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
  flash('File(s) successfully uploaded')
  return redirect('/')
  
if __name__ == '__main__':
 app.run(debug=True)
//upload.html
<!DOCTYPE html>
<html>
<head>
 <title>Python Flask Multiple Files Upload</title>
 <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
 <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/js/bootstrap.min.js"></script>
 <script src="https://code.jquery.com/jquery-1.11.1.min.js"></script>
</head>
<div id="wrapper">
            <div id="page-wrapper">
                <div class="row">
                    <div class="container">
                        <div id="identitycard" style="margin-top:50px" class="mainbox col-md-6 col-md-offset-3 col-sm-8 col-sm-offset-2">
                            <div class="panel panel-info">
                                <div class="panel-heading">
                                    <div class="panel-title">Select file(s) to upload</div>
                                </div>
                                <div class="panel-body">
        <p>
         {% with messages = get_flashed_messages() %}
           {% if messages %}
          {% for message in messages %}
            <div class="alert alert-success">
             <strong>{{ message }}</strong>
           </div>
          {% endfor %}
           {% endif %}
         {% endwith %}
        </p>
                                    <div class="row">
                                        <p style="padding: 8px;" class="text-center">File to upload txt, pdf, png, jpg, jpeg, gif</p>
                                    </div>
                                    <div class="row" style="padding: 10px 15px 9px;">
                                        <form method="post" action="/" enctype="multipart/form-data">
                                            <div class="form-group"> 
                                                <div class="row" style="margin-bottom: 20px;">
                                                    <div class="col-md-12 col-sm-12 col-xs-12 col-lg-12 col-md-offset-3 col-sm-offset-3 col-xs-offset-2"> 
                                                        <input type="file" name="files[]" multiple="true" autocomplete="off" required> 
                                                    </div>
                                                </div>
                                                <div class="row text-center" style="padding-left: 20px;padding-right: 20px;">
             <input type="submit" value="Submit" class="btn btn-lg btn-block btn-success" style="border-radius: 50px;background-color:hover: #35832f;">
            </div>                                                 
                                            </div>                                                                                          
                                        </form>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
        </div>
</div>
</body>
</html>

Thursday, February 27, 2020

Shopping Cart using Python Flask MySQL


Shopping Cart using Python Flask MySQL

This shopping cart have no checkout option and payment option this is about to display product and add item to cart remove item from cart remove all items from cart

CREATE TABLE `product` (
  `pid` int(11) NOT NULL,
  `code` varchar(255) NOT NULL,
  `name` varchar(70) DEFAULT NULL,
  `image` varchar(255) NOT NULL,
  `category` varchar(70) DEFAULT NULL,
  `price` int(11) DEFAULT NULL,
  `discount` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

--
-- Dumping data for table `product`
--

INSERT INTO `product` (`pid`, `code`, `name`, `image`, `category`, `price`, `discount`) VALUES
(3, 'EDNALAN01', 'Samsung Galaxy A10S', '2.jpg', 'Mobile', 520, 100),
(4, 'EDNALAN02', 'Samsung Galaxy Win Duos', '3.jpg', 'Mobile', 1600, 500),
(5, 'EDNALAN03', 'Women Summer Spaghetti Strap Down', '4.jpg', 'Woman Dresess', 2020, 1250),
(6, 'EDNALAN04', 'Honda TMX Alpha Clamp', '5.jpg', 'Motorcycle', 320, 50);

ALTER TABLE `product`
  ADD PRIMARY KEY (`pid`);

ALTER TABLE `product`
  MODIFY `pid` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=250;
COMMIT;

 
#app.py
from flask import Flask, session, render_template, request, redirect, url_for
from flaskext.mysql import MySQL
import pymysql
from werkzeug import generate_password_hash, check_password_hash

app = Flask(__name__)
app.secret_key = "cairocoders-ednalan"

mysql = MySQL()

# MySQL configurations
app.config['MYSQL_DATABASE_USER'] = 'root'
app.config['MYSQL_DATABASE_PASSWORD'] = ''
app.config['MYSQL_DATABASE_DB'] = 'testingdb'
app.config['MYSQL_DATABASE_HOST'] = 'localhost'
mysql.init_app(app)

@app.route('/add', methods=['POST'])
def add_product_to_cart():
 cursor = None
 try:
  _quantity = int(request.form['quantity'])
  _code = request.form['code']
  # validate the received values
  if _quantity and _code and request.method == 'POST':
   conn = mysql.connect()
   cursor = conn.cursor(pymysql.cursors.DictCursor)
   cursor.execute("SELECT * FROM product WHERE code=%s", _code)
   row = cursor.fetchone()
   
   itemArray = { row['code'] : {'name' : row['name'], 'code' : row['code'], 'quantity' : _quantity, 'price' : row['price'], 'image' : row['image'], 'total_price': _quantity * row['price']}}
   
   all_total_price = 0
   all_total_quantity = 0
   
   session.modified = True
   if 'cart_item' in session:
    if row['code'] in session['cart_item']:
     for key, value in session['cart_item'].items():
      if row['code'] == key:
       old_quantity = session['cart_item'][key]['quantity']
       total_quantity = old_quantity + _quantity
       session['cart_item'][key]['quantity'] = total_quantity
       session['cart_item'][key]['total_price'] = total_quantity * row['price']
    else:
     session['cart_item'] = array_merge(session['cart_item'], itemArray)

    for key, value in session['cart_item'].items():
     individual_quantity = int(session['cart_item'][key]['quantity'])
     individual_price = float(session['cart_item'][key]['total_price'])
     all_total_quantity = all_total_quantity + individual_quantity
     all_total_price = all_total_price + individual_price
   else:
    session['cart_item'] = itemArray
    all_total_quantity = all_total_quantity + _quantity
    all_total_price = all_total_price + _quantity * row['price']
   
   session['all_total_quantity'] = all_total_quantity
   session['all_total_price'] = all_total_price
   
   return redirect(url_for('.products'))
  else:
   return 'Error while adding item to cart'
 except Exception as e:
  print(e)
 finally:
  cursor.close() 
  conn.close()
  
@app.route('/')
def products():
 try:
  conn = mysql.connect()
  cursor = conn.cursor(pymysql.cursors.DictCursor)
  cursor.execute("SELECT * FROM product")
  rows = cursor.fetchall()
  return render_template('products.html', products=rows)
 except Exception as e:
  print(e)
 finally:
  cursor.close() 
  conn.close()

@app.route('/empty')
def empty_cart():
 try:
  session.clear()
  return redirect(url_for('.products'))
 except Exception as e:
  print(e)

@app.route('/delete/')
def delete_product(code):
 try:
  all_total_price = 0
  all_total_quantity = 0
  session.modified = True
  
  for item in session['cart_item'].items():
   if item[0] == code:    
    session['cart_item'].pop(item[0], None)
    if 'cart_item' in session:
     for key, value in session['cart_item'].items():
      individual_quantity = int(session['cart_item'][key]['quantity'])
      individual_price = float(session['cart_item'][key]['total_price'])
      all_total_quantity = all_total_quantity + individual_quantity
      all_total_price = all_total_price + individual_price
    break
  
  if all_total_quantity == 0:
   session.clear()
  else:
   session['all_total_quantity'] = all_total_quantity
   session['all_total_price'] = all_total_price
  
  return redirect(url_for('.products'))
 except Exception as e:
  print(e)
  
def array_merge( first_array , second_array ):
 if isinstance( first_array , list ) and isinstance( second_array , list ):
  return first_array + second_array
 elif isinstance( first_array , dict ) and isinstance( second_array , dict ):
  return dict( list( first_array.items() ) + list( second_array.items() ) )
 elif isinstance( first_array , set ) and isinstance( second_array , set ):
  return first_array.union( second_array )
 return False 
 
if __name__ == '__main__':
 app.run(debug=True)
//product.html
<!DOCTYPE html>
<html>
<head>
 <title>Shopping Cart using Python Flask MySQL</title>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
</head>
<body>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"> 
<div class="container">
    <div class="row">
  <p><h2>Shopping Cart using Python Flask MySQL</h2></p>
        <div class="col-sm-12">
  <div>
   {% with messages = get_flashed_messages() %}
     {% if messages %}
    <ul class=flashes>
    {% for message in messages %}
      <li>{{ message }}</li>
    {% endfor %}
    </ul>
     {% endif %}
   {% endwith %}
  </div>
  {% if 'cart_item' in session %}
   <p><a id="btnEmpty" href="{{ url_for('.empty_cart') }}" class="btn btn-danger">Empty Cart</a></p>
            <table class="table table-hover">
                <thead>
                    <tr>
                        <th>Product</th>
                        <th>Quantity</th>
                        <th class="text-center">Unit Price</th>
                        <th class="text-center">Price</th>
                        <th> </th>
                    </tr>
                </thead>
                <tbody>
    {% for key, val in session['cart_item'].items() %}
     {% set quantity = session['cart_item'][key]['quantity'] %}
     {% set price = session['cart_item'][key]['price'] %}
     {% set item_price = session['cart_item'][key]['total_price'] %} 
                    <tr>
                        <td class="col-sm-8 col-md-6">
                        <div class="media">
                            <a class="thumbnail pull-left" href="#"> <img class="media-object" src="/static/images/product-images/{{ session['cart_item'][key]['image'] }}" style="width: 72px; height: 72px;"> </a>
                            <div class="media-body">
                                <h4 class="media-heading"> <a href="#">{{ session['cart_item'][key]['name'] }}</a></h4>
                                <h5 class="media-heading"> by <a href="#">Brand name</a></h5>
                                <span>Status: </span><span class="text-success"><strong>In Stock</strong></span>
                            </div>
                        </div></td>
                        <td class="col-sm-1 col-md-1" style="text-align: center">
                        <input type="email" class="form-control" value="{{ quantity }}">
                        </td>
                        <td class="col-sm-1 col-md-1 text-center"><strong>${{ price }} </strong></td>
                        <td class="col-sm-1 col-md-1 text-center"><strong>${{ item_price }} </strong></td>
                        <td class="col-sm-1 col-md-1">
                        <a href="{{ url_for('.delete_product', code=session['cart_item'][key]['code']) }}" class="btn btn-danger">
                            <span class="glyphicon glyphicon-remove"></span> Remove
                        </a></td>
                    </tr>
    {% endfor %}
                    <tr>
                        <td colspan="4"><h5>Total Quantity</h5></td>
                        <td class="text-right"><h5><strong>{{ session['all_total_quantity'] }}</strong></h5></td>
                    </tr>
                    <tr>
                        <td colspan="3"><h3>Total</h3></td>
                        <td colspan="2" class="text-right"><h3><strong>$ {{ session['all_total_price'] }}</strong></h3></td>
                    </tr>
                    <tr>
                        <td colspan="4">
                        <button type="button" class="btn btn-default">
                            <span class="glyphicon glyphicon-shopping-cart"></span> Continue Shopping
                        </button></td>
                        <td>
                        <button type="button" class="btn btn-success">
                            Checkout <span class="glyphicon glyphicon-play"></span>
                        </button></td>
                    </tr>
                </tbody>
            </table>
  {% else: %}
   <div class="no-records">Your Cart is Empty</div>
  {% endif %}
        </div>
    </div>
</div>
              
<section class="our-publication pt-100 pb-70">
            <div class="container">
                <div class="section-header">
                    <i class="fa fa-book"></i>
                    <h2>Our Product</h2>
                    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod  labore et dolore magna aliqua.</p>
                </div>
                
                <div class="row">
    {% for product in products %}
                    <div class="col-sm-6 col-lg-3"> 
      <form method="post" action="/add">
                        <div class="single-publication">
                            <figure style="width:263px;">
                                <a href="#">
                                    <img src="/static/images/product-images/{{ product.image }}">
                                </a>
                                <ul>
                                    <li><a href="#" title="Add to Favorite"><i class="fa fa-heart"></i></a></li>
                                    <li><a href="#" title="Add to Compare"><i class="fa fa-refresh"></i></a></li>
                                    <li><a href="#" title="Quick View"><i class="fa fa-search"></i></a></li>
                                </ul>
                            </figure>

                            <div class="publication-content">
                                <span class="category">{{ product.category }}</span>
                                <h3><a href="#">{{ product.name }}</a></h3>
                                <ul>
                                    <li><i class="icofont-star"></i></li>
                                    <li><i class="icofont-star"></i></li>
                                    <li><i class="icofont-star"></i></li>
                                    <li><i class="icofont-star"></i></li>
                                    <li><i class="icofont-star"></i></li>
                                </ul>
                                <h4 class="price">$ {{ product.price }}</h4>
                            </div>

                            <div class="add-to-cart">
        <input type="hidden" name="code" value="{{ product.code }}"/>
        <input type="text" class="product-quantity" name="quantity" value="1" size="2" />
        <input type="submit" value="Add to Cart" class="default-btn" />
                            </div>
                        </div>
      </form>
                    </div>
                {% endfor %}    
                    
                </div>
            </div>
        </section>
<style>
.pt-100 {
                padding-top: 100px;
            }
            .pb-70 {
                padding-bottom: 70px;
            }
            .section-header {
                margin-bottom: 60px;
                text-align: center;
            }
            .section-header i {
                color: #ff007d;
                font-size: 50px;
                display: inline-block;
                margin-bottom: 10px;
            }
            .section-header h2 {
                font-weight: bold;
                font-size: 34px;
                margin: 0;
            }
            .section-header p {
                max-width: 500px;
                margin: 20px auto 0;
            }
            .single-publication {
                border: 1px solid #f2eee2;
                margin-bottom: 30px;
                position: relative;
                overflow: hidden;
            }
            .single-publication figure {
                position: relative;
                margin: 0;
                text-align: center;
            }
            .single-publication figure > a {
                background-color: #fafafa;
                display: block;
            }
            .single-publication figure ul {
                list-style-type: none;
                padding: 0;
                margin: 0;
                position: absolute;
                right: -50px;
                top: 20px;
                transition: .6s;
                -webkit-transition: .6s;
            }
            .single-publication:hover figure ul {
                right: 15px;
            }
            .single-publication figure ul li a {
                display: inline-block;
                width: 35px;
                height: 35px;
                text-align: center;
                font-size: 15px;
                background: #ff007d;
                margin-bottom: 7px;
                border-radius: 50%;
                line-height: 35px;
                color: #fff;
            }
            .single-publication figure ul li a:hover {
                color: #fff;
                background: #e50663;
            }
            .single-publication .publication-content {
                text-align: center;
                padding: 20px;
            }
            .single-publication .publication-content .category {
                display: inline-block;
                font-family: 'Open Sans', sans-serif;
                font-size: 14px;
                color: #ff007d;
                font-weight: 600;
            }
            .single-publication .publication-content h3 {
                font-weight: 600;
                margin: 8px 0 10px;
                font-size: 20px;
            }
            .single-publication .publication-content h3 a {
                color: #1f2d30;
            }
            .single-publication .publication-content h3 a:hover {
                color: #ff007d;
            }
            .single-publication .publication-content ul {
                list-style-type: none;
                padding: 0;
                margin: 0;
                margin-bottom: 15px;
            }
            .single-publication .publication-content ul li {
                display: inline-block;
                font-size: 18px;
                color: #fec42d;
            }
            .single-publication .publication-content .price {
                font-size: 18px;
                color: #ff007d;
            }
            .single-publication .publication-content .price span {
                color: #6f6f6f;
                text-decoration: line-through;
                padding-left: 5px;
                font-weight: 300;
            }
            .single-publication .add-to-cart {
                position: absolute;
                right: 0;
                bottom: 0;
                left: 0;
                background: #fff;
                opacity: 0;
                visibility: hidden;
                text-align: center;
                -webkit-transform: scale(.7);
                transform: scale(.7);
                height: 105px;
                -moz-transition: .4s;
                -webkit-transition: .4s;
                transition: .4s;
            }
            .single-publication:hover .add-to-cart {
                visibility: visible;
                transform: scale(1);
                -webkit-transform: scale(1);
                opacity: 1;
            }
            .single-publication .add-to-cart .default-btn {
                margin-top: 28px;
                padding: 8px 25px;
                font-size: 14px;
            }
            .single-publication .category {
                margin: 0;
            }
            .single-publication .add-to-cart .default-btn {
                margin-top: 28px;
                padding: 8px 25px;
                font-size: 14px;
            }
            .default-btn {
                background-color: #ff007d;
                color: #fff;
                border: 1px solid #ff007d;
                display: inline-block;
                padding: 10px 30px;
                border-radius: 30px;
                text-transform: uppercase;
                font-weight: 600;
                font-family: 'Open Sans', sans-serif;
            }
            .default-btn:hover {
                color: #fff;
                text-decoration: none;
            }
</style>  
</body>
</html>
<//html>

Wednesday, February 26, 2020

Python Flask Parent and child Templates


Python Flask Parent and child Templates

 
#app.py
from flask import Flask, render_template, url_for, request, jsonify
from datetime import datetime

app = Flask(__name__)

@app.context_processor
def inject_now():
    return {'now': datetime.utcnow()}

@app.route('/')
def home():
 return render_template('index.html')
 
@app.route('/about')
def about():
 return render_template('about.html')
 
@app.route('/testimonials')
def testimonials():
 return render_template('testimonials.html')
 
@app.route('/contact')
def contact():
 return render_template('contact.html')
 
@app.route('/products')
def products():
 return render_template('products.html') 
  
if __name__ == '__main__':
 app.run(debug=True)
//parent.html
<!DOCTYPE html>
<html>
 <head>
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Python Flask Parent and child Templates - {% block title %}{% endblock %}</title>
  {% block head %}   
  {% endblock %}
 </head>
<body>
 {% include "snippets/header.html" %}
 <div class="row">
  <div class="col-s-3">
   {% include "snippets/left.html" %}
  </div> 
  <div class="col-s-9">
   {% block content %}{% endblock %}
  </div>
 </div>
 {% include "snippets/footer.html" %}
</body>
</html>
//index.html
{% extends "parent.html" %}
{% block title %}Welcome{% endblock %}

{% block content %}
    <h1>Welcome</h1>
    <p>
  Welcome to working with parent and child templates in flask
 </p>
{% endblock %}
//about.html
{% extends "parent.html" %}
{% block title %}About Us{% endblock %}

{% block content %}
    <h1>About</h1>
    <p>
  this is about page
 </p>
{% endblock %}
//testimonials.html
{% extends "parent.html" %}
{% block title %}Testimonials{% endblock %}

{% block content %}
    <h1>Testimonials</h1>
    <p>
  This is testimonials page
 </p>
{% endblock %}
//contact.html
{% extends "parent.html" %}
{% block title %}Contact Us{% endblock %}

{% block content %}
    <h1>Contact Us </h1>
    <p>
  This is Contact Us page
 </p>
{% endblock %}

Sunday, February 23, 2020

Python Flask Mysql Login Logout with Remember Me Option and Password Hash


Python Flask Mysql Login Logout with Remember Me Option and Password Hash


This tutorial we are going to see how to give users to remember their login credentials through cookie and password in the database is in hash

Database Table

CREATE TABLE `user_test_flask` (
  `id` int(10) UNSIGNED NOT NULL,
  `name` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `username` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
  `email` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `pwd` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `admin` tinyint(4) DEFAULT '0',
  `last_login` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

Dumping data for table `user_test_flask`

INSERT INTO `user_test_flask` (`id`, `name`, `username`, `email`, `pwd`, `admin`, `last_login`) VALUES

(1, 'Cairocoders Ednalan', 'test2', 'test2@gmail.com', 'pbkdf2:sha256:150000$QYp0kc3v$88fb99cca1479b212dfdf7f58199e7207693a9cc187065b7dbe7837f3cd4872c', 0, '2020-02-22 02:26:21')

ALTER TABLE `user_test_flask`
  ADD PRIMARY KEY (`id`);

ALTER TABLE `user_test_flask`
  MODIFY `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=2;

Login
Email : test2@gmail.com
Password : test2


#app.py
from flask import Flask, render_template, url_for, flash, session, request, redirect, make_response
from flaskext.mysql import MySQL
import pymysql
from datetime import timedelta
from werkzeug import generate_password_hash, check_password_hash

app = Flask(__name__)

app.secret_key = "caircocoders-ednalan-2020"
app.config['PERMANENT_SESSION_LIFETIME'] =  timedelta(minutes=10)

global COOKIE_TIME_OUT
#COOKIE_TIME_OUT = 60*60*24*7 #7 days
COOKIE_TIME_OUT = 60*5 #5 minutes

#Database Configuration
mysql = MySQL()

# MySQL configurations
app.config['MYSQL_DATABASE_USER'] = 'root'
app.config['MYSQL_DATABASE_PASSWORD'] = ''
app.config['MYSQL_DATABASE_DB'] = 'testingdb'
app.config['MYSQL_DATABASE_HOST'] = 'localhost'
mysql.init_app(app)

@app.route('/')
def index():
 if 'email' in session:
  username = session['email']
  return 'Logged in as ' + username + '<br>' + "<b><a href = '/logout'>Click here to logout</a></b>"
 return "You are not logged in <br><a href = '/login'></b>" + "click here to login</b></a>"
 
@app.route('/login')
def login():
 return render_template('login_logout_with_rememberme.html')

@app.route('/submit', methods=['POST'])
def login_submit():
 conn = None
 cursor = None
 
 _email = request.form['inputEmail']
 _password = request.form['inputPassword']
 _remember = request.form.getlist('inputRemember')
 
 if 'email' in request.cookies:
  username = request.cookies.get('email')
  password = request.cookies.get('pwd')
  conn = mysql.connect()
  cursor = conn.cursor()
  sql = "SELECT * FROM user_test_flask WHERE email=%s"
  sql_where = (username,)
  cursor.execute(sql, sql_where)
  row = cursor.fetchone()
  if row and check_password_hash(row[4], password):
   print(username + ' ' + password)
   session['email'] = row[3]
   cursor.close()
   conn.close()
   return redirect('/')
  else:
   return redirect('/login')
 # validate the received values
 elif _email and _password:
  #check user exists   
  conn = mysql.connect()
  cursor = conn.cursor()
  sql = "SELECT * FROM user_test_flask WHERE email=%s"
  sql_where = (_email,)
  cursor.execute(sql, sql_where)
  row = cursor.fetchone()
  if row:
   if check_password_hash(row[4], _password):
    session['email'] = row[3]
    cursor.close() 
    conn.close()
    if _remember:
     resp = make_response(redirect('/'))
     resp.set_cookie('email', row[3], max_age=COOKIE_TIME_OUT)
     resp.set_cookie('pwd', _password, max_age=COOKIE_TIME_OUT)
     resp.set_cookie('rem', 'checked', max_age=COOKIE_TIME_OUT)
     return resp
    return redirect('/')
   else:
    flash('Invalid Password!')
    return redirect('/login')
  else:
   flash('Invalid Email Or Password!')
   return redirect('/login')
 else:
  flash('Invalid Email Or Password!')
  return redirect('/login')
  
@app.route('/logout')
def logout():
 if 'email' in session:
  session.pop('email', None)
 return redirect('/')
 
if __name__ == '__main__':
 app.run(debug=True)

//login_logout_with_rememberme.html
<html>
<title>Python Flask Mysql Login Logout with Remember Me Option and Password Hash</title>
 <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
 <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.1/css/all.css">
</head>
<body>
 <div class="container h-100">
  <h4 align="center">Python Flask Mysql Login Logout with Remember Me Option and Password Hash</h4>
  <div class="d-flex justify-content-center h-100">
   <div class="user_card">
    <div class="d-flex justify-content-center">
     <div class="brand_logo_container">
      <img src="{{ url_for('static', filename='img/logo.png') }}" class="brand_logo" alt="Logo">
     </div>
    </div>
    <div class="d-flex justify-content-center form_container">
     <form method="post" action="/submit">
      <div class="input-group mb-3">
       <div class="input-group-append">
        <span class="input-group-text"><i class="fas fa-user"></i></span>
       </div>
       <input type="text" name="inputEmail" value="{% if 'email' in request.cookies %} {{ request.cookies.get('email') }} {% endif %}" placeholder="Email" required class="form-control input_user">
      </div>
      <div class="input-group mb-2">
       <div class="input-group-append">
        <span class="input-group-text"><i class="fas fa-key"></i></span>
       </div>
       <input type="password" name="inputPassword" value="{% if 'pwd' in request.cookies %} {{ request.cookies.get('pwd') }} {% endif %}" placeholder="Password" autocomplete="off" required class="form-control input_pass" value="">
      </div>
      <div class="form-group">
       <div class="custom-control custom-checkbox">
        <input type="checkbox" name="inputRemember" checked="{% if 'rem' in request.cookies %} {{ request.cookies.get('rem') }} {% endif %}" autocomplete="off" class="custom-control-input" id="customControlInline">
        <label class="custom-control-label" for="customControlInline">Remember me</label>
       </div>
      </div>
       <div class="d-flex justify-content-center mt-3 login_container">
       <input type="submit" value="Login" class="btn login_btn">
       </div>
     </form>
    </div>
  
    <div class="mt-4">
    <div>
     {% with messages = get_flashed_messages() %}
       {% if messages %}
      {% for message in messages %}
      <div class="alert alert-danger" role="alert">{{ message }}</div>
      {% endfor %}
       {% endif %}
     {% endwith %}
    </div>
     <div class="d-flex justify-content-center links">
      Don't have an account? <a href="#" class="ml-2">Sign Up</a>
     </div>
     <div class="d-flex justify-content-center links">
      <a href="#">Forgot your password?</a>
     </div>
    </div>
   </div>
  </div>
 </div>
<style>
  body,
  html {
   margin: 0;
   padding: 0;
   height: 100%;
   background: #60a3bc !important;
  }
  .user_card {
   height: 450px;
   width: 350px;
   margin-top: auto;
   margin-bottom: auto;
   background: #f39c12;
   position: relative;
   display: flex;
   justify-content: center;
   flex-direction: column;
   padding: 10px;
   box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
   -webkit-box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
   -moz-box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
   border-radius: 5px;

  }
  .brand_logo_container {
   position: absolute;
   height: 170px;
   width: 170px;
   top: -75px;
   border-radius: 50%;
   background: #60a3bc;
   padding: 10px;
   text-align: center;
  }
  .brand_logo {
   height: 150px;
   width: 150px;
   border-radius: 50%;
   border: 2px solid white;
  }
  .form_container {
   margin-top: 100px;
  }
  .login_btn {
   width: 100%;
   background: #c0392b !important;
   color: white !important;
  }
  .login_btn:focus {
   box-shadow: none !important;
   outline: 0px !important;
  }
  .login_container {
   padding: 0 2rem;
  }
  .input-group-text {
   background: #c0392b !important;
   color: white !important;
   border: 0 !important;
   border-radius: 0.25rem 0 0 0.25rem !important;
  }
  .input_user,
  .input_pass:focus {
   box-shadow: none !important;
   outline: 0px !important;
  }
  .custom-checkbox .custom-control-input:checked~.custom-control-label::before {
   background-color: #c0392b !important;
  }
</style> 
</body>
</html>

Saturday, February 22, 2020

Generate CSV Report File using Python Flask MySQL


Generate CSV Report File using Python Flask MySQL

Database Table
CREATE TABLE `employees` (
  `id` int(10) UNSIGNED NOT NULL,
  `first_name` varchar(30) COLLATE utf8mb4_unicode_ci NOT NULL,
  `last_name` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL,
  `mgr_id` int(11) DEFAULT NULL,
  `designation` varchar(30) COLLATE utf8mb4_unicode_ci DEFAULT NULL

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

ALTER TABLE `employees`

  ADD PRIMARY KEY (`id`);

ALTER TABLE `employees`

  MODIFY `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=1;

 
#app.py
from flask import Flask, render_template, url_for, Response
from flaskext.mysql import MySQL
import pymysql
import io
import csv

app = Flask(__name__)
#Database Configuration
mysql = MySQL()

# MySQL configurations
app.config['MYSQL_DATABASE_USER'] = 'root'
app.config['MYSQL_DATABASE_PASSWORD'] = ''
app.config['MYSQL_DATABASE_DB'] = 'testingdb'
app.config['MYSQL_DATABASE_HOST'] = 'localhost'
mysql.init_app(app)


@app.route('/')
def download():
 return render_template('download_csv.html')

@app.route('/download/report/csv')
def download_report():
 conn = None
 cursor = None
 try:
  conn = mysql.connect()
  cursor = conn.cursor(pymysql.cursors.DictCursor)
  
  cursor.execute("SELECT id, first_name, last_name, designation FROM employees")
  result = cursor.fetchall()

  output = io.StringIO()
  writer = csv.writer(output)
  
  line = ['Id, First Name, Last Name, Designation']
  writer.writerow(line)

  for row in result:
   line = [str(row['id']) + ',' + row['first_name'] + ',' + row['last_name'] + ',' + row['designation']]
   writer.writerow(line)

  output.seek(0)
  
  return Response(output, mimetype="text/csv", headers={"Content-Disposition":"attachment;filename=employee_report.csv"})
 except Exception as e:
  print(e)
 finally:
  cursor.close() 
  conn.close()
 
if __name__ == '__main__':
 app.run(debug=True)
//download_csv.html
<html>
<head>
 <meta charset="UTF-8">
<title>Generate CSV Report File using Python Flask MySQL</title>
</head>
<body>
<h2>Generate CSV Report File using Python Flask MySQL</h2>
<p>
 <a href="{{ url_for('download_report') }}">Generate CSV Report File</a>
</p>
</body>
</html>

Friday, February 21, 2020

Check Availability username with Python Flask Jquery AJAX, MySQL


Check Availability username with Python Flask Jquery AJAX, MySQL

#app.py
from flask import Flask, render_template, url_for, request, json, jsonify
from flaskext.mysql import MySQL
import pymysql

app = Flask(__name__)

mysql = MySQL()
 
# MySQL configurations
app.config['MYSQL_DATABASE_USER'] = 'root'
app.config['MYSQL_DATABASE_PASSWORD'] = ''
app.config['MYSQL_DATABASE_DB'] = 'testingdb'
app.config['MYSQL_DATABASE_HOST'] = 'localhost'
mysql.init_app(app)
 
@app.route('/user_check', methods=['POST'])
def username_check():
 conn = None
 cursor = None
 try:
  username = request.form['username']
  
  # validate the received values
  if username and request.method == 'POST':  
   conn = mysql.connect()
   cursor = conn.cursor(pymysql.cursors.DictCursor)
   
   cursor.execute("SELECT * FROM user_test_flask WHERE username=%s", username)
   row = cursor.fetchone()
   
   if row:
    resp = jsonify('Username unavailable')
    resp.status_code = 200
    return resp
   else:
    resp = jsonify('Username available')
    resp.status_code = 200
    return resp
  else:
   resp = jsonify('Username is required field.')
   resp.status_code = 200
   return resp
 except Exception as e:
  print(e)
 finally:
  cursor.close() 
  conn.close()
  
@app.route('/')
def home():
 return render_template('username.html')
 
  
if __name__ == '__main__':
 app.run(debug=True)
//username.html
<!DOCTYPE html>
<html>
<head>
 <meta charset="UTF-8">
 <title>Check Availability username with Python Flask Jquery AJAX, MySQL</title>
 <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
</head>
<body>
 <div style="margin: 10px 0 0 10px;width: 600px">
  <h3>Check Availability username with Python Flask Jquery AJAX, MySQL</h3>
  
  <form id="signupform" style="padding: 10px;">
   <fieldset>
    <legend>Check username</legend>
    <div>
     <p style="padding-bottom:5px;font-weight:bold;">Username</p>
     <input type="text" class="form-control" name="username" id="username" autocomplete="off"/>
     <div id="msg"></div>
     <h4 id='loading' style="display:none;"><img src="{{ url_for('static', filename='img/loader.gif') }}"/> Loading..</h4>
    </div>
   </fieldset>
  </form>
 </div>
 <script type="text/javascript">
  $(document).ready(function() {
   $("#username").on('input', function(e) {
    $('#msg').hide();
    $('#loading').show();
    if ($('#username').val() == null || $('#username').val() == "") {
     $('#msg').show();
     $("#msg").html("Username is required field.").css("color", "red");
    } else {
     $.ajax({
      type: "POST",
      url: "/user_check",
      data: $('#signupform').serialize(),
      dataType: "html",
      cache: false,
      success: function(msg) {
       $('#msg').show();
       $('#loading').hide();
       $("#msg").html(msg);
      },
      error: function(jqXHR, textStatus, errorThrown) {
       $('#msg').show();
       $('#loading').hide();
       $("#msg").html(textStatus + " " + errorThrown);
      }
     });
    }
   });
  });
 </script>
<style>
body {font-size:16px;}
#msg {font-weight:bold;padding:10px;}
.form-control {
    display: block;
    width:300px;
    height: 25px;
    padding: 6px 12px;
    font-size: 14px;
    line-height: 1.428571429;
    color: #555;
    background-color: #fff;
    background-image: none;
    border: 1px solid #ccc;
    border-radius: 4px;
    -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075);
    box-shadow: inset 0 1px 1px rgba(0,0,0,.075);
    -webkit-transition: border-color ease-in-out .15s,box-shadow ease-in-out .15s;
    transition: border-color ease-in-out .15s,box-shadow ease-in-out .15s;
}
</style> 
</body>
</html>

jQuery AJAX based Registration System using Python Flask MySQL


jQuery AJAX based Registration System using Python Flask MySQL

Database table
CREATE TABLE `user_test_flask` (
  `id` int unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(50) NULL,
  `email` varchar(50) NULL,
  `pwd` varchar(255) NULL,
  `admin` tinyint DEFAULT 0,
  PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
from flask import Flask, render_template, url_for, request, json, jsonify
from flaskext.mysql import MySQL
import pymysql
from werkzeug import generate_password_hash, check_password_hash

app = Flask(__name__)

mysql = MySQL()
 
# MySQL configurations
app.config['MYSQL_DATABASE_USER'] = 'root'
app.config['MYSQL_DATABASE_PASSWORD'] = ''
app.config['MYSQL_DATABASE_DB'] = 'testingdb'
app.config['MYSQL_DATABASE_HOST'] = 'localhost'
mysql.init_app(app)
  
@app.route('/')
def home():
 return render_template('signup_user_flask.html')
 
@app.route('/signup', methods=['POST'])
def signup():
    conn = mysql.connect()
    cursor = conn.cursor(pymysql.cursors.DictCursor)
 
    _json = request.json
    _name = _json['name']
    _email = _json['email']
    _pwd = _json['password']
 
    if _email and _name and _pwd:
 
        cursor.execute('SELECT email FROM user_test_flask WHERE email = %s', (_email))
        user_exist = cursor.fetchone()
  
        if user_exist:
            resp = jsonify({'message' : 'User already registered'})
            resp.status_code = 409
            return resp
        else:
            sql = "INSERT INTO user_test_flask(name, email, pwd) VALUES(%s, %s, %s)"
            data = (_name, _email, generate_password_hash(_pwd),)
            cursor.execute(sql, data)
            conn.commit()
            cursor.close()
            conn.close()
   
            resp = jsonify({'message' : 'User registered successfully'})
            resp.status_code = 201
            return resp
    else:
        resp = jsonify({'message' : 'Bad Request - invalid parameters'})
        resp.status_code = 400
        return resp
  
if __name__ == '__main__':
 app.run(debug=True)
//signup_user_flask.html
<html>
<head>
<title>jQuery AJAX based Registration System using Python Flask MySQL</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script>
$(document).ready(function() {
 $('#signupSubmit').on('click', function(e) {
  e.preventDefault();
  $('#loading').show();
  var name = $('#fullname').val();
  var email = $('#email').val();
  var pwd = $('#password').val();
  var cnfpwd = $('#cnfpassword').val();
  
  var regex = /^([a-zA-Z0-9_.+-])+\@(([a-zA-Z0-9-])+\.)+([a-zA-Z0-9]{2,4})+$/i;
  
  if(email != "" && pwd != "" && cnfpwd != "") {
   if(pwd != cnfpwd) {
    $('#msg').html('<span style="color: red;">Password and confirm password must match</span>');
   } else if(!regex.test(email)) {
    $('#msg').html('<span style="color: red;">Invalid email address</span>');
   } else {
    $.ajax({
     method: "POST",
     url: '/signup',
     contentType: 'application/json;charset=UTF-8',
     data: JSON.stringify({'name': name, 'email': email, 'password': pwd}),
     dataType: "json",
     success: function(data) {
      $('#signupform').hide();
      $('#loading').hide();
      $('#msg').html('<span style="color: green;">You are registered successfully</span>');
     },statusCode: {
      400: function() {
       $('#loading').hide();
       $('#msg').html('<span style="color: red;">Bad request parameters</span>');
      },
      409 : function() {
       $('#loading').hide();
       $('#msg').html('<span style="color: red;">You are already registered user</span>');
      }
     },
     error: function(err) {
      console.log(err);
     }
    });
   }
  } else {
   $('#loading').hide();
   $('#msg').html('<span style="color: red;">All fields are required</span>');
  }
 });
});
</script>
</head>
<body>
<h1 align="center">jQuery AJAX based Registration System using Python Flask MySQL</h1>
<div class="reg-box" style="width: 500px; margin: auto;">
  <h4 id='loading' style="display:none;"><img src="{{ url_for('static', filename='img/loader.gif') }}"/> Loading..</h4>
  <div style="clear: both;"></div>
  <div id="msg"></div>
  <div id="signupform" style="width: 500px; margin: auto;">
   <h2>Sign Up</h2>
   <dl>
    <p>
     <input id="fullname" class="form-control" value="" type="text" placeholder="Full Name" required>
    </p>
    <p>
     <input id="email" class="form-control" value="" type="text" placeholder="Email" autocomplete="off" required>
    </p>
    <p>
     <input id="password" class="form-control" value="" type="password" placeholder="Password" autocomplete="off" required>
    </p>
    <p>
     <input id="cnfpassword" class="form-control" value="" type="password" placeholder="Confirm Password" autocomplete="off" required>
    </p>
   <p>
    <input type="button" id="signupSubmit" class="btn-info" value="Submit">
   </p>
   </dl>
   
  </div>
 </div>
<style>
body { font-size:16px;}
.reg-box {
    background: none repeat scroll 0 0 #EEEEEE;
    border: 1px solid #CCCCCC;
    border-radius: 12px 12px 12px 12px;
    margin-top: 20px;
    padding: 10px;
}
.form-control {
    display: block;
    width: 100%;
    height: 34px;
    padding: 6px 12px;
    font-size: 14px;
    line-height: 1.428571429;
    color: #555;
    background-color: #fff;
    background-image: none;
    border: 1px solid #ccc;
    border-radius: 4px;
    -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075);
    box-shadow: inset 0 1px 1px rgba(0,0,0,.075);
    -webkit-transition: border-color ease-in-out .15s,box-shadow ease-in-out .15s;
    transition: border-color ease-in-out .15s,box-shadow ease-in-out .15s;
}
.btn-info {
    color: #fff;    width: 100%;text-align: center;vertical-align: middle;
    background-color: #5bc0de;    border: 1px solid transparent;
    border-color: #46b8da;padding: 6px 12px;font-size: 14px;border-radius: 4px;
}
</style>
</body>
</html>

Tuesday, February 18, 2020

Python Flask jQuery Ajax POST and insert data to Mysql


Python Flask jQuery Ajax POST and insert data to Mysql

 
#app.py
from flask import Flask, render_template, url_for, request, json, jsonify
from flaskext.mysql import MySQL
import pymysql

app = Flask(__name__)
 
mysql = MySQL()
 
# MySQL configurations
app.config['MYSQL_DATABASE_USER'] = 'root'
app.config['MYSQL_DATABASE_PASSWORD'] = ''
app.config['MYSQL_DATABASE_DB'] = 'testingdb'
app.config['MYSQL_DATABASE_HOST'] = 'localhost'
mysql.init_app(app)

@app.route("/")
def hello():
    return "Welcome to Python Flask!"

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

@app.route('/process', methods=['POST'])
def process():
	# connect
    conn = mysql.connect()
    cursor = conn.cursor(pymysql.cursors.DictCursor)
    msg = ''
    username = request.form['username']
    password = request.form['password']
    name = request.form['name']
    email = request.form['email']

    if name and email and username and password:
        cursor.execute('INSERT INTO accounts VALUES (NULL, %s, %s, %s, %s)', (name, username, password, email)) 
        conn.commit()
        msg = 'You have successfully registered!'
        return jsonify({'name' : msg})

    return jsonify({'error' : 'Missing data!'})
	
if __name__ == '__main__':
	app.run(debug=True)
//signUp.html

 <html lang="en">
 <head>
     <meta charset="utf-8">
     <meta http-equiv="X-UA-Compatible" content="IE=edge">
     <meta name="viewport" content="width=device-width, initial-scale=1">
     <title>Python Flask jQuery Ajax POST and insert data to Mysql </title>
	 <link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
	<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js"></script>
	<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script>
$(document).ready(function() {
	$('form').on('submit', function(event) {
		$('#loading').show();
		$.ajax({
			data : {
				name : $('#fullname').val(),
				username : $('#username').val(),
				password : $('#password').val(),
				email : $('#txtmail').val()
			},
			type : 'POST',
			url : '/process'
		})
		.done(function(data) {
			if (data.error) {
				$('#errorAlert').text(data.error).show();
				$('#successAlert').hide();
				$('#loading').hide();
			}
			else {
				$('#successAlert').text(data.name).show();
				$('#errorAlert').hide();
				$('#loading').hide();
			}

		});
		event.preventDefault();
	});
});
</script>
</head>
 <body>
      <div class="container">
		<p><h1>Python Flask jQuery Ajax POST and insert data to Mysql</h1></p>
		<div class="col-md-4 col-md-offset-4" id="login">
			<section id="inner-wrapper" class="login">
							<article>
								<form class="form-signin">
								<h2 class="form-signin-heading">Please Sign Up </h2>
									<div class="form-group">
										<div class="input-group">
											<span class="input-group-addon"><i class="fa fa-user"> </i></span>
											<input type="text" class="form-control" name="fullname" id="fullname" placeholder="Your Name" required autofocus>
										</div>
									</div>
									<div class="form-group">
										<div class="input-group">
											<span class="input-group-addon"><i class="fa fa-user"> </i></span>
											<input type="text" class="form-control" name="username" id="username" placeholder="Your Username" required>
										</div>
									</div>
									<div class="form-group">
										<div class="input-group">
											<span class="input-group-addon"><i class="fa fa-envelope"> </i></span>
											<input type="email" class="form-control" name="txtmail" id="txtmail" placeholder="Email Address" required>
										</div>
									</div>
									<div class="form-group">
										<div class="input-group">
											<span class="input-group-addon"><i class="fa fa-key"> </i></span>
											<input type="password" class="form-control" name="password" id="password" class="form-control" placeholder="Password" required>
										</div>
									</div>
									  <button type="submit" class="btn btn-success btn-block">Register</button>
								</form>
								<br/>
				<div id="successAlert" class="alert alert-success" role="alert" style="display:none;"></div>
				<div id="errorAlert" class="alert alert-danger" role="alert" style="display:none;"></div>
				<h4 id='loading' style="display:none;"><img src="{{ url_for('static', filename='img/loader.gif') }}"/> Loading..</h4>
				
				
							</article>
			</section>			
		</div>				
</div>		
<style>
body {
    background:#333;
}
h1 {color:#fff;}
#login {
	-webkit-perspective: 1000px;
	-moz-perspective: 1000px;
	perspective: 1000px;
	margin-top:50px;
	margin-left:30%;
}
.login {
	font-family: 'Josefin Sans', sans-serif;
	-webkit-transition: .3s;
	-moz-transition: .3s;
	transition: .3s;
	-webkit-transform: rotateY(40deg);
	-moz-transform: rotateY(40deg);
	transform: rotateY(40deg);
}
.login:hover {
	-webkit-transform: rotate(0);
	-moz-transform: rotate(0);
	transform: rotate(0);
}
.login .form-group {
	margin-bottom:17px;
}
.login .form-control,
.login .btn {
	border-radius:0;
}
.login .btn {
	text-transform:uppercase;
	letter-spacing:3px;
}
.input-group-addon {
	border-radius:0;
	color:#fff;
	background:#f3aa0c;
	border:#f3aa0c;
}
.forgot {
	font-size:16px;
}
.forgot a {
	color:#333;
}
.forgot a:hover {
	color:#5cb85c;
}

#inner-wrapper, #contact-us .contact-form, #contact-us .our-address {
    color: #1d1d1d;
    font-size: 19px;
    line-height: 1.7em;
    font-weight: 300;
    padding: 50px;
    background: #fff;
    box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12);
    margin-bottom: 100px;
}
.input-group-addon {
    border-radius: 0;
        border-top-right-radius: 0px;
        border-bottom-right-radius: 0px;
    color: #fff;
    background: #f3aa0c;
    border: #f3aa0c;
        border-right-color: rgb(243, 170, 12);
        border-right-style: none;
        border-right-width: medium;
}
</style>				
 </body>
 </html>
 

How To Handle 404 Error In Python Flask


How To Handle 404 Error In Python Flask

from flask import Flask, render_template
#from flask import jsonify

app = Flask(__name__)

@app.route("/")
def hello():
    return "Welcome to Python Flask."

@app.errorhandler(404) 
def invalid_route(e): 
    #return "Invalid route."
 #return jsonify({'errorCode' : 404, 'message' : 'Route not found'})
 return render_template('404.html')
 
if __name__ == '__main__':
    app.run(debug=True)
//404.html
<!DOCTYPE html>
<html>
<head>
 <title>404</title>
</head>
<body>
<p><h1>404 Page not found</h1></p>
</body>
</html>

Login Register Sytem with Python Flask and Mysql


Login Register Sytem with Python Flask and Mysql

A complete login and registration system with Python Flask and MySQL

Table account

CREATE TABLE `accounts` (
  `id` int(11) NOT NULL,
  `fullname` varchar(200) NOT NULL,
  `username` varchar(50) NOT NULL,
  `password` varchar(255) NOT NULL,
  `email` varchar(100) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
#app.py
from flask import Flask, request, session, redirect, url_for, render_template
from flaskext.mysql import MySQL
import pymysql 
import re 

app = Flask(__name__)

# Change this to your secret key (can be anything, it's for extra protection)
app.secret_key = 'cairocoders-ednalan'

mysql = MySQL()
  
# MySQL configurations
app.config['MYSQL_DATABASE_USER'] = 'root'
app.config['MYSQL_DATABASE_PASSWORD'] = ''
app.config['MYSQL_DATABASE_DB'] = 'testingdb'
app.config['MYSQL_DATABASE_HOST'] = 'localhost'
mysql.init_app(app)

# http://localhost:5000/pythonlogin/ - this will be the login page
@app.route('/pythonlogin/', methods=['GET', 'POST'])
def login():
 # connect
    conn = mysql.connect()
    cursor = conn.cursor(pymysql.cursors.DictCursor)
 
    # Output message if something goes wrong...
    msg = ''
    # Check if "username" and "password" POST requests exist (user submitted form)
    if request.method == 'POST' and 'username' in request.form and 'password' in request.form:
        # Create variables for easy access
        username = request.form['username']
        password = request.form['password']
        # Check if account exists using MySQL
        cursor.execute('SELECT * FROM accounts WHERE username = %s AND password = %s', (username, password))
        # Fetch one record and return result
        account = cursor.fetchone()
  
    # If account exists in accounts table in out database
        if account:
            # Create session data, we can access this data in other routes
            session['loggedin'] = True
            session['id'] = account['id']
            session['username'] = account['username']
            # Redirect to home page
            #return 'Logged in successfully!'
            return redirect(url_for('home'))
        else:
            # Account doesnt exist or username/password incorrect
            msg = 'Incorrect username/password!'
   
    return render_template('index.html', msg=msg)

# http://localhost:5000/register - this will be the registration page
@app.route('/register', methods=['GET', 'POST'])
def register():
 # connect
    conn = mysql.connect()
    cursor = conn.cursor(pymysql.cursors.DictCursor)
 
    # Output message if something goes wrong...
    msg = ''
    # Check if "username", "password" and "email" POST requests exist (user submitted form)
    if request.method == 'POST' and 'username' in request.form and 'password' in request.form and 'email' in request.form:
        # Create variables for easy access
        fullname = request.form['fullname']
        username = request.form['username']
        password = request.form['password']
        email = request.form['email']
  
  #Check if account exists using MySQL
        cursor.execute('SELECT * FROM accounts WHERE username = %s', (username))
        account = cursor.fetchone()
        # If account exists show error and validation checks
        if account:
            msg = 'Account already exists!'
        elif not re.match(r'[^@]+@[^@]+\.[^@]+', email):
            msg = 'Invalid email address!'
        elif not re.match(r'[A-Za-z0-9]+', username):
            msg = 'Username must contain only characters and numbers!'
        elif not username or not password or not email:
            msg = 'Please fill out the form!'
        else:
            # Account doesnt exists and the form data is valid, now insert new account into accounts table
            cursor.execute('INSERT INTO accounts VALUES (NULL, %s, %s, %s, %s)', (fullname, username, password, email)) 
            conn.commit()
  
            msg = 'You have successfully registered!'
    elif request.method == 'POST':
        # Form is empty... (no POST data)
        msg = 'Please fill out the form!'
    # Show registration form with message (if any)
    return render_template('register.html', msg=msg)
 
# http://localhost:5000/home - this will be the home page, only accessible for loggedin users
@app.route('/')
def home():
    # Check if user is loggedin
    if 'loggedin' in session:
  
        # User is loggedin show them the home page
        return render_template('home.html', username=session['username'])
    # User is not loggedin redirect to login page
    return redirect(url_for('login'))
 
# http://localhost:5000/logout - this will be the logout page
@app.route('/logout')
def logout():
    # Remove session data, this will log the user out
   session.pop('loggedin', None)
   session.pop('id', None)
   session.pop('username', None)
   # Redirect to login page
   return redirect(url_for('login'))

# http://localhost:5000/profile - this will be the profile page, only accessible for loggedin users
@app.route('/profile')
def profile(): 
 # Check if account exists using MySQL
    conn = mysql.connect()
    cursor = conn.cursor(pymysql.cursors.DictCursor)
 
    # Check if user is loggedin
    if 'loggedin' in session:
        # We need all the account info for the user so we can display it on the profile page
        cursor.execute('SELECT * FROM accounts WHERE id = %s', [session['id']])
        account = cursor.fetchone()
        # Show the profile page with account info
        return render_template('profile.html', account=account)
    # User is not loggedin redirect to login page
    return redirect(url_for('login'))
 
 
 
if __name__ == '__main__':
    app.run(debug=True)
//index.html
<!DOCTYPE html>
<html>
 <head>
  <meta charset="utf-8">
  <title>Login</title>
  <link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.1/css/all.css">
 <link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
 <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js"></script>
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
 </head>
 <body style="background-color:#ccc;">
  <div class="login-box" >
  <div class="login-header">Login</div>
  <div class="login-body">
   <p>Please enter your username and password</p>
   <form class="form-group" action="{{ url_for('login') }}" method="post">
    <label>Username</label>
    <input type="text" class="form-control" name="username" placeholder="Username" id="username" required>
    <label>Password</label>
    <input type="password" class="form-control" name="password" placeholder="Password" id="password" required>
    <input type="checkbox" value="checked"><b>Remember</b>
    <input type="submit" value="Login" class="form-control btn btn-success " name="">
   </form>
   <div id="msg">{{ msg }}</div>
   <p>No account <a href="{{ url_for('register') }}">Register</a></p>
  </div>
 </div>
 </body>
</html>
//home.html
{% extends 'layout.html' %}

{% block title %}Home{% endblock %}

{% block content %}
<h1 class="h2">Dashboard</h1>
<p>Welcome back, {{ username }}!</p>
{% endblock %}
//layout.html
<!DOCTYPE html>
<html>
 <head>
  <meta charset="utf-8">
  <title>{% block title %}{% endblock %}</title>
  <link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.1/css/all.css">
 <link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
 <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js"></script>
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
 </head>
 <body class="loggedin">
 <nav class="site-header sticky-top py-1">
      <div class="container d-flex flex-column flex-md-row justify-content-between">
        <a class="py-2" href="#">
          <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="d-block mx-auto"><circle cx="12" cy="12" r="10"></circle><line x1="14.31" y1="8" x2="20.05" y2="17.94"></line><line x1="9.69" y1="8" x2="21.17" y2="8"></line><line x1="7.38" y1="12" x2="13.12" y2="2.06"></line><line x1="9.69" y1="16" x2="3.95" y2="6.06"></line><line x1="14.31" y1="16" x2="2.83" y2="16"></line><line x1="16.62" y1="12" x2="10.88" y2="21.94"></line></svg>
        </a>
  <a class="py-2 d-none d-md-inline-block" href="{{ url_for('home') }}"><i class="fas fa-home"></i> Home</a>
  <a class="py-2 d-none d-md-inline-block" href="{{ url_for('profile') }}"><i class="fas fa-user-circle"></i> Profile</a>
  <a class="py-2 d-none d-md-inline-block" href="{{ url_for('logout') }}"><i class="fas fa-sign-out-alt"></i> Logout</a>
   </div>
    </nav>
 
 <div class="container-fluid">
      <div class="row">
        <nav class="col-md-2 d-none d-md-block bg-light sidebar">
          <div class="sidebar-sticky">
            <ul class="nav flex-column">
              <li class="nav-item">
                <a class="nav-link active" href="#">
                  <i class="fas fa-home"></i>
                  Dashboard <span class="sr-only">(current)</span>
                </a>
              </li>
              <li class="nav-item">
                <a class="nav-link" href="#">
                  <i class="fas fa-shopping-cart"></i>
                  Orders
                </a>
              </li>
              <li class="nav-item">
                <a class="nav-link" href="#">
    <i class="fas fa-shopping-cart"></i>
                  Products
                </a>
              </li>
              <li class="nav-item">
                <a class="nav-link" href="#">
                  <i class="fas fa-users"></i>
                  Customers
                </a>
              </li>
              <li class="nav-item">
                <a class="nav-link" href="#">
                  <i class="fas fa-download"></i>
                  Reports
                </a>
              </li>
            </ul>
   </div>
        </nav>

        <main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4">
          <div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pb-2 mb-3 border-bottom">
            <div class="col-12">
   {% block content %}{% endblock %}
   </div>
          </div>
   </main>
   
      </div>
    </div>
 
 </body>
</html>
//profile.html
{% extends 'layout.html' %}

{% block title %}Profile{% endblock %}

{% block content %}
<h1>Profile Page</h1>
<div>
    <p>Your account details are below:</p>
    <table>
        <tr>
            <td>Name:</td>
            <td>{{ account['fullname'] }}</td>
        </tr>
  <tr>
            <td>Username:</td>
            <td>{{ account['username'] }}</td>
        </tr>
        <tr>
            <td>Password:</td>
            <td>{{ account['password'] }}</td>
        </tr>
        <tr>
            <td>Email:</td>
            <td>{{ account['email'] }}</td>
        </tr>
    </table>
</div>
{% endblock %}
//register.html
<!DOCTYPE html>
<html>
 <head>
  <meta charset="utf-8">
  <title>Register</title>
  <link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
  <link rel="stylesheet" href="../static/css/style.css">
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.1/css/all.css">
  <!-- Google Fonts -->
  <link href='https://fonts.googleapis.com/css?family=Passion+One' rel='stylesheet' type='text/css'>
  <link href='https://fonts.googleapis.com/css?family=Oxygen' rel='stylesheet' type='text/css'>
  <link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
 </head>
 <body style="background-color:#ccc;">
 <div class="container">
   <div class="row main">
    <div class="main-login main-center">
    <h5>Register New user or login existing account</h5>
     <form action="{{ url_for('register') }}" method="post" autocomplete="off"> 
      <div class="form-group">
       <label for="name" class="cols-sm-2 control-label">Your Name</label>
       <div class="cols-sm-10">
        <div class="input-group">
         <span class="input-group-addon"><i class="fa fa-user fa" aria-hidden="true"></i></span>
         <input type="text" class="form-control" name="fullname" id="fullname"  placeholder="Enter your Name"/>
        </div>
       </div>
      </div>
      <div class="form-group">
       <label for="email" class="cols-sm-2 control-label">Your Email</label>
       <div class="cols-sm-10">
        <div class="input-group">
         <span class="input-group-addon"><i class="fa fa-envelope fa" aria-hidden="true"></i></span>
         <input type="text" class="form-control" name="email" id="email"  placeholder="Enter your Email"/>
        </div>
       </div>
      </div>

      <div class="form-group">
       <label for="username" class="cols-sm-2 control-label">Username</label>
       <div class="cols-sm-10">
        <div class="input-group">
         <span class="input-group-addon"><i class="fa fa-users fa" aria-hidden="true"></i></span>
         <input type="text" class="form-control" name="username" id="username" placeholder="Enter your Username" required>
        </div>
       </div>
      </div>

      <div class="form-group">
       <label for="password" class="cols-sm-2 control-label">Password</label>
       <div class="cols-sm-10">
        <div class="input-group">
         <span class="input-group-addon"><i class="fa fa-lock fa-lg" aria-hidden="true"></i></span>
         <input type="password" class="form-control" name="password" placeholder="Password" id="password" required  placeholder="Enter your Password"/>
        </div>
       </div>
      </div>

      <div class="form-group ">
       <div id="msg">{{ msg }}</div>
       <input type="submit" value="Register" class="form-control btn btn-primary " name="">
       <p style="padding:5px;">
       <a href="{{ url_for('login') }}" class="btn btn-dark ">Login</a></p>
      
      </div>
      
     </form>
    </div>
   </div>
  </div>
 <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js"></script>
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>  
 </body>
</html>
//style.css
body {
   background-color: #435165;
   margin: 0;
}

.login-box
  {
   height: 50%;
   width: 30%;
   border: 1px solid grey;
   margin-left: 35%;
   margin-top: 10%;
   position: relative;
        box-shadow: 21px 12px 24px 10px rgba(0, 0, 0, .5);
        background: #dadada;
  }
  .login-header
  {
   text-align: center;
   font-family: "vardhana",cursive;
   font-size: 35px;
   background: linear-gradient(to bottom, #00bfff 0%, #0000ff 100%);
   color:#fff;
   position: relative;
        box-shadow: 1px 3px 14px  rgba(0, 0, 0, .5);
  }
  .login-body
  {
   padding: 20px;
   line-height: 2;
  }
.msg {
 color: #721c24;
    background-color: #f8d7da;
    border-color: #f5c6cb;
 padding: .75rem 1.25rem;
    margin-bottom: 1rem;
    border: 1px solid transparent;
    border-radius: .25rem;
}  
.main{
  margin-top:50px;
}

h1.title { 
 font-size: 50px;
 font-family: 'Passion One', cursive; 
 font-weight: 400; 
}

hr{
 width: 10%;
 color: #fff;
}

.form-group{
 margin-bottom: 15px;
}

label{
 margin-bottom: 15px;
}

input,
input::-webkit-input-placeholder {
    font-size: 11px;
    padding-top: 3px;
}

.main-login{
  background-color: #fff;
    /* shadows and rounded borders */
    -moz-border-radius: 2px;
    -webkit-border-radius: 2px;
    border-radius: 2px;
    -moz-box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3);
    -webkit-box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3);
    box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3);

}
.form-control {
    height: auto!important;
padding: 8px 12px !important;
}
.input-group {
    -webkit-box-shadow: 0px 2px 5px 0px rgba(0,0,0,0.21)!important;
    -moz-box-shadow: 0px 2px 5px 0px rgba(0,0,0,0.21)!important;
    box-shadow: 0px 2px 5px 0px rgba(0,0,0,0.21)!important;
}
.main-center{
  margin-top: 30px;
  margin: 0 auto;
  max-width: 400px;
    padding: 10px 40px;
 background:#009edf;
     color: #FFF;
    text-shadow: none;
 -webkit-box-shadow: 0px 3px 5px 0px rgba(0,0,0,0.31);
-moz-box-shadow: 0px 3px 5px 0px rgba(0,0,0,0.31);
box-shadow: 0px 3px 5px 0px rgba(0,0,0,0.31);

}
span.input-group-addon i {
    color: #fff;
    font-size: 17px;padding:10px;
}

.login-button{
 margin-top: 5px;
}

.login-register{
 font-size: 11px;
 text-align: center;
}

.site-header {
    background-color: rgba(0, 0, 0, .85);
    -webkit-backdrop-filter: saturate(180%) blur(20px);
    backdrop-filter: saturate(180%) blur(20px);
}
.site-header a { 
 color:#fff;
}

Related Post