Shape a Streamlit Filter Bar Before the Refresh Loop Starts Rushing

Shape a Streamlit Filter Bar Before the Refresh Loop Starts Rushing
Suggested cover: a Streamlit dashboard with a left sidebar full of filters, sliders and checkboxes before the charts begin.

Imports and connection setup deserve to stay visible at the top

The first screen controls matter, but they only make full sense once the file opening is visible. In this dashboard the top of the file already tells the reader almost everything: which libraries are involved, that PostgreSQL is part of the flow, and that time-window logic will matter later.

That is why this article now starts a little earlier. Instead of jumping straight to widgets, it restores the import block and the connection helper so the rest of the page can still be traced back into the original file without guesswork.

TermMeaningWhy it matters
Import surfaceThe libraries declared before any Streamlit logic begins.It signals that the page depends on dataframes, PostgreSQL and time-based filtering.
Connection helperThe function that creates the database handle.It keeps the database settings in one identifiable place before the loader uses them.
Sidebar stateThe slider and checkbox that define the visible slice.These values drive the later refresh and query flow.

The file opens with a compact import block

import streamlit as st
import pandas as pd
import psycopg2
from datetime import datetime, timedelta

The import surface stays small and literal, which makes the rest of the file easier to reconstruct in the same order.

This is a helpful opening because it keeps the dashboard identity visible. The file is clearly about Streamlit, dataframe work, PostgreSQL access and time-window calculations before any UI component is rendered.

The database helper is easier to follow in its own slice

def get_connection():
    return psycopg2.connect(
        dbname="CAR",
        user="postgres",
        password="1234",
        host="localhost",
        port="5432"
    )

The connection settings now remain visible as a standalone block, so the loader can still point back to one direct helper.

Keeping the connection helper separate is useful because later code can call it without repeating credentials or reshuffling the file structure around the query layer.

Page setup and controls can stay split into two smaller blocks

st.set_page_config(page_title="Traffic Dashboard", layout="wide")
st.title("Traffic Monitoring Dashboard")

The page frame and the title are left together, because they define the opening canvas before any filters appear.

with st.sidebar:
    st.header("Filters")
    hours = st.slider("Show last N hours", 1, 24, 6)
    auto_refresh = st.checkbox("Auto refresh (every 10 sec)", value=False)

The sidebar state sits in its own block now, which makes the window selector and the refresh toggle easier to lift back into the original script.

  • The imports are visible again, so the article no longer skips the top of the file.
  • The connection helper is back as a direct slice instead of being implied by later code.
  • The UI opening is spread across smaller code blocks, which makes each step easier to read and reuse.
A dashboard is easier to rebuild when the top of the file still shows imports, connection setup and controls in their original order.