Making a Dashboard in Dash (pt.1)

George Reyes
4 min readJan 29, 2021

This article should help you get familiar with setting up a multipage application utilizing the Dash framework.
[Entire Code on GitHub]

Preview of the Graph Entity Search Feature

To show how to do this I will make a marketing dashboard with a broad range of functionality. The features will include:

  • - a Google Knowledge Graph API integration for Entity Searching
  • - a Scrapy Scraper for Google SERP Results
  • - a Response parser — for Dataframe Visualizations

To get started open up your Python editor and setup a virtual environment by inputting the lines below in your terminal.

mkdir Vigil
cd Vigil
mkdir dashboard
# Creates our virtual env
python3 -m venv vigil_dash
# Activates our
source vigil_dash/bin/activate
# to exit virtual environment type in: deactivate
cd dashboard

Now we must set up our project structure as pictured below:

|-- dashboard
|-- assets # create using: mkdir assets
|-- data
|-- pages
|- serpScraper.py
|- nlpStats.py
|- knowledgeGraph.py
|- home.py
|- blog.py
|- overview.py
|-- googler
|- app.py # create using: touch app.py
|- utils.py
|- keywordQuery.py
|- yourCreds.py
|- requirements.txt

If you are unfamiliar with the command line then look into the commands “mkdir” to make folders and “touch” to make a new file. Alternatively go into your folder system and manually make each folder and file.

Now it’s time to install our packages: Pandas, Flask, Dash and Scrapy

pip install flask
pip install dash
pip install pandas
pip install scrapy

It’s time to setup our Flask app utilizing the Dash framework. Head over to your app file and copy the code below:

import flask
import dash
import dash_html_components as html
import dash_core_components as dcc
from dash.dependencies import Input, Output, State
from dash.exceptions import PreventUpdate
import pandas as pd
import time
# from keywordQuery import knowledge_graph, KG_API
from pages import (
blog,
serpScraper,
home,
knowledgeGraph,
nlpStats,
overview,
)
server = flask.Flask(__name__)app = dash.Dash(
__name__,
server=server,
suppress_callback_exceptions=True
)
app.layout = html.Div(
[dcc.Location(id="url", refresh=True), html.Div(id="page-content")]
)
# Update page
@app.callback(Output("page-content", "children"), [Input("url", "pathname")])
def display_page(pathname):
if pathname == "/blog":
return blog.create_layout(app)
elif pathname == "/graphapi":
return knowledgeGraph.create_layout(app)
elif pathname == "/serpscrape":
return serpScraper.create_layout(app)
elif pathname == "/":
return home.create_layout(app)
elif pathname == "/nlpstats":
return nlpStats.create_layout(app)
else:
return overview.create_layout(app)
# all callbacks for pages go here# Knowledge Graph Callback
# @app.callback(
# Output("scraped", "data"),
# [Input('button', 'n_clicks')],
# state=[State("input2", "value")]
# )
# def update_output(n_clicks, input2):
# if n_clicks is None:
# raise PreventUpdate
# else:
# searched2 = knowledge_graph(key=KG_API, query=input2)
# searched2['#'] = list(range(1, len(searched2) + 1))
# return searched2.to_dict('rows')


# fyi: keeping data queries withing data callbacks ensures fresh data is coming in upon input change
if __name__ == '__main__':
app.run_server(debug=False)

There is a lot going on in the file above, especially if you are not familiar with the codebase. Essentially what you need to understand is that Dash is powered by Flask under the hood. You can use Flask for many different applications but in this instance we are using it to power our server so we can visualize our code in the browser.

The function display_page() I wrote above serves as an if statement that switches the routes of the application, this serves to make the app have “multiple” pages or tabs. If you look at the code once a URL is clicked, depending on the pathname we call its corresponding function so that we may render it.

The @app.callback and update_output() function serve as our state management of sorts. Depending on your skill level as a developer you may already be familiar with similar libraries such as: Provider/BLoC in Dart or RxJS in JavaScript. If you are not then here is a quick breakdown, you must remember that your application is dumb, just because you pass in data/inputs does not mean that the app will now how to handle/react to those inputs. So you need to create some logic to tell your application what to do once a certain input/data is received.

Next step is to make our header so we have a menu at the top right of our screen. To make this menu go to your “utils” file and copy in the code below:

You will need to add in your own image where I state in the comment below, if you do not have one here is mine: [GR]

import dash_html_components as html
import dash_core_components as dcc
def Header(app):
return html.Div([get_header(app), html.Br([])])
def get_header(app):
header = html.Div(
[
html.Div(
[
html.Div(
[dcc.Link([
# !!!! CHANGE OUT THIS FILE TO YOUR FILE OF CHOICE TO GET A LOGO AT THE TOP LEFT !!!!
html.Img(src=app.get_asset_url("logoGR.png"), style={"marginTop": "12px", "marginLeft": "24px"}, className="logo")
],
href="/")],
className="five columns",
),
html.Div([
html.Div(
[
dcc.Link(
"Portfolio",
href="/",
className="tab first",
),
html.A(
"Blog",
href="https://georgereyes.dev/",
className="tab",
),
dcc.Link(
"SERP Scraper",
href="/serpscrape",
className="tab",
),
dcc.Link(
"Knowledge Graph API",
href="/graphapi",
className="tab",
),
dcc.Link(
"NLP Analysis",
href="/nlpstats",
className="tab",
)
],
className="row all-tabs",
)
], className="seven columns")
],
className="twelve columns",
style={"padding-left": "0", "color": "white"},
)
],
className="row", style={"background-color": "white", "padding-bottom": "10px"}
)
return header
def make_dash_table(df):
""" Return a dash definition of an HTML table for a Pandas dataframe """
table = []
for index, row in df.iterrows():
html_row = []
for i in range(len(row)):
html_row.append(html.Td([row[i]]))
table.append(html.Tr(html_row))
return table

To style our application I scraped an open source bootstrap css theme recommended by the Dash Framework, you should download the files and place them inside your assets folder: [assets]

The last step in the first part of this tutorial is to add the code below for each of your page files under the pages directory. The other tutorials will focus on fleshing out each of these pages with common marketing tools, but for the sake of brevity we will end this one here.

import dash_html_components as html
from utils import Header
def create_layout(app):
return html.Div([
html.H6("This is page x"),
html.Div([Header(app)])
], className="page")

To quickly run your application under the dashboard directory run:

flask run

If you enjoyed this tutorial and would like to see more you can find them on here, or from my personal website under the insights section:

https://georgereyes.dev/

--

--

George Reyes

Software engineer with experience in Python, TypeScript and Dart.