Skip to content

Build a reusable research visualization template#1

Merged
drothermel merged 5 commits into
mainfrom
04-13-setup
Apr 13, 2026
Merged

Build a reusable research visualization template#1
drothermel merged 5 commits into
mainfrom
04-13-setup

Conversation

@drothermel
Copy link
Copy Markdown
Owner

@drothermel drothermel commented Apr 13, 2026

Summary

  • scaffold a full-stack research visualization template with FastAPI, React, TypeScript, Tailwind, shadcn/ui, TanStack Query, and Plotly
  • switch local Python workflow to root uv + pyproject.toml and keep make as the main entrypoint
  • add agent-focused docs so this repo is easy to transplant into an existing project

What Changed

  • added example backend models and experiment/heatmap endpoints
  • added frontend layout, typed API client, reusable Plotly wrapper, and example Overview + Heatmap pages
  • updated local setup to use uv sync, uv run, .python-version, and uv.lock
  • fixed frontend config/runtime mismatches under ESM, including the Tailwind config issue
  • fixed Plotly modebar rendering so the toolbar stays compact and appears on hover
  • added AGENTS.md, an integration guide, an agent prompt template, and an integration smoke checklist

Verification

  • uv lock
  • uv sync
  • npm ci
  • make install
  • uv run python -c "from backend.main import app"
  • make backend
  • curl http://127.0.0.1:8000/health
  • npm run build
  • Playwright-assisted browser inspection of the heatmap page and Plotly modebar behavior

Demo

Screenshot 2026-04-13 at 4.20.48 AM.png

Screenshot 2026-04-13 at 4.21.01 AM.png

Copy link
Copy Markdown
Owner Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

@drothermel drothermel marked this pull request as ready for review April 13, 2026 08:20
@drothermel drothermel changed the title setup Build a reusable research visualization template Apr 13, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 13, 2026

Walkthrough

This pull request introduces a complete full-stack research tool template project. The backend adds a FastAPI application with CORS middleware, environment variable loading, and two API endpoints for experiments data under /api/experiments (list and heatmap). Backend models define hyperparameter configurations, metrics, and experiment results using Pydantic. The frontend is a React application using Vite, TypeScript, React Router, TanStack Query, and Plotly for visualization. It includes a sidebar layout, two pages (Overview scatter plot and HeatmapExplorer), UI components built with Radix UI and Tailwind CSS, and a typed API client. Configuration files include Python requirements, Node dependencies, Tailwind setup, and a Makefile for development. Documentation files provide integration guidance and checklists.


Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 12

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.gitignore:
- Around line 14-17: Update the .gitignore entries that currently list
backend/data/*.csv, backend/data/*.jsonl, and backend/data/*.parquet to cover
additional extensions and nested folders: replace or supplement those lines with
broader patterns such as backend/data/* (or backend/data/** for recursive
ignores) and add any specific extensions you need (e.g., .json, .txt, .xlsx) so
all data files and subdirectories under backend/data are excluded; ensure you
keep or remove the original specific patterns as appropriate for your desired
granularity.
- Around line 9-12: Update the Node section of .gitignore to also ignore local
environment variants and common debug/log files: add patterns for .env, .env.*
(including .env.local/.env.development), npm-debug.log, yarn-debug.log,
yarn-error.log, pnpm-debug.log and any .log files generated during development
so local configuration and debug logs (previously only node_modules/, dist/,
.DS_Store) are not accidentally committed; modify the existing Node block in the
file to include these additional patterns.
- Around line 1-7: Update the Python .gitignore entries to include common
build/test artifacts missing from the current list: add patterns such as
.pytest_cache/, build/, dist/, pip-wheel-metadata/, .mypy_cache/, .tox/,
.cache/, .coverage, *.pyc, *.pyo, *.pyd, *.so and env/ (if not already covered)
so that transient test/build files and wheel metadata are ignored alongside the
existing __pycache__/, *.egg-info/, .env, venv/ and .venv/ entries.

In `@backend/main.py`:
- Line 16: The ALLOWED_ORIGINS parsing uses raw .split(",") which leaves
whitespace and empty entries that can break CORS matching; update the
initialization of allowed_origins so each origin is stripped and empty strings
removed (e.g., build allowed_origins by splitting the env var, calling .strip()
on each entry, and filtering out falsy/empty results) and ensure the cleaned
allowed_origins list is used for CORS registration in the same module
(reference: allowed_origins variable in backend/main.py).

In `@backend/routers/experiments.py`:
- Around line 152-157: The comprehension that builds matching uses direct
equality between _get_config_value(e, x_param) and x_val which is fragile for
floating-point data in EXPERIMENTS; change the comparison to an approximate
check (e.g., math.isclose with a small rel/abs tolerance) or apply a
bucketing/rounding strategy (round to a fixed precision) when comparing values
for x_param and y_param so near-equal floats match reliably; update the list
comprehension building matching and any other comparisons that call
_get_config_value to use the chosen tolerance/rounding approach.
- Around line 115-116: The current filter uses min_accuracy against
e.metrics.accuracy (training accuracy) but the frontend displays bestAcc from
metrics.val_accuracy; update the filter in experiments.py so that when
min_accuracy is provided you filter on e.metrics.val_accuracy instead (i.e.,
change the list comprehension that references e.metrics.accuracy to use
e.metrics.val_accuracy), and also search for any other uses of the min_accuracy
parameter to ensure consistency with the displayed validation metric;
alternatively, if you prefer to keep training accuracy, rename the parameter to
min_train_accuracy across the API and callers (but pick one approach and update
all references such as the results filtering and API parameter/docs).

In `@frontend/src/api/client.ts`:
- Around line 34-38: The fetch call in client.ts can hang; wrap it with an
AbortController and a timeout so stalled requests are aborted and surface a
clear error: create an AbortController, pass controller.signal into
fetch(url.toString(), { signal }), start a setTimeout that calls
controller.abort() after the desired timeout, and clear that timeout after fetch
completes; ensure the error path distinguishes abort/timeouts (e.g., throw a
timeout-specific Error when controller.signal.aborted) and preserve the existing
API error behavior around res and res.ok.

In `@frontend/src/components/charts/Plot.tsx`:
- Around line 14-24: The style prop in the PlotProps interface is typed as
React.CSSProperties but React is not imported, causing a TypeScript error;
update the imports to include the React type or directly import the
CSSProperties type and update PlotProps accordingly (e.g., add an import type
for React or import type { CSSProperties } from "react" and change style?:
React.CSSProperties to style?: CSSProperties) so that the PlotProps interface
(specifically the style property) compiles under strict JSX settings.

In `@frontend/src/components/layout/Sidebar.tsx`:
- Around line 59-62: Replace the hardcoded "localhost:8000" text in the Sidebar
component footer with the app's env-driven API base used by the client: import
or call the existing config/util that exposes the API base (for example
NEXT_PUBLIC_API_BASE, NEXT_PUBLIC_API_URL, or a getApiBase() exported from your
API client module) and render that value inside the <span className="font-mono">
instead of the literal string; include a safe fallback (e.g., "unknown") if the
value is undefined so the UI stays stable.
- Around line 5-9: The NavItem interface references React.ReactNode but React is
not imported; add a type import and update the reference to avoid TS
errors—either import React (e.g., import * as React from 'react') or import the
type directly (import { ReactNode } from 'react') and change the icon property
to use ReactNode; update the NavItem interface declaration (symbol: NavItem,
property: icon) accordingly so the compiler recognizes the type.

In `@frontend/src/components/ui/card.tsx`:
- Around line 31-40: The CardTitle forwarded ref is typed as
HTMLParagraphElement but renders an <h3>; update the React.forwardRef generic to
use HTMLHeadingElement so the ref type matches the rendered element (change the
first generic parameter for CardTitle in the forwardRef call). Ensure the props
generic remains React.HTMLAttributes<HTMLHeadingElement> and keep the same
function signature and ref usage.

In `@frontend/vite.config.ts`:
- Line 9: The alias uses __dirname which breaks in ESM frontend config; replace
__dirname usage when building the "@/": path.resolve(...) alias by deriving the
config directory via import.meta.url and fileURLToPath (from 'url') and then use
path.resolve(configDir, "./src") so alias resolution is ESM-safe; update the
module where alias is defined (the path.resolve call and any imports relying on
__dirname) to use fileURLToPath(import.meta.url) to compute the base directory.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 9cbb7336-f26e-4ef9-87ce-c952cf744baa

📥 Commits

Reviewing files that changed from the base of the PR and between 9787dd1 and 7a20b67.

⛔ Files ignored due to path filters (2)
  • frontend/package-lock.json is excluded by !**/package-lock.json
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (43)
  • .gitignore
  • .python-version
  • AGENTS.md
  • Makefile
  • README.md
  • backend/.env.example
  • backend/__init__.py
  • backend/data/.gitkeep
  • backend/main.py
  • backend/models/__init__.py
  • backend/models/experiment.py
  • backend/routers/__init__.py
  • backend/routers/experiments.py
  • docs/agent-prompt-template.md
  • docs/integrating-into-existing-project.md
  • docs/integration-smoke-checklist.md
  • frontend/index.html
  • frontend/package.json
  • frontend/postcss.config.js
  • frontend/src/App.tsx
  • frontend/src/api/client.ts
  • frontend/src/api/experiments.ts
  • frontend/src/components/charts/Plot.tsx
  • frontend/src/components/layout/Layout.tsx
  • frontend/src/components/layout/Sidebar.tsx
  • frontend/src/components/ui/badge.tsx
  • frontend/src/components/ui/button.tsx
  • frontend/src/components/ui/card.tsx
  • frontend/src/components/ui/label.tsx
  • frontend/src/components/ui/select.tsx
  • frontend/src/components/ui/separator.tsx
  • frontend/src/components/ui/slider.tsx
  • frontend/src/index.css
  • frontend/src/lib/utils.ts
  • frontend/src/main.tsx
  • frontend/src/pages/HeatmapExplorer.tsx
  • frontend/src/pages/Overview.tsx
  • frontend/src/types/experiment.ts
  • frontend/tailwind.config.js
  • frontend/tsconfig.json
  • frontend/tsconfig.node.json
  • frontend/vite.config.ts
  • pyproject.toml

Comment thread .gitignore
Comment thread .gitignore
Comment thread .gitignore Outdated
Comment thread backend/main.py Outdated
Comment thread backend/routers/experiments.py Outdated
Comment thread frontend/src/components/charts/Plot.tsx
Comment thread frontend/src/components/layout/Sidebar.tsx
Comment thread frontend/src/components/layout/Sidebar.tsx
Comment thread frontend/src/components/ui/card.tsx
Comment thread frontend/vite.config.ts Outdated
@drothermel drothermel merged commit c51727b into main Apr 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant