How to create an executive business intelligence dashboard in pure Python, automate continuous integration with GitHub Actions, and deploy live to the cloud with zero-downtime automation.
Published on: Medium / Dev.to / Hashnode
Reading Time: 8 min read
Tags: #python #datascience #streamlit #devops #cicd #cloud #plotly
GitHub Repository: https://github.com/Rodrig0496/AG-01-Building-and-Deploying-an-Interactive-Analytics-Dashboard
Live Demo: https://ag-01-analytics-dashboard.streamlit.app
π Introduction
In todayβs data-driven landscape, static PDF reports and spreadsheet exports are no longer sufficient for business decision-makers. Executives and operational teams expect interactive, real-time, and accessible analytical dashboards that allow them to filter date ranges, explore regional performance, and drill down into granular KPIs on demand.
Historically, developing custom analytical web applications required a full-stack engineering team proficient in JavaScript (React/Vue), backend APIs (FastAPI/Flask), CSS styling, and complex cloud infrastructure.
While tools like Dash (Plotly), R Shiny, Bokeh, and static charting libraries like Seaborn each have their distinct strengths:
- Seaborn / Matplotlib: Great for exploratory static exploratory charts in Jupyter Notebooks, but lack built-in web reactivity.
- Bokeh: Powerful for interactive web canvas plots, but requires significant boilerplate for complex app UI states.
- Dash: Highly customizable and production-grade, but demands deep familiarity with HTML/CSS components and reactive callback decorators.
- Shiny for Python: Excellent reactive paradigm, but still carries a steeper learning curve for teams coming strictly from Python data analysis.
Enter Streamlit: the open-source Python framework that has revolutionized how data scientists and engineers turn data scripts into shareable web applications in minutes, using 100% pure Python.
In this guide, we walk through the complete end-to-end lifecycle:
- Designing a production-grade Executive Sales & KPI Dashboard using Streamlit and Plotly.
- Structuring a clean, public open-source repository.
- Automating validation and testing through CI/CD pipelines using GitHub Actions.
- Deploying to a public Cloud / SaaS platform (Streamlit Community Cloud) with automated continuous deployment.
π System Architecture & Workflow
The architecture follows modern DevOps and GitOps practices for data applications:
flowchart LR
A[Local Development<br>Streamlit + Plotly] -->|git push| B[Public GitHub Repository]
B -->|Triggers| C[GitHub Actions CI<br>Linting & Smoke Tests]
B -->|Webhook Sync| D[Streamlit Community Cloud<br>Public SaaS Hosting]
D --> E[Live Web Dashboard<br>Accessible Worldwide]
Key Workflow Pillars:
-
Developer Experience: Write clean Python code with reactive data caching (
@st.cache_data). - Quality Assurance: GitHub Actions automatically lints code and runs headless smoke tests on every push.
-
Continuous Deployment (CD): Streamlit Community Cloud watches the
mainbranch and deploys updates instantaneously with zero manual server configuration.
π Repository Structure
A clean, reproducible directory structure is vital for both collaboration and automated cloud buildpacks:
AG-01-Building-and-Deploying-an-Interactive-Analytics-Dashboard/
βββ .github/
β βββ workflows/
β βββ ci.yml # Automated CI pipeline (linting & headless tests)
βββ .streamlit/
β βββ config.toml # UI styling theme & production server flags
βββ app.py # Main Streamlit dashboard application
βββ requirements.txt # Pinned Python package dependencies
βββ .gitignore # Ignore caches, virtual environments & secrets
βββ README.md # Project documentation, live links & setup guide
π οΈ Step 1: Building the Interactive Streamlit Dashboard
Our application, app.py, provides a comprehensive executive analytics experience:
- KPI Metric Scorecards with comparative deltas.
- Interactive Time-Series Chart tracking Gross Revenue vs. Net Profit.
- Market Share Donut Chart highlighting regional distribution.
- Category Performance Grouped Bar Chart analyzing product lines.
- Segment Profitability Scatter Plot correlating volume with profit margins.
- Dynamic Sidebar Filters with multi-selects and date-range pickers.
- In-Memory CSV Exporter for tabular data inspection.
1.1 Configuring Page Layout & Custom Styling
We initialize a wide layout and apply subtle dark-mode styling adjustments using Streamlit's native st.set_page_config and injected CSS:
import streamlit as st
import pandas as pd
import numpy as np
import plotly.express as px
import plotly.graph_objects as go
from datetime import datetime, timedelta
st.set_page_config(
page_title="Executive Sales & KPI Dashboard",
page_icon="π",
layout="wide",
initial_sidebar_state="expanded",
)
1.2 Optimized Data Caching with @st.cache_data
One of Streamlit's most powerful features is intelligent caching. By decorating our data ingestion function with @st.cache_data, Streamlit memoizes the dataset in memory, preventing expensive computations from re-running on every filter click:
@st.cache_data(ttl=3600)
def generate_sample_sales_data(num_records: int = 1500) -> pd.DataFrame:
np.random.seed(42)
end_date = datetime.now()
start_date = end_date - timedelta(days=365)
date_range = [
start_date + timedelta(days=int(d))
for d in np.random.uniform(0, 365, num_records)
]
regions = ["North America", "Europe", "Asia-Pacific", "Latin America", "Middle East"]
categories = {
"Cloud Solutions": ["Enterprise SaaS", "Data Storage", "Cloud Compute", "Cybersecurity"],
"Hardware": ["Servers", "Workstations", "Networking Gear", "IoT Hubs"],
"Professional Services": ["Cloud Migration", "AI Consulting", "Managed Support", "DevOps Audit"]
}
# Generate realistic revenue and profit margins
units_sold = np.random.randint(1, 15, size=num_records)
base_unit_prices = np.random.uniform(150, 4500, size=num_records)
gross_sales = np.round(units_sold * base_unit_prices, 2)
profit = np.round(gross_sales * np.random.uniform(0.15, 0.42, size=num_records), 2)
data = pd.DataFrame({
"Order_ID": [f"ORD-{10000 + i}" for i in range(num_records)],
"Date": pd.to_datetime(date_range),
"Region": np.random.choice(regions, size=num_records),
"Customer_Segment": np.random.choice(["Enterprise", "Mid-Market", "SMB", "Government"], size=num_records),
"Category": np.random.choice(list(categories.keys()), size=num_records),
"Gross_Sales": gross_sales,
"Net_Profit": profit,
})
data["Month_Year"] = data["Date"].dt.to_period("M").dt.to_timestamp()
return data.sort_values("Date")
raw_data = generate_sample_sales_data()
1.3 Interactive Sidebar Controls & Filtering
Streamlit's declarative syntax allows us to construct interactive UI controls directly in the sidebar:
with st.sidebar:
st.markdown("### βοΈ Filter Controls")
# Time Window Filter
min_date = raw_data["Date"].min().date()
max_date = raw_data["Date"].max().date()
date_selection = st.date_input("Select Time Window", value=(min_date, max_date))
# Geographic Multi-Select
selected_regions = st.multiselect(
"Geographic Regions",
options=sorted(raw_data["Region"].unique()),
default=sorted(raw_data["Region"].unique())
)
# Filter logic
filtered_data = raw_data[
(raw_data["Date"].dt.date >= date_selection[0]) &
(raw_data["Date"].dt.date <= date_selection[1]) &
(raw_data["Region"].isin(selected_regions))
]
1.4 High-Impact Visualizations with Plotly
Combining Streamlit with Plotly allows us to generate responsive, hardware-accelerated interactive charts. For example, rendering our monthly revenue trajectory:
monthly_trend = filtered_data.groupby("Month_Year")[["Gross_Sales", "Net_Profit"]].sum().reset_index()
fig_trend = go.Figure()
fig_trend.add_trace(go.Scatter(
x=monthly_trend["Month_Year"],
y=monthly_trend["Gross_Sales"],
name="Gross Sales",
mode="lines+markers",
line=dict(color="#6366F1", width=3),
fill="tozeroy",
fillcolor="rgba(99, 102, 241, 0.15)"
))
fig_trend.update_layout(template="plotly_dark", hovermode="x unified")
st.plotly_chart(fig_trend, use_container_width=True)
βοΈ Step 2: Continuous Integration & Automated Testing
Deploying data applications without automated tests is risky. A broken library version or syntax typo can crash your production dashboard. We implement a continuous integration workflow using GitHub Actions in .github/workflows/ci.yml.
Every time a team member pushes code or opens a Pull Request to main, the workflow executes:
name: Streamlit Dashboard CI/CD Pipeline
on:
push:
branches: [ main, master ]
pull_request:
branches: [ main, master ]
jobs:
validate-and-test:
runs-on: ubuntu-latest
steps:
- name: π₯ Checkout Repository
uses: actions/checkout@v4
- name: π Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"
cache: "pip"
- name: π¦ Install Dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install flake8
- name: π Lint Code with Flake8
run: |
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
- name: π§ͺ Smoke Test App Compilation
run: |
python -c "import app; print('App syntax and imports verified successfully!')"
- name: π Verify Headless Streamlit Startup
run: |
timeout 10s streamlit run app.py --server.headless=true --server.port=8501 || [ $? -eq 124 ]
echo "Streamlit successfully launched in headless mode!"
Why This Automated CI Step Matters:
-
Catches Dependency Conflicts: Guarantees that
requirements.txtcontains valid, installable packages. - Headless Smoke Test: Validates that the Streamlit server boots up and serves traffic without throwing unhandled startup exceptions.
- Guards Production: Prevents broken code from being pushed to the live cloud platform.
βοΈ Step 3: Deploying to a Public Cloud / SaaS Platform
For public deployment, we select Streamlit Community Cloudβa native public cloud SaaS platform providing global hosting, zero-configuration SSL, and native GitOps integration.
Step-by-Step Deployment Walkthrough:
- Push your code to GitHub:
git init
git add .
git commit -m "feat: complete executive streamlit dashboard with CI pipeline"
git branch -M main
git remote add origin https://github.com/Rodrig0496/AG-01-Building-and-Deploying-an-Interactive-Analytics-Dashboard.git
git push -u origin main
-
Connect Streamlit Community Cloud:
- Navigate to share.streamlit.io.
- Sign in using your GitHub account.
-
Deploy the Application:
- Click on the "New app" button.
- Select your repository:
Rodrig0496/AG-01-Building-and-Deploying-an-Interactive-Analytics-Dashboard. - Set the Branch to:
main. - Set the Main file path to:
app.py. - (Optional) Customize your App URL subdomain:
https://ag-01-analytics-dashboard.streamlit.app. - Click "Deploy!".
-
Automated Continuous Deployment (CD):
Streamlit Community Cloud registers a webhook with your GitHub repository. Whenever you or a teammate pushes commits tomain:- The GitHub Actions CI pipeline runs and validates your code.
- Streamlit Cloud automatically pulls the new commit, installs updated dependencies, and performs a live rolling reload without downtime.
(Alternative Cloud Providers: You can also deploy this containerized app to **Render, **Hugging Face Spaces, **AWS App Runner, or **Google Cloud Run* using a lightweight Dockerfile).*
π Live Application & Public Repository
The source code and live deployed instance are publicly accessible:
| Resource | Link |
|---|---|
| π¦ Public GitHub Repository | https://github.com/Rodrig0496/AG-01-Building-and-Deploying-an-Interactive-Analytics-Dashboard |
| π Live Cloud Dashboard | https://ag-01-analytics-dashboard.streamlit.app |
| π Automated CI/CD Workflow | .github/workflows/ci.yml |
π‘ Lessons Learned & Best Practices
-
Always Use Caching: Uncached data loading leads to laggy interactions because Streamlit re-executes scripts top-to-bottom on state changes. Use
@st.cache_datafor dataframes and@st.cache_resourcefor database connections or ML models. -
Containerize Server Configurations: Use
.streamlit/config.tomlto lock in headless mode and consistent branding colors so your app looks identical locally and in the cloud. -
Automate Smoke Testing: The
timeout 10s streamlit runtest in GitHub Actions saves hours of debugging by catching missing cloud packages before your users see an error screen. -
Design for Responsiveness: Utilize
st.columns()and Plotly'suse_container_width=Trueto ensure your dashboard renders gracefully on both ultra-wide desktop monitors and mobile devices.
π― Conclusion
Modern data professionals need more than just analytical algorithmsβthey need the ability to communicate insights effectively through accessible web applications.
By combining Streamlit for rapid UI development, Plotly for interactive visualization, GitHub Actions for automated CI testing, and Streamlit Community Cloud for automated continuous deployment, you can deliver production-grade data products in hours instead of weeks.
π¬ Let's Connect!
Have questions or suggestions on dashboard architecture or cloud automation? Feel free to leave a comment below or connect on LinkedIn / GitHub. If you found this article helpful, don't forget to leave a π or star the repository!
Top comments (0)