NutriSight is a local-first FastAPI web app for photo-based nutrition logging with a mobile-first multi-page UI. It supports:
- scan a meal photo and get AI-detected food items with editable macros
- manually log foods via search against a 7,800+ item nutrition database
- AI food lookup: get nutrition estimates for any food via LLM, with optional web search
- edit AI estimates (name, macros) and save to the database for future use
- save favorite foods for one-tap re-logging
- review and edit meals after saving (update items, macros, delete)
- daily dashboard with calorie and macro tracking
- AI-powered meal recommendations for the rest of the day (Indian vegetarian default)
- full meal history with trends, grouped by day
- per-user accounts with persistent device sessions
- configurable AI provider (LM Studio, Ollama, API, or stub)
The app is organized into focused mobile-first pages with a bottom tab bar:
- FastAPI + Jinja2 server-rendered templates
- Vanilla JavaScript with per-page modules (
shared.js,analyze.js,log.js) - SQLite for meals, nutrition catalog, users, and settings
- LM Studio integration (OpenAI-compatible API) for vision detection and portion estimation
- Direct LM Studio calls from browser for meal recommendations (proxied through
/api/llm/chatto avoid CORS)
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
# Quick start (kills any existing server on port 8000 and restarts)
./host.sh
# Or manually
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000Then open http://localhost:8000 from your laptop or http://<your-lan-ip>:8000 from your phone on the same network.
pytest tests/ -v57 tests covering:
- Nutrition math, daily aggregation, and user-scoped trend helpers
- API endpoint validation (save meals, search, admin CRUD, LLM proxy)
- AI food lookup (input validation, LLM estimation, DB persistence)
- LM Studio payload parsing and service integration
- Playwright UI tests for the AI Help modal (visibility, interaction, edit flow, save-to-DB integration)
- Camera capture with client-side image compression
- AI detection via LM Studio with Qwen3-VL
- Item cards show all macros (P/C/F) and calories
- Tap macros to edit via popup; changes override auto-calculated values
- S/M/L portion toggle + grams stepper
- Change food mapping via full-text search
- Undo on item removal
- Calls LM Studio directly to suggest meals for remaining meal slots
- Accounts for remaining calories, protein, carbs, and fat
- Time-aware: breakfast (8am), lunch (12pm), snack (4pm), dinner (7pm)
- 2 options per meal slot with ingredient weights
- Dynamic per-meal calorie allocation that sums to the full budget
- Adjustable calorie budget with −/+ buttons (100 kcal steps)
- Indian vegetarian by default; override with keyword input
- Refresh button to regenerate suggestions
- Hidden after 9pm (no meals suggested)
- Floating "AI Help" button opens a centered modal
- Type any food or dish name to get AI-estimated nutrition (calories, protein, carbs, fat)
- Optional web search toggle queries DuckDuckGo for a second data point
- Edit button lets you customize the food name and all macro values before saving
- "Use in meal" adds the item (original or edited) to the meal builder
- "Save to DB" persists to the nutrition database so it's searchable next time
- Refresh button re-runs the lookup
- Input validated against injection attacks (regex whitelist, max 200 chars)
- 14-day bar chart and day-grouped meal list
- Tap to expand meal detail with per-item macros
- Edit button: inline editing of meal name, grams, calories, and all macros per item
- Delete items or entire meals
- Top logged foods section
- Dark card with today's calorie/macro summary and remaining budgets (protein, carbs, fat)
- Hover/touch on recommendation cards previews how remaining budgets would change
- Quick action buttons (Scan, Quick Log)
- Recent meals with inline delete
- AI meal plan section with adjustable calorie budget
GET /— DashboardGET /analyze— Scan meal pageGET /log— Quick log pageGET /history— Meal history pageGET /settings— Settings pagePOST /api/analyze— Upload image and run analysisPOST /api/meals— Save a mealGET /api/meals/{id}— Fetch meal detailPUT /api/meals/{id}— Update a saved meal (name, items, macros)DELETE /api/meals/{id}— Delete a mealGET /api/foods— Search nutrition catalogPOST /api/settings— Update goals and provider configPOST /api/llm/chat— Proxy chat requests to LM StudioPOST /api/ai-food-lookup— AI-powered nutrition estimation for any food (with optional web search)POST /api/ai-food-lookup/save— Save an AI-looked-up food to the nutrition databasePOST /custom-foods— Create a user-owned custom foodPOST /custom-foods/{id}/log— Log a custom food as a mealPOST /custom-foods/{id}/delete— Delete a custom food
GET /admin/db— Nutrition catalog managementGET /admin/users— User managementPOST /admin/nutrition-items— Create/update nutrition itemPOST /admin/nutrition-items/{id}/delete— Delete nutrition itemPOST /admin/label-import— Import from nutrition label image
Static rendered previews of all pages with sample data:
What the preview is:
- static rendered preview of the real templates with sample data
- useful for checking layout and mobile presentation
What the preview is not:
- not the live FastAPI app; forms, uploads, and API calls do not work
How to enable:
- Go to repo
Settings→Pages - Set
SourcetoGitHub Actions - Push to
mainor manually run theDeploy Template Previewworkflow
Files:
- Workflow:
.github/workflows/pages.yml - Renderer:
scripts/render_template_previews.py - Output:
site/
- Start LM Studio on your machine (default:
http://localhost:1234) - Load a vision-language model (e.g.,
qwen/qwen3-vl-8b) - In NutriSight Settings, choose
lmstudioas provider and configure the URL and model - Save settings, then scan a meal
ARCHITECTURE.md— Runtime flow, route structure, DB schema, code layoutSIGNON.md— Auth options and deployment guidanceTODO.md— Current backlogdocs/EXECUTION_LOG.md— Session-by-session handoff logdocs/ROADMAP.md— Implementation sequence
The local catalog stores 7,849 items from USDA Foundation, USDA SR Legacy, and Indian (IFCT) sources. Bootstrap from scratch:
.venv/bin/python scripts/bootstrap_nutrition_sources.py --download --extract --verify
.venv/bin/python scripts/import_local_catalog.py