256 Kilobytes

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

        <title>Muh Dashboard</title> 
                body            { background-color: lightcyan; } 
                table           { width:100%; border:1px solid black; background-color:beige; }
                textarea        { width:100%; resize:vertical; min-height:300px; }
        <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.

                Both of these are distributed under the MIT License: 
                        <tr><th>Number Completed </th><td id="complete">???</td></tr>
                        <tr><th>Most Recent Score</th><td id="score"   >???</td></tr>

        <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>

        // 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  
        // 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
                // 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
                // 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() {
        }, 500);

[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

[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});
Users Who Have Downloaded More RAM:
Hash Brown (2 years ago)
🐏 ⨉ 1
Posted 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

Profile Photo - August R. GarciaAugust R. GarciaLARPing as a Sysadmi...Portland, ORSite Owner

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" attributeproxiessin, 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.

Profile Photo - Hash BrownHash BrownInternet ActivistEnglandStaff

Hell motherfucking yeah sir

Download more RAM. 🐏 ⨉ 0Posted by Hash Brown 2 years ago 🕓 Posted at 05 September, 2019 06:55 AM PDT


Profile Photo - DefaultRadioBoxBanned

Thank you for the post.

Blogger at Radio Box

Download more RAM. 🐏 ⨉ 0Posted by RadioBox 2 years ago

Edit 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

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.

Register an Account