Building a business intelligence dashboard in Flask

In this recipe, we are going to build on the previous two recipes and build a business intelligence dashboard using Flask.

How to do it…

  1. First, create a new directory for your application. For this recipe, I am going to name the directory pbic-dashboard.
  2. Next, open a terminal session and change into the directory you just created.
  3. After that, create a folder named templates.
  4. Next, create a folder named charts.
  5. Run the previous recipe to create all your charts.
  6. Next, in the root directory of your application, create an empty dashboard.py file.
  7. Now, change into the templates folder, and create a file named dashboard.html.

    You should have a directory structure that looks like the one shown in the following screenshot:

    How to do it…
  8. Next, open dashboard.py, and add the following code:
    from flask import Flask, send_from_directory, render_template
    
    UPLOAD_FOLDER = '/Users/robertdempsey/Dropbox/Private/Python Business Intelligence Cookbook/Drafts/Chapter 5/ch5_code/pbic-dashboard/charts'
    BASE_URL = 'http://127.0.0.1:5000/charts/'
    
    app = Flask(__name__)
    app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
    
    @app.route('/')
    def uploaded_file():
        # list the charts to show
        wcd = BASE_URL + 'weather-conditions-distribution.png'
        lcb = BASE_URL + 'light-conditions-boxplot.png'
        lcbwcb = BASE_URL + 'lc-by-wc-boxplot.png'
        cca = BASE_URL + 'casualty-count-all.png'
        cc2 = BASE_URL + 'casualty-count-2000.png'
        cc1980 = BASE_URL + 'casualty-count-1980s.png'
    
        return render_template('dashboard.html',
                               wcd=wcd,
                               lcb=lcb,
                               lcbwcb=lcbwcb,
                               cca=cca,
                               cc2=cc2,
                               cc1980=cc1980)
    
    
    @app.route('/charts/<filename>')
    def send_file(filename):
        return send_from_directory(UPLOAD_FOLDER, filename)
    
    if __name__ == "__main__":
        app.debug = True
        app.run()
  9. Lastly, open the index.html file in the templates folder and add this code:
    <html>
      <head>
        <title>Dashboard</title>
      </head>
      <body>
        <h1>Data Dashboard</h1>
        <table>
            <tr>
                <td colspan="2"><h2>Distributions</h2></td>
            </tr>
            <tr>
                <td>
                    <img src="{{ wcd }}" />
                </td>
                <td>
                    <img src="{{ lcb }}" />
                </td>
            </tr>
            <tr>
                <td>
                    <h3>Data Keys</h3>
                    <table>
                        <tr>
                            <th>Weather Conditions Value</th>
                            <th>Meaning</th>
                            <th>&nbsp;</th>
                            <th>Light Conditions Value</th>
                            <th>Meaning</th>
                        </tr>
                        <tr>
                            <td>1</td>
                            <td>Fine no high winds</td>
                            <td>&nbsp;</td>
                            <td>1</td>
                            <td>Daylight</td>
                        </tr>
                        <tr>
                            <td>2</td>
                            <td>Raining no high winds</td>
                            <td>&nbsp;</td>
                            <td>4</td>
                            <td>Darkness - lights lit</td>
                        </tr>
                        <tr>
                            <td>3</td>
                            <td>Snowing no high winds</td>
                            <td>&nbsp;</td>
                            <td>5</td>
                            <td>Darkness - lights unlit</td>
                        </tr>
                        <tr>
                            <td>4</td>
                            <td>Fine + high winds</td>
                            <td>&nbsp;</td>
                            <td>6</td>
                            <td>Darkness - no lighting</td>
                        </tr>
                        <tr>
                            <td>5</td>
                            <td>Raining + high winds</td>
                            <td>&nbsp;</td>
                            <td>7</td>
                            <td>Darkness - lighting unknown</td>
                        </tr>
                        <tr>
                            <td>6</td>
                            <td>Snowing + high winds</td>
                            <td>&nbsp;</td>
                            <td>-1</td>
                            <td>Data missing or out of range</td>
                        </tr>
                        <tr>
                            <td>7</td>
                            <td>Fog or mist</td>
                            <td colspan="3">&nbsp;</td>
                        </tr>
                        <tr>
                            <td>8</td>
                            <td>Other</td>
                            <td colspan="3">&nbsp;</td>
                        </tr>
                        <tr>
                            <td>9</td>
                            <td>Unknown</td>
                            <td colspan="3">&nbsp;</td>
                        </tr>
                        <tr>
                            <td>-1</td>
                            <td>Data missing or out of range</td>
                            <td colspan="3">&nbsp;</td>
                        </tr>
                    </table>
                </td>
            <tr>
                <td>
                    <img src="{{ lcbwcb }}" />
                </td>
                <td>&nbsp;</td>
            </tr>
            <tr>
                <td colspan="2">
                    <h2>Time Series Analysis</h2>
                </td>
            </tr>
            <tr>
                <td colspan="2">
                    <h3>Casualty Count Over Time</h3>
                    <img src="{{ cca }}" />
                </td>
            </tr>
            <tr>
                <td colspan="2">
                    <h3>Casualty Count in 2000</h3>
                    <img src="{{ cc2 }}" />
                </td>
            </tr>
            <tr>
                <td colspan="2">
                    <h3>Casualty Count in the 1980's</h3>
                    <img src="{{ cc1980 }}" />
                </td>
            </tr>
      </body>
    </html>
  10. To run this application, go to your terminal and run the following command in the root directory:
    python dashboard.py
    

    This will start Flask's internal web server and run it on port 5000. Open up a web browser and navigate to http://127.0.0.1:5000.

How it works…

  1. In dashboard.py, the first thing we do is to import the Flask, send_from_directory, and render_template methods from the Flask library. This allows us to create a Flask application, expose files from an upload folder, and render templates. Templates are what will have data inserted into them and be shown to the users when they visit the application:
    from flask import Flask, send_from_directory, render_template
  2. Next we tell Flask the location of the upload folder and the base URL for the application. I've chosen to create an upload folder in case you later want to add an upload functionality to the application as the method for updating the charts:
    UPLOAD_FOLDER = '/Users/robertdempsey/Dropbox/Private/Python Business Intelligence Cookbook/Drafts/Chapter 5/ch5_code/pbic-dashboard/charts'
    BASE_URL = 'http://127.0.0.1:5000/charts/'
  3. Next, we create a new Flask application object, and tell the application where the upload folder is:
    app = Flask(__name__)
    app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
  4. In order for Flask to serve a web page, it needs to know what to do when a user visits a URL. The following lines define a route to the home page as well as an the function that will be run when that URL is visited, which in this case is uploaded_file(). What this function does is build the full URL of each of our six charts, assign each to a variable, and then tell Flask to render the dashboard template and assign the URLs to the variables in the template:
    @app.route('/')
    def uploaded_file():
        # list the charts to show
        wcd = BASE_URL + 'weather-conditions-distribution.png'
        lcb = BASE_URL + 'light-conditions-boxplot.png'
        lcbwcb = BASE_URL + 'lc-by-wc-boxplot.png'
        cca = BASE_URL + 'casualty-count-all.png'
        cc2 = BASE_URL + 'casualty-count-2000.png'
        cc1980 = BASE_URL + 'casualty-count-1980s.png'
    
        return render_template('dashboard.html',
                               wcd=wcd,
                               lcb=lcb,
                               lcbwcb=lcbwcb,
                               cca=cca,
                               cc2=cc2,
                               cc1980=cc1980)
  5. After that, we create the route that will display the chart in the template, and define a function to be run when the URL is visited. Here, we're defining a function named send_file() which takes a filename as an argument. That filename is then passed to the send_from_directory() method, which retrieves it from the upload folder.
    @app.route('/charts/<filename>')
    def send_file(filename):
        return send_from_directory(UPLOAD_FOLDER, filename)
  6. In order to run the file at the command line as we did, we need to tell it what to run. In this instance, we are telling Python to run the Flask application that we previously defined, and turn on debugging before doing so:
    if __name__ == "__main__":
        app.debug = True
        app.run()
  7. The dashboard.html template is a much larger version of the index.html template that we created in a previous recipe. The main point to note here is that we have six image tags that look like this:
    <img src="{{ wcd }}" />
  8. When the page is rendered and we pass the values of these variables to the templates, Flask replaces the template code – {{ wcd }} – with the value we're passing in. If you view the source of the webpage, you'll see the following as the result:
    <img src="http://127.0.0.1:5000/charts/weather-conditions-distribution.png" />
  9. When you run the file using the python dashboard.py command, you should see your dashboard complete with charts! It's ugly and needs styling; however, you have six tasty charts:
    How it works…
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset