Dashboard Architecture¶
Overview¶
The Duckalog dashboard is a modern, reactive web application built with:
- Litestar - High-performance async web framework
- Datastar - Reactive UI framework with server-sent events (SSE)
- htpy - Pythonic HTML templating
- Tailwind CSS - Utility-first CSS framework
- DuckDB - Embedded analytical database
Architecture Diagram¶
┌─────────────────────────────────────────────────────────────────┐
│ Client Browser │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Home Page │ │ Views Page │ │ Query Page │ │
│ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │
│ │ │ │ │
│ └─────────┬───────┴─────────┬───────┘ │
│ │ │ │
│ ┌──────▼──────┐ ┌──────▼──────┐ │
│ │ Datastar │ │ Datastar │ │
│ │ (SSE) │ │ (SSE) │ │
│ └──────┬──────┘ └──────┬──────┘ │
│ │ │ │
│ └─────────┬───────┘ │
│ │ │
└─────────────────────────────┼───────────────────────────────────┘
│
│ HTTP/WebSocket
│
┌─────────────────────────────▼───────────────────────────────────┐
│ Dashboard Server (Litestar) │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Routes │ │ Components │ │ State │ │
│ │ │ │ │ │ │ │
│ │ - home.py │ │ - layout.py │ │ - Dashboard │ │
│ │ - views.py │ │ - tables.py │ │ Context │ │
│ │ - query.py │ │ - forms.py │ │ │ │
│ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │
│ │ │ │ │
│ └─────────┬───────┴─────────┬───────┘ │
│ │ │ │
│ ┌──────▼──────┐ ┌──────▼──────┐ │
│ │ Datastar │ │ DuckDB │ │
│ │ SDK │ │ Database │ │
│ └─────────────┘ └─────────────┘ │
│ │
└──────────────────────────────────────────────────────────────────┘
Core Components¶
1. Routes (src/duckalog/dashboard/routes/)¶
Routes define HTTP endpoints and request handlers:
- home.py - Dashboard home page with catalog statistics
- views.py - List and detail views for catalog views
- query.py - SQL query interface with real-time execution
Each route returns HTML generated by htpy components.
2. Components (src/duckalog/dashboard/components/)¶
Reusable UI components built with htpy:
- layout.py - Base layout, navigation, theme toggle
- tables.py - Data table components
- forms.py - Form components
Components are Python functions that return htpy Element objects.
3. State Management (src/duckalog/dashboard/state.py)¶
DashboardContext manages application state:
- Database connections
- View definitions
- Query execution
- Row limit configuration
4. App Factory (src/duckalog/dashboard/app.py)¶
create_app() initializes the Litestar application:
- Registers routes
- Configures static file serving
- Sets up Datastar integration
- Enables CORS and middleware
Datastar Integration¶
Server-Sent Events (SSE)¶
Datastar uses SSE for real-time communication:
- Query Execution (
/query/execute) - Sends query results as they execute
- Updates UI without page refresh
-
Streams results incrementally
-
Build Status (
/build/status) - Streams build progress updates
- Shows real-time build status
- Heartbeat every 30 seconds
Signal-Based State¶
Client-side state is managed via Datastar signals:
// Example signal structure
{
search: "", // View search query
sql: "", // SQL query text
loading: false, // Loading state
error: "", // Error messages
results: [...] // Query results
}
Signals update reactively when server sends patches.
Datastar Attributes¶
HTML elements use Datastar attributes for reactivity:
data-bind- Bind element to signaldata-on-click- Handle click eventsdata-on-input- Handle input changesdata-signals- Initialize signalsdata-show- Conditional displaydata-text- Set element text
HTML Templating with htpy¶
htpy provides Pythonic HTML generation:
from htpy import div, button, span
def my_component():
return div(class_="container")[
button(
id="submit-btn",
**{"data-on-click": "$$post('/api/submit')"}
)["Submit"],
span(id="status")["Ready"]
]
Benefits: - Type-safe HTML generation - Python IDE support - No template syntax to learn - Composability via Python functions
Styling¶
Tailwind CSS¶
Utility-first CSS framework:
- Rapid UI development
- Consistent design system
- Responsive breakpoints (sm, md, lg, xl)
- Dark mode support
Basecoat CSS¶
Additional component styling via CDN:
- Consistent spacing
- Typography
- Component primitives
Theme System¶
Dark/light mode toggle:
- Stored in localStorage
- Applied to
htmlelement - Class:
dark - Persists across sessions
Static Files¶
Served from /static/ directory:
datastar.js- Datastar client library- Custom CSS/JS (if needed)
Configured in Litestar app factory with cache headers.
Request Flow¶
1. Page Load¶
2. Interactive Action¶
Browser (Datastar) → SSE POST → Route Handler → Datastar SDK
↓
Browser (DOM) ← SSE Response ← Signal Update ← Execute Query
3. Query Execution¶
User Input → Datastar Signal → POST /query/execute
↓
Execute Query
↓
Datastar SSE Response
↓
Update UI Reactively
Development Workflow¶
Adding a New Route¶
- Create
routes/new_page.py - Define controller class with
@get()decorator - Use htpy components for HTML
- Register in
app.py
Adding a New Component¶
- Create
components/new_component.py - Define function returning htpy Element
- Use Datastar attributes for interactivity
- Import and use in routes
Adding a New Feature¶
- Define route handler
- Create/update components
- Add Datastar signals as needed
- Write tests
- Update documentation
Performance Considerations¶
SSE Connections¶
- Keep-alive connections
- Automatic reconnection
- Heartbeat every 30 seconds
- Limited concurrent connections
Query Results¶
- Row limit configurable (default: 500)
- Streaming for large results
- Pagination for view listings
- Responsive table rendering
Static Assets¶
- CDN for Tailwind/Basecoat
- Local Datastar.js
- Cache headers configured
- Minimal bundle size
Testing¶
Test Structure¶
- Unit tests - Context, components, routes
- Integration tests - Datastar SSE, search, filtering
- CLI tests - Command-line interface
- Responsive tests - Mobile/tablet layouts
Running Tests¶
# All tests
uv run pytest tests/test_dashboard.py -v
# Specific test class
uv run pytest tests/test_dashboard.py::TestSSEDashboard -v
# With coverage
uv run pytest --cov=src/duckalog/dashboard tests/test_dashboard.py
Deployment¶
Dependencies¶
Install UI dependencies:
Includes: - litestar - datastar-py - htpy - uvicorn - python-multipart
Running the Dashboard¶
# Via CLI
duckalog ui config.yaml
# Or programmatically
from duckalog.cli import ui
ui("config.yaml", host="127.0.0.1", port=8787)
Production Considerations¶
- Use reverse proxy (nginx)
- Enable HTTPS
- Set appropriate row limits
- Configure CORS if needed
- Monitor SSE connections
- Set up logging
Migration from Legacy Dashboard¶
The previous ASGI-based dashboard has been completely replaced. Key changes:
| Old | New |
|---|---|
| Legacy ASGI framework | Litestar |
| Custom HTML | htpy |
| No reactivity | Datastar SSE |
| No styling | Tailwind CSS |
| Disabled CLI | Working CLI |
See Migration Guide for details.
Future Enhancements¶
Potential improvements:
- Pagination - For large datasets
- Caching - Static file and query caching
- Authentication - User management
- Export - CSV/JSON export
- Charts - Visualization components
- Keyboard Shortcuts - Power user features
- Themes - Custom color schemes