How to Make a Simple, Automatically-Updating Dashboard for Python Scripts Using HTML, JavaScript, and JSONP
Debugging with print("asdf1") messages is adequate, but has limitations. Conveniently, it's fairly straightforward to put together a basic, auto-updating HTML dashboard with minimal code and basically no dependencies.
How to Make a Simple, Automatically-Updating Dashboard for Python Scripts Using HTML, JavaScript, and JSONP
Articles in Scripting and Automation | By August R. Garcia
Published | Last Update
Debugging with print("asdf1") messages is adequate, but has limitations. Conveniently, it's fairly straightforward to put together a basic, auto-updating HTML dashboard with minimal code and basically no dependencies.
1,510 view, 1 RAM, and 2 comments
When writing arbitrary scripts with Python, printing arbitrary debugging messages to the screen is adequate, but has limitations. Data can be hard to read and update, the output is purely text-based, and applications that are multithreaded can quickly become chaotic and difficult to follow.
Some basic methods to improve a Python script's UI/debugging messages include:
- Using a library like Termcolor (or directly adding escape sequences) to highlight, color, or markup text printed to the terminal.
- Using a library like PrettyTable to display arbitrary data in tablular form via the creation of text-based tables.
- Using commands like
os.system('cls' if os.name == 'nt' else 'clear')
to clear old data from previous loops. - Using logging to output messages to one or more files, rather than to the terminal.
Of course, these are all still text-based solutions for outputting text, which has a number of inherent limitations. To get around this:
- There are libraries like Tkinter that can be used to create GUIs, but then you have to learn how to use Tkinter, which requires effort.
- Alternatively, there are web frameworks like Django that can be used to create web applications, which could also be used for a basic dashboard, but for a basic dashboard, this is probably excessive.
Conveniently, it's fairly straightforward to put together a basic HTML dashboard with extremely minimal code and basically no dependencies. See cover image for this post for a screenshot of the code below running locally on FireFox.
The Files and Code
[index.html] The HTML/JS Template File
<html>
<head>
<title>Muh Dashboard</title>
<style>
body { background-color: lightcyan; }
table { width:100%; border:1px solid black; background-color:beige; }
textarea { width:100%; resize:vertical; min-height:300px; }
</style>
</head>
<body>
<h1>Muh Dashboard</h1>
<!--
HTML template that will be used to display the data
You could also use a library like chart.js or the DataTables jQuery plugin for
additional flexibility/functionality in displaying data.
https://datatables.net/
https://www.chartjs.org/
Both of these are distributed under the MIT License:
https://opensource.org/licenses/MIT
-->
<table>
<thead>
<tr><th>Field</th><th>Value</th></tr>
</thead>
<tbody>
<tr><th>Number Completed </th><td id="complete">???</td></tr>
<tr><th>Most Recent Score</th><td id="score" >???</td></tr>
</tbody>
</table>
<textarea id="msg"></textarea>
<!-- Force a dashbaord refresh faster than the auto-refresh interval set below -->
<button onclick="load_jsonp()">Refresh Dashboard</button>
<!-- Div that JSONP will be loaded into -->
<div id="jsonp_target"></div>
<script>
// The function that loads in the JSONP and then creates a script tag to execute it
// You could alternatively use asyncronous requests to a pure JSON file, however
// this causes cross-origin resource sharing (CORS) errors to occur if you're
// running this on localhost (which you probably are, for a one-off Python dashboard.
// There are other CORS workarounds with localhost, but they're basically all more
// involved than using JSONP instead.
function load_jsonp() {
var s = document.createElement("script");
s.src = "data.json";
// Make sure to clear the previous script tag, since otherwise
// a new script tag will be inserted on each interval.
// This can easily become an obscene amount of HTML if the tab is left open for
// a non-trivial amount of time, which can cause the tab to lag or crash.
document.getElementById("jsonp_target").innerHTML = '';
// Inject the script tag, which the browser will then execute
document.getElementById("jsonp_target").appendChild(s);
}
// The thing to do with the JSON parsed/received via the JSONP response
function myFunc(myObj) {
// Assist with debugging by logging the JSON objects full data to the console
console.log(myObj);
// This can alternatively be done as a table. See:
// https://www.256kilobytes.com/content/show/10378/5-tasks-you-didnt-know-could-be-done-from-the-developer-console
console.table(myObj);
// Insert specific pieces of data from the JSON data into the page's HTML
document.getElementById("complete").innerHTML = myObj.complete;
document.getElementById("score" ).innerHTML = myObj.score ;
// Append the latest log message as as tab-separated data. See:
// https://www.256kilobytes.com/content/show/10868/the-virgin-csv-vs-the-chad-tsv
document.getElementById("msg" ).innerHTML += myObj.msg + "\t" + myObj.complete + "\t" + myObj.score + "\n" ;
}
// Every half a second, load the json in from the data.json file and use it to update the dashbaord
setInterval(function() {
load_jsonp();
}, 500);
</script>
</body>
</html>
[dashboard.py] The Python Script
import random, time, json
iii = 1
while True:
# Some arbitrary data in a dictionary
data = {
"complete" : iii ,
"score" : random.randint(0,999999) ,
"msg" : "Loop %s has finished..." % iii
}
# The file that the python script will write to whenever there is updated data
with open('data.json', 'w') as f:
f.write( "myFunc(" ) # Start of the JSONP's JS function
json.dump(data, f) # The dict converted to JSON
f.write( ");" ) # Close the JSONP's JS function
iii += 1
time.sleep(random.randint(0,3))
[data.json] The Automatically-Generated JSONP File
This file is automatically created and updated/replaced by the Python script. The content below is an example of this output.
myFunc({"msg": "Loop 693 has finished...", "score": 408418, "complete": 693});








Hash Brown (2 years ago) 🐏 ⨉ 1Posted by August R. Garcia 2 years ago
Edit History
• [2019-09-05 4:39 PDT] August R. Garcia (2 years ago)• [2019-09-05 4:39 PDT] August R. Garcia (2 years ago)
🕓 Posted at 05 September, 2019 04:39 AM PDT
- C U How to Make a Simple, Automatically-Updating Dashboard for Python Scripts Using HTML, JavaScript, and JSONP
- C U [BASH, cURL] Yellow Pages Scraper: Fully Functional Script with Source Code
- C U [cURL, BASH] How to Crawl and Scrape DuckDuckGo Search Results
- C U The Basics to Web Scraping with cURL and XPath
- C U Extracting Emails from HTML with Google Sheets: Get Contact Information in Bulk for Guest Posts, (lmao) 404 Re...
- C U [Infographic] The Beginner's SQLite Cheat Sheet
- C U Analyzing the Web: Downloading the Majestic Million, Setting up SQLite, Crawling the Web, and Generating Repor...
- C U Downloading Bulk Images: ThisPersonDoesNotExist with Python and urllib2
- C U Spit in the Face of God: Five Tasks You Didn’t Know Could be Done with Google Sheets
- C U An introduction to scraping with Python and BeautifulSoup
August Garcia is some guy who used to sell Viagra on the Internet. He made this website to LARP as a sysadmin while posting about garbage like user-agent spoofing, spintax, the only good keyboard, virtual assitants from Pakistan, links with the rel="nofollow" attribute, proxies, sin, the developer console, literally every link building method, and other junk.
Available at arg@256kilobytes.com, via Twitter, or arg.256kilobytes.com. Open to business inquiries based on availability.
Hell motherfucking yeah sir
"THAT DOG IS GETTING RAPED" - Terry A. Davis
Thank you for the post.
Blogger at Radio BoxEdit History
• [2019-09-21 4:07 PDT] RadioBox (2 years ago)• [2019-09-21 4:07 PDT] August R. Garcia (2 years ago)
🕓 Posted at 21 September, 2019 04:07 AM PDT
Post a New Comment
To leave a comment, login to your account or create an account.
Do you like having a good time?
Register an Account
You can also login to an existing account or reset your password. All use of this site is subject to the terms of service and privacy policy.
Read Quality Articles
Read some quality articles. If you can manage to not get banned for like five minutes, you can even post your own articles.
View Articles →
Argue with People on the Internet
Use your account to explain why people are wrong on the Internet forum.
View Forum →
Vandalize the Wiki
Or don't. I'm not your dad.
View Wiki →
Ask and/or Answer Questions
If someone asks a terrible question, post a LMGTFY link.
View Answers →
Make Some Money
Hire freelancers and/or advertise your goods and/or services. Hire people directly. We're not a middleman or your dad. Manage your own business transactions.