Overview

Skill Level: Intermediate

"broad" intermediate

This recipe illustrates extending a Python app so that it functions as a native Flask web app and supports a backend NoSQL database.
Other topics by the author in the "Automation Series" can be found at: https://developer.ibm.com/recipes/author/patemic/

Ingredients

  1. Linux
  2. Python
  3. Flask
  4. MongoDB
  5. pinch of Angularjs

Step-by-step

  1. Set Up Python Imports

    import os  needed for some file management

    import sys  necessary for this application, if services such as stdin, stdout needed to operate

    from flask import Flask, render_template necessary for relating Python code to url references

    from flask_bower import Bower  Bower is a package CSS/js management utility. Import YOUR pkg mgt utility

    from flask import request HTTP requests sent from Python

    import json   Python can parse JSON dict into Python lists

    from flask import jsonify Python can parse lists into json format

    from pymongo import MongoClient, DESCENDING necessary for doc mongo insertion

    from sys import stdout may be necessary if Python uses STDOUT as part of I/O method

    from sys import stdin may be necessary if Python uses STDIN as part of I/O method

    from time import sleep  used as variable rest between I/O inmstances

     

  2. Set Up MongoDB Client

    Decision point: 

    • will Mongo be running on local Python/Flask web app server ?
    • will Mongo be running in a remote server/container, possibly in a K8s POD?

     

    Local server setup and use:

    client = MongoClient() 

     

    Mongo is remote from local server:

    client = MongoClient(“mongodb://<hostname>:27017”)  remote host, using native Mongo port

    client = MongoClient(“mongodb://localhost:27017”) example of remote host in same K8s POD, using native Mongo port

     

    db = client.portalDB    —finally, set up DB the mongo db 

  3. Set Up Flask to Present Python app as Native Web App

    app = Flask(__name__)  sets up object of Flask class assigned to variable “app”.  Necessary when app is a single module

    @app.route(“/”)  Python decorator for function main. This is Flask at work

    def main():

        return render_template(‘myview.html’)  now make the view available at Flask port 5000 . This  module launches View service at the Flask port. Bear in mind, this Flask/Python app will likely be reverse proxied by a web front end (Apache) in production. More on this in the next recipes in “the Automation Series”

     

    Rather than have a static Web Page, The Python app wil llikely be re-accessed by js contained in the very HTML/js that the Python app served to the client browser.  Python Decorators like the following (Flask urls or Flask “routes”) are used to allow the js to cause function code execution in the Python app:

    @app.route(“/mycode”,methods=[‘POST’]) 

    def mycode():

    |

    |

    (code in this function is bound to the route “/my_code”)

    |

    |

    —For this module to execute properly, it must be loaded interactively and be the single (main) module. If, so, then execute it

    if __name__ == “__main__”:   
        app.run()

     

  4. Accessing MongoDB Backend

     

    Insert a document record into the DB collection.  This could be the code within the function previosuly referenced in the Flask route “/mycode”

    @app.route(“/mycode”,methods=[‘POST’])
    def my_code():
        try:
            json_data = request.json[‘info’]        ident1 = json_data[‘name’]        ident2 = json_data[‘loc1’]        ident3 = json_data[‘loc2’]        db.collection1.insert_one({
                ‘name’:ident1,’address1’:ident2,’address2’:ident3})

     The db was altready identified.  The collection is identified here as “collection1”.   Insert one document (record) of information

     

  5. The circle of (code) Life

    Thus far, we have:

    • a fragment Python/Flask app now operating as a native web app,
    • which served the index page “myview.html”
    • we have function(s) in the app, inside Flask url(s) that in this case include executing MongoDB document insertion

    But, how did we get to the Flask url “/my_code”? 

    As mentioned, the Flask/Python app likely doesn’t serve a static web page.  Web page dynamics are likely made possible by Angularjs directives in the web page, that in turn reference the Flask/Python URL, in an Angularjs method as follows:

     

    Reference from the web index page. define the controller that owns the scope containing the data

    <body>
        <div ng-app=”myApp” ng-controller=”HomeCtrl”>

    |

    | Now in the HTML, use an Angularjs directive (thisDirective) to invoke a method in the controller, because a button is pressed

      <button class=”w3-btn w3-large w3-blue” ng-click=”thisDirective()”>button_label </button>

    |

    Now inside the Angularjs controller script:

    angular.module(‘myApp’, []);
        .controller(‘HomeCtrl’, function ($scope, $http) { 

    |

    | scope initial/default definitions here

    |

    | Angularjs directive in HTML points to this method

    $scope.thisDirective = function () {

                $scope.info.name = $scope.employeename

                $scope.info.loc1 = $scope.address1

                $scope.info.loc2 = $scope.address2

                $http({

                    method: ‘POST’,

                    url: ‘http://FlaskPythonHostName:AppPort/mycode’,  –—Now point back to the route mycode in the Python app

                    data: {

                        info: $scope.info

                    }

    The relationshio between HTML angularjs directive, scope, DOM and Controller wil lbe covered in more detail in subsequent recipes in “the Automation Series”.              

     

    So:this closes the circle as follows:

    • Flask/Python app served the index page
    • The index page loaded the js and the Angularjs file
    • The index page referenced an Angularjs directive “thisDirective” in controller “HomeCtrl”
    • Angularjs controller method called the url http://FlaskPythonHostName:appport/mycode (“mycode” url in the Flask/Python page)
    • Flask/Python function executes a document insertion into the MongoDB backend

    Whereas Angularjs was out of scope for the Recipe, this section illustrated the Angularjs data binding between the HTML and the Flask/Python app.  

Join The Discussion