DEV Community

Brad
Brad

Posted on

Build a Real-Time Business Dashboard in Python — See All Your Metrics at a Glance

Most small businesses run on Excel and guesswork. I switched to a live Python dashboard 6 months ago — here's how to build one in an afternoon.

What We're Building

A dashboard that shows:

  • Today's revenue vs yesterday (and vs last week same day)
  • Pending orders/invoices
  • Low stock alerts
  • Top 5 customers this month
  • Simple profit/expense summary

Runs in terminal, updates every 30 seconds.

The Complete Code

import sqlite3
import time
import os
from datetime import datetime, timedelta

def clear_screen():
    os.system("cls" if os.name == "nt" else "clear")

def get_dashboard_data(db_path="business.db"):
    conn = sqlite3.connect(db_path)
    c = conn.cursor()
    today = datetime.now().date()
    yesterday = today - timedelta(days=1)
    last_week_today = today - timedelta(days=7)
    month_start = today.replace(day=1)

    # Today's revenue
    c.execute("SELECT COALESCE(SUM(amount), 0) FROM orders WHERE date(order_date) = ?", (str(today),))
    today_revenue = c.fetchone()[0]

    c.execute("SELECT COALESCE(SUM(amount), 0) FROM orders WHERE date(order_date) = ?", (str(yesterday),))
    yesterday_revenue = c.fetchone()[0]

    c.execute("SELECT COALESCE(SUM(amount), 0) FROM orders WHERE date(order_date) = ?", (str(last_week_today),))
    last_week_revenue = c.fetchone()[0]

    # Pending invoices
    c.execute("SELECT COUNT(*), COALESCE(SUM(amount), 0) FROM invoices WHERE paid = 0")
    pending_count, pending_amount = c.fetchone()

    # Overdue invoices
    c.execute("""
        SELECT COUNT(*), COALESCE(SUM(amount), 0) FROM invoices 
        WHERE paid = 0 AND due_date < ?
    """, (str(today),))
    overdue_count, overdue_amount = c.fetchone()

    # Low stock
    c.execute("SELECT name, quantity, reorder_point FROM inventory WHERE quantity <= reorder_point")
    low_stock = c.fetchall()

    # Top customers this month
    c.execute("""
        SELECT client_name, SUM(amount) as total FROM orders
        WHERE date(order_date) >= ?
        GROUP BY client_name ORDER BY total DESC LIMIT 5
    """, (str(month_start),))
    top_customers = c.fetchall()

    # Monthly expenses
    c.execute("""
        SELECT category, SUM(amount) FROM expenses 
        WHERE date(expense_date) >= ? GROUP BY category
    """, (str(month_start),))
    expenses = dict(c.fetchall())

    # Monthly revenue
    c.execute("""
        SELECT COALESCE(SUM(amount), 0) FROM orders WHERE date(order_date) >= ?
    """, (str(month_start),))
    month_revenue = c.fetchone()[0]

    conn.close()
    return {
        "today_revenue": today_revenue,
        "yesterday_revenue": yesterday_revenue,
        "last_week_revenue": last_week_revenue,
        "pending": (pending_count, pending_amount),
        "overdue": (overdue_count, overdue_amount),
        "low_stock": low_stock,
        "top_customers": top_customers,
        "expenses": expenses,
        "month_revenue": month_revenue,
    }

def render_dashboard(data):
    clear_screen()
    now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")

    # Header
    print("=" * 60)
    print(f"  BUSINESS DASHBOARD  |  {now}")
    print("=" * 60)

    # Revenue
    rev = data["today_revenue"]
    yesterday = data["yesterday_revenue"]
    lw = data["last_week_revenue"]

    vs_yesterday = ((rev - yesterday) / yesterday * 100) if yesterday > 0 else 0
    vs_last_week = ((rev - lw) / lw * 100) if lw > 0 else 0

    yoy_icon = "" if vs_yesterday >= 0 else ""
    lw_icon = "" if vs_last_week >= 0 else ""

    print(f"\n💰 TODAY'S REVENUE: ${rev:,.2f}")
    print(f"   vs yesterday:   {yoy_icon} {abs(vs_yesterday):.1f}%  (${yesterday:,.2f})")
    print(f"   vs last week:   {lw_icon} {abs(vs_last_week):.1f}%  (${lw:,.2f})")

    # Invoices
    pc, pa = data["pending"]
    oc, oa = data["overdue"]
    print(f"\n📄 INVOICES: {pc} pending (${pa:,.2f})")
    if oc > 0:
        print(f"   ⚠️  {oc} OVERDUE: ${oa:,.2f}")

    # Low stock
    if data["low_stock"]:
        print(f"\n📦 LOW STOCK ALERTS:")
        for name, qty, reorder in data["low_stock"]:
            print(f"   ⚠️  {name}: {qty} left (reorder at {reorder})")

    # Top customers
    print(f"\n👥 TOP CUSTOMERS THIS MONTH:")
    for i, (name, total) in enumerate(data["top_customers"], 1):
        print(f"   {i}. {name:20} ${total:,.2f}")

    # Monthly P&L summary
    month_rev = data["month_revenue"]
    total_exp = sum(data["expenses"].values())
    profit = month_rev - total_exp

    print(f"\n📊 MONTH TO DATE:")
    print(f"   Revenue:  ${month_rev:,.2f}")
    print(f"   Expenses: ${total_exp:,.2f}")
    print(f"   Profit:   ${profit:,.2f}")

    print("\n" + "=" * 60)
    print("Press Ctrl+C to exit | Refreshes every 30s")

def run_dashboard(db_path="business.db", refresh_interval=30):
    print("Starting dashboard... Press Ctrl+C to stop.")
    try:
        while True:
            try:
                data = get_dashboard_data(db_path)
                render_dashboard(data)
            except Exception as e:
                clear_screen()
                print(f"Dashboard error: {e}")
            time.sleep(refresh_interval)
    except KeyboardInterrupt:
        print("\nDashboard stopped.")

if __name__ == "__main__":
    run_dashboard()
Enter fullscreen mode Exit fullscreen mode

Setting Up the Database

You'll need a SQLite database with these tables:

import sqlite3

def setup_database(db_path="business.db"):
    conn = sqlite3.connect(db_path)
    c = conn.cursor()

    c.executescript("""
        CREATE TABLE IF NOT EXISTS orders (
            id INTEGER PRIMARY KEY,
            client_name TEXT,
            amount REAL,
            order_date TEXT
        );

        CREATE TABLE IF NOT EXISTS invoices (
            id INTEGER PRIMARY KEY,
            invoice_num TEXT,
            client_name TEXT,
            amount REAL,
            due_date TEXT,
            paid INTEGER DEFAULT 0
        );

        CREATE TABLE IF NOT EXISTS inventory (
            id INTEGER PRIMARY KEY,
            name TEXT,
            quantity INTEGER,
            reorder_point INTEGER
        );

        CREATE TABLE IF NOT EXISTS expenses (
            id INTEGER PRIMARY KEY,
            category TEXT,
            amount REAL,
            description TEXT,
            expense_date TEXT
        );
    """)
    conn.commit()
    conn.close()
    print("Database setup complete")

setup_database()
Enter fullscreen mode Exit fullscreen mode

Import from CSV (If You Use Excel Now)

If your current system is spreadsheets, import your existing data:

import pandas as pd
import sqlite3

def import_orders_from_csv(csv_file, db_path="business.db"):
    df = pd.read_csv(csv_file)
    # Assumes columns: client_name, amount, order_date
    conn = sqlite3.connect(db_path)
    df.to_sql("orders", conn, if_exists="append", index=False)
    conn.close()
    print(f"Imported {len(df)} orders")

import_orders_from_csv("orders.csv")
Enter fullscreen mode Exit fullscreen mode

Run It Automatically at Startup

On Linux/Mac, add to crontab to start the dashboard every morning:

# Run dashboard at 8am, output to log
0 8 * * * python3 /path/to/dashboard.py >> /tmp/dashboard.log 2>&1
Enter fullscreen mode Exit fullscreen mode

Or just run python3 dashboard.py in a terminal and keep it open.

What This Replaced

Before this dashboard, I'd spend 20-30 minutes each morning:

  • Opening QuickBooks to check payments
  • Checking inventory spreadsheet manually
  • Cross-referencing invoices against bank statement

Now I see it all in one place, updated every 30 seconds, with anomaly detection built in.


Want all 12 scripts I use to run my business automatically? The Python Business Automation Toolkit has everything: invoicing, payment reminders, inventory alerts, competitor monitoring, and email automation — $29 one-time download.

What metrics do you wish you could see at a glance? Share in the comments.

Top comments (0)