Drop in a spreadsheet, say what you want to know, and get an interactive dashboard.
Hillside AI is a web app I built that turns a CSV or Excel file into a dashboard. It profiles the data, talks through what you want to learn, then builds a page of charts, KPI cards and tables that you can filter, rearrange and edit, by hand or by asking the AI. (The project started under the name ONYX, hence the repository name.)
- Upload CSV, TSV and Excel (
.xlsx,.xls,.xlsb) files. Uploads are converted to Parquet for fast reloads. - Profiling: column types, unique values, missing values, min, max and mean, shown as a summary table.
- Automatic dashboards: a rules engine scores every column and picks KPI cards, bar, line, pie, scatter and histogram charts, tables, and maps when it finds latitude and longitude. It also adds views such as totals by day of week or hour of day, and conversion rates for yes/no columns.
- AI chat that builds and refines dashboards, with streamed responses.
- Choose your model: 13 models from Google Gemini, Anthropic Claude, OpenAI and Groq, 7 of them free tier.
- Filters: date ranges (7, 30 or 90 days, year to date, custom) and field filters, applied to every chart.
- Combine data: join two datasets on matching key columns, or stack files with the same layout.
- Projects and accounts: email and password (JWT) or Google sign-in. Work done as a guest moves to your account when you sign up.
- Export the data to CSV, and save the key insights as a PNG.
flowchart LR
UI["Browser<br/>vanilla JS, Plotly.js, GridStack"] -->|REST + streaming| API["FastAPI"]
subgraph Backend
API --> R["Routers<br/>auth, projects, datasets, visuals, models"]
R --> ING["Ingestion<br/>pandas → Parquet"]
R --> VIS["Visual engine<br/>column scoring, chart specs"]
R --> LLM["LLM router"]
end
ING --> FS[("File storage")]
R --> DB[("SQLite<br/>SQLModel")]
LLM --> P["Gemini · Claude · OpenAI · Groq"]
The backend does the analysis and sends chart specifications; the frontend draws them with Plotly.js and lays them out on a GridStack grid.
git clone https://github.com/vikwillberg/Onyx-AI.gitcd Onyx-AI && python -m venv .venvsource .venv/bin/activate # Windows: .venv\Scripts\Activate.ps1pip install -r backend/requirements.txtuvicorn app.main:app --app-dir backend --port 8002Then open http://127.0.0.1:8002. The Datasets/ folder has about 30 public sample datasets to try
(sales, pizza orders, subscriptions, web sessions and more).
Create backend/.env with a key for any provider you want to use. Groq and Gemini both have free tiers.
GROQ_API_KEY=your-key # https://console.groq.com
GEMINI_API_KEY=your-key # https://aistudio.google.com
CLAUDE_API_KEY=your-key # https://console.anthropic.com
OPENAI_API_KEY=your-key # https://platform.openai.com| Variable | Default | Purpose |
|---|---|---|
JWT_SECRET_KEY |
change-me |
Signs login tokens. Set your own in production. |
DATABASE_URL |
sqlite:///./app.db |
Database connection |
STORAGE_DIR |
./storage |
Where uploaded files are kept |
CORS_ORIGINS |
["http://localhost:3000"] |
Allowed browser origins |
GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET |
(empty) | Turns on "Sign in with Google" |
render.yaml describes the service for Render: connect the repository as a Blueprint
and it installs the backend, generates a JWT secret and starts the server.
backend/app/
├── main.py # FastAPI app; also serves the frontend
├── routers/ # auth, Google sign-in, projects, datasets, visuals, models
├── services/
│ ├── ingestion.py # file reading, profiling, merge and stack
│ ├── visuals.py # column scoring and chart selection
│ ├── llm.py # model registry and provider calls
│ └── storage.py
├── models.py, schemas.py, db.py
└── core/ # settings, auth helpers
frontend/ # index.html, app.js, styles.css
Datasets/ # sample data
render.yaml # Render deployment
Built by Viktor Berg · LinkedIn · Released under the MIT License



