feat: add Streamlit web interface with interactive dashboard#6
Merged
Conversation
Update author name from "mcaxtr" to "Marcus Castro" in LICENSE and setup.cfg. Add .claude/, CLAUDE.md, and web runtime directories to .gitignore.
Replace matplotlib and seaborn with plotly for interactive visualization. Add streamlit, humanize, kaleido, and pydantic as core dependencies. Register spkmc.web and spkmc.models packages in setuptools. Add e2e optional dependency group for pytest-playwright. Add pytest e2e marker definition.
Add parameters dict to the Experiment model for storing global default parameters that scenarios inherit from. Wire it through from_config() to preserve the field when loading experiment configurations.
Add analyze_scenario() method to AIAnalyzer for single-scenario analysis with dedicated prompt and system prompt. Add formatting guidelines to all analysis prompts for consistent markdown output with section headers, blockquotes, and visual separators. Increase experiment analysis max_tokens from 2000 to 2500.
Extract _build_markdown_content() and _build_html_content() as public class methods, enabling the web interface to generate export data without writing to disk. Add to_bytes() for in-memory serialization. Handle missing kaleido gracefully for plot generation failures.
Add the foundational web interface modules: - __init__.py: Package initialization with version info - config.py: WebConfig class for JSON prefs and Streamlit secrets management, with SPKMC_WEB_CONFIG_FILE env var override - state.py: Typed SessionState accessors for all Streamlit session state, preventing raw st.session_state access throughout the app - app.py: Main Streamlit entry point with sidebar navigation, page routing, and CSS injection
Add the visual and charting layer: - styles.py: Complete CSS design system with teal palette, Plus Jakarta Sans typography, dark sidebar, card renderers (stat cards, experiment cards, scenario cards), and responsive layout utilities - components.py: Reusable UI components including network/distribution/ simulation parameter forms, result metric cards, and status badges - plotting.py: Core Plotly figure builders for SIR curves with error bands, state toggles, chart type switching, and multi-scenario comparison overlays
Replace matplotlib/seaborn with Plotly for all CLI visualization. Import core figure builders from spkmc.web.plotting to share code between CLI and web interface. Update Visualizer class to produce interactive HTML charts (opens in browser) and support static image export via kaleido. Update test assertions and docs code examples for the new Plotly-based API.
Add subprocess-based execution engines: - runner.py: SimulationRunner class that launches scenarios as background subprocesses with dynamic Python script generation, filesystem-based status tracking, atomic JSON writes, PID liveness checks, and dead-process detection - analysis_runner.py: AnalysisRunner class for AI-powered analysis as background subprocesses, with backup/restore safety for existing analysis artifacts and proper API key propagation
Add the three main UI pages: - dashboard.py: Experiments list with summary stat cards, experiment cards with status badges, create experiment modal with full parameter configuration, and empty state handling - experiment_detail.py: Single experiment view with global parameter display, scenario cards, scenario detail modal with interactive Plotly charts, S/I/R toggles, chart type switching, multi-scenario comparison, export popover, and AI analysis integration. Includes add/edit scenario flows and update_scenario_in_experiment() for safe parameter editing with result file lifecycle management - settings.py: Preferences page with AI configuration, chart preferences, default simulation parameters, storage paths, and danger zone reset functionality
Add 'spkmc web' CLI command with --port, --host, and --no-browser options. Launches the Streamlit server as a subprocess with preconfigured theme settings. Also update batch->experiment terminology in comments for consistency.
Add comprehensive test suite for all web interface modules: - test_state.py: SessionState accessors and typed getters/setters - test_config.py: WebConfig JSON persistence and secrets management - test_runner.py: SimulationRunner subprocess lifecycle and status - test_analysis_runner.py: AnalysisRunner script generation and safety - test_plotting.py: Plotly figure builders for SIR curves and overlays - test_experiment_detail.py: Scenario update logic, label collision detection, and result file lifecycle on parameter changes
Add end-to-end test suite using Playwright for browser testing: - conftest.py: Session-scoped Streamlit server fixture, pre-seeded experiment data with synthetic SIR curves, page helper functions - fixtures/: Committed experiment definition (data.json) with result JSONs generated dynamically at runtime - test_navigation.py: Sidebar nav, page routing, title, version - test_dashboard.py: Stats cards, create modal, experiment cards, create experiment flow - test_experiment_detail.py: Global params, scenario cards, detail modal with chart controls, comparison, export, and AI button state - test_settings.py: Preference sections, inputs, reset button Update pytest.ini to exclude E2E tests from default test runs and register the e2e marker.
Add e2e job to GitHub Actions that runs Playwright tests on ubuntu-latest with Python 3.11 after lint and test jobs pass. Installs Chromium and Firefox browsers, uploads artifacts on failure. Add --ignore=tests/e2e to the unit test step to prevent import errors when pytest-playwright is not installed.
Expand README.md with full web interface documentation including launch commands (spkmc web), detailed feature descriptions, architecture diagram, design decisions, configuration guide, workflow walkthrough, troubleshooting section, and development guide. Add complete project structure covering all modules (web, analysis, CLI, core, tests). Consolidate documentation from separate doc files into a single authoritative reference.
- Bump minimum Python from 3.8 to 3.9 (streamlit>=1.48.0 dropped 3.8) - Replace os.kill(pid, 0) with psutil.pid_exists() for cross-platform dead-process detection in runner.py, analysis_runner.py, and state.py - Fix path assertion in test_runner.py to use repr() matching script embedding (Windows backslash escaping) - Update CI matrix, pyproject.toml, setup.cfg, and black target-version - Remove CLAUDE.md from git tracking (already in .gitignore)
- Reformat settings.py, styles.py, experiment_detail.py with black 26.x - Update pre-commit black from 24.3.0 to 26.1.0 (2026 stable style) - Pin CI black to >=26,<27 to prevent version drift
- Remove unused os import from runner.py (replaced by psutil) - Remove unnecessary global statement in config.py (F824) - Align CI flake8 extend-ignore with pre-commit config
- Use stHeading testid instead of stTitle (Streamlit 1.54+ changed it) - Replace index-based card lookups with text-based lookups to handle card reordering when test_create_experiment_flow persists across browser passes (Chromium creates experiment, Firefox sees it at idx 0)
The experiment card text is rendered via st.markdown (non-clickable div), while the actual navigation trigger is st.button inside the same container. Find the container by text, then click its button element.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Add a complete browser-based web interface for SPKMC built with Streamlit and Plotly. This enables self-service experiment management for users who prefer a GUI over the CLI, while maintaining full compatibility with the existing command-line workflow.
43 files changed, ~11,100 insertions, ~600 deletions across 15 focused commits.
What this PR adds
spkmc/web/) -- Full Streamlit application with dashboard, experiment detail, and settings pagesspkmc webCLI command -- Launch the web interface with--port,--host, and--no-browseroptionsFeatures
Experiments Dashboard
Experiment Detail
Settings / Preferences
Design System
Architecture
Key design decisions
Breaking changes
spkmc plotnow produces interactive HTML charts (opens in browser) instead of matplotlib windowsVisualizer.plot_result()API signature unchangedstreamlit>=1.48.0,plotly>=5.18.0,kaleido>=0.2.1,humanize>=4.0.0Test coverage
Unit tests (417 pass, 19 skip)
test_state.pytest_config.pytest_runner.pytest_analysis_runner.pytest_plotting.pytest_experiment_detail.pyE2E tests (49 tests across 4 files)
test_navigation.pytest_dashboard.pytest_experiment_detail.pytest_settings.pyE2E uses pre-seeded fixture data with synthetic SIR curves -- no actual simulations run during tests.
Commit log
chore: update author metadata and gitignorechore: replace matplotlib/seaborn with plotly and add web depsfeat(models): add global parameters field to Experimentfeat(analysis): add scenario-level analysis and formattingrefactor(io): extract content builders in DataManagerfeat(web): add core infrastructurefeat(web): add design systemrefactor(visualization): migrate CLI plotting to plotlyfeat(web): add simulation and analysis runnersfeat(web): add dashboard, experiment detail, settings pagesfeat(cli): add web commandspkmc weblaunchertest(web): add unit tests for web modulestest(e2e): add Playwright E2E test suiteci: add E2E job to GitHub Actionsdocs: comprehensive web interface documentationTest plan
pytest tests/ --ignore=tests/e2e-- all 417 unit tests passpytest tests/e2e/ --browser chromium-- E2E tests pass against running Streamlit serverspkmc web-- launches web interface, dashboard loads with experiment cardsspkmc run -n er -d gamma-- CLI still works with Plotly outputspkmc plot <result.json>-- opens interactive chart in browser