Saturday, 14 September 2019

Create a Web App Using Python Flask Framework With Postgresql As Database

How To Create a Flask Web Application With Postgresql

### Prerequisites

  • Ubuntu 18.04
  • Python3
  • pip3

### Steps

  • Install Postgresql & Create database user and the database
  • Create Python virtual environment
  • Install Flask and other required modules
  • Create codebase
  • Run database migration
  • Run the Flask application

### Install Postgresql & Create Database

  • Run following command in terminal to install postgresql
    sudo apt-get install postgresql postgresql-contrib
  • To verify installation, run the command:
    sudo -u postgres psql -c "SELECT version();"
  • Create User and DB
    sudo su - postgres -c "createuser devopsuser"
    sudo su - postgres -c "createdb devopsdb"
  • Grant privileges
    sudo -u postgres psql
    grant all privileges on database devopsdb to devopsuser;
    alter user devopsuser with password 'devops';
    run following to exit from psql
    \q
  • Enable remote access to postgresql, edit
    sudo vi /etc/postgresql/10/main/postgresql.conf
    Change the line "listen_addresses = 'localhost'" to "listen_addresses = '*'"
    Save and exit the file
    Restart postgresql
    sudo /etc/init.d/postgresql restart

### Create python virtual environment

  • Create a directory "python-flask-pg"
  • cd python-flask-pg
  • pip3 install virtualenv
  • cd python-flask-pg
  • virtualenv env
  • Activate virtualenv with command and keep it activated for rest of the work.
  • source env/bin/activate

### Install Flask and other required modules

  • Create a file requirement.txt and put following dependencies in it. Make sure the virtual env is activated.
    Flask
    flask_sqlalchemy
    flask_script
    flask_migrate
    psycopg2-binary
  • Install above dependencies using following command
    pip3 install -r requirement.txt

### Create .env with the following code

Run the following command to make these variable available to the current shell:
source .env

export APP_SETTINGS="config.DevelopmentConfig"
export DATABASE_URL="postgresql://devopsuser:devops@localhost/devopsdb"

### Create app.py with the following code

from flask import Flask, request, jsonify, render_template
from flask_sqlalchemy import SQLAlchemy
import os

app = Flask(__name__)

app.config.from_object(os.environ['APP_SETTINGS'])
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

db = SQLAlchemy(app)

from models import Employee

@app.route("/")
def hello():
    return "Hello DevOps!"

@app.route("/name/<name>")
def get_employee_name(name):
    return "name : {}".format(name)

@app.route("/details")
def get_employee_details():
    age=request.args.get('age')
    address=request.args.get('address')
    return "Age : {}, Address: {}".format(age,address)

@app.route("/add")
def add_employee():
    name=request.args.get('name')
    age=request.args.get('age')
    address=request.args.get('address')
    try:
        employee=Employee(
            name=name,
            age=age,
            address=address
        )
        db.session.add(employee)
        db.session.commit()
        return "Employee added. employee id={}".format(employee.id)
    except Exception as e:
     return(str(e))

@app.route("/add/form",methods=['GET', 'POST'])
def add_employee_form():
    if request.method == 'POST':
        name=request.form.get('name')
        age=request.form.get('age')
        address=request.form.get('address')
        try:
            employee=Employee(
                name=name,
                age=age,
                address=address
            )
            db.session.add(employee)
            db.session.commit()
            return "Employee added. employee id={}".format(employee.id)
        except Exception as e:
            return(str(e))
    return render_template("getdata.html")

@app.route("/getall")
def get_all():
    try:
        employees=Employee.query.all()
        return  jsonify([e.serialize() for e in employees])
    except Exception as e:
     return(str(e))

@app.route("/get/<id_>")
def get_by_id(id_):
    try:
        employee=Employee.query.filter_by(id=id_).first()
        return jsonify(book.serialize())
    except Exception as e:
     return(str(e))

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

### Create config.py with the following code

import os
basedir = os.path.abspath(os.path.dirname(__file__))

class Config(object):
    DEBUG = False
    TESTING = False
    CSRF_ENABLED = True
    SECRET_KEY = 'this-really-needs-to-be-changed'
    SQLALCHEMY_DATABASE_URI = os.environ['DATABASE_URL']


class ProductionConfig(Config):
    DEBUG = False


class StagingConfig(Config):
    DEVELOPMENT = True
    DEBUG = True


class DevelopmentConfig(Config):
    DEVELOPMENT = True
    DEBUG = True


class TestingConfig(Config):
    TESTING = True

### Create models.py with the following code

from flask_sqlalchemy import SQLAlchemy 
from app import db                                         


class Employee(db.Model):
    __tablename__ = 'employee'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String())
    age = db.Column(db.String())
    address = db.Column(db.String())

    def __init__(self, name, age, address):
        self.name = name
        self.age = age
        self.address = address

    def __repr__(self):
        return '<id {}>'.format(self.id)
    
    def serialize(self):
        return {
            'id': self.id, 
            'name': self.name,
            'age': self.age,
            'address':self.address
        }

### Create manage.py with the following code

from flask_script import Manager
from flask_migrate import Migrate, MigrateCommand

from app import app, db

migrate = Migrate(app, db)
manager = Manager(app)

manager.add_command('db', MigrateCommand)


if __name__ == '__main__':
    manager.run()

### Create getdata.html inside templates directory with the following code

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO"
        crossorigin="anonymous">
</head>

<body>
    <div class="container">

        <div class="container">
            <br>
            <br>

            <div class="row align-items-center justify-content-center">
                <h1>Add an employee</h1>
            </div>
            <br>

            <form method="POST">

                <label for="name">Employee Name</label>
                <div class="form-row">
                    <input class="form-control" type="text" placeholder="Name of Employee" id="name" name="name">
                </div>
                <br>
                <div class="form-row">
                    <label for="author">Age</label>
                    <input class="form-control" type="text" placeholder="Employee Age" id="age" name="age">
                </div>
                <br>
                <div class="form-row ">
                    <label for="published">Address</label>
                    <input class="form-control " type="text" placeholder="Address" id="address" name="address">
                </div>

                <br>
                <button type="submit " class="btn btn-primary " style="float:right ">Save</button>
            
            </form>
            <br><br>
        </div>
    </div>

    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js " integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo "
        crossorigin="anonymous "></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js " integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49 "
        crossorigin="anonymous "></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js " integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy "
        crossorigin="anonymous "></script>
</body>

</html>

### Database Migration

  • flask_sqlalchemy is needed for database migrations which we have already installed above with requirements.txt or you can install it with below command as well
    pip3 install flask_sqlchemy
  • python3 manage.py db init
  • python3 manage.py db migrate
  • python3 manage.py db upgrade
  • Above commands will create the schema in database

### Running the App

  • Run the following command from the root of project directory
  • python3 manage.py runserver 
  • Now Open the browser and hit the url - localhost:5000
  • Access http://localhost:5000/add/form in browser to see the form to save data
  • Access http://localhost:5000/getall to see all the data


    1 comments:

    1. Yes, indeed. There is no reason to doubt the validity of this view. Many technologies have already applied this idea at least once. So, for the next promotional event if the company is looking for smart but impressive gifts, then promtional pen
      can be a reliable proposal. This is also economical, the most important part of your budget will be saved.

      ReplyDelete

     

    Copyright @ 2013 Appychip.

    Designed by Appychip & YouTube Channel