title: NutriLoop AI
emoji: π±
colorFrom: blue
colorTo: green
sdk: docker
app_port: 7860
NutriLoop AI
Food demand forecasting backend using Facebook Prophet, KMeans clustering for cold-start restaurants, and NewsAPI-based demand adjustment.
Features
- Prophet Forecasting: Trained per restaurant+item combination with Indian public holidays
- Cold-Start Clustering: KMeans-based fallback for new restaurants without historical data
- Restaurant Metadata: Optional
restaurantstable stores location and cuisine data for deterministic fallback behavior - News Adjustment: Real-time demand multiplier from news headlines (festival, weather, events)
- Nightly Retraining: GitHub Actions cron job pulls latest Supabase data and retrains models
- Hugging Face Spaces: Containerized FastAPI app deploys to
*.hf.space
Quick Start (Local Development)
1. Install Dependencies
# Use Python 3.13 for this project
# Create or refresh the venv if needed, then install dependencies
uv sync
2. Configure Environment
cp .env.example .env
# Edit .env with your credentials:
# - SUPABASE_URL / SUPABASE_KEY from Supabase project settings
# - NEWSAPI_KEY from https://newsapi.org (free tier)
# - HF_TOKEN / HF_REPO_ID from Hugging Face
3. Seed Supabase with Kaggle Data
Download the Kaggle dataset from: https://www.kaggle.com/datasets/mer-sun/restaurant-sales
# Print the SQL schema to run in Supabase dashboard
python scripts/seed_supabase.py --print-sql
# Seed data from CSV
python scripts/seed_supabase.py /path/to/kaggle/sales.csv
4. Train Models
# Train Prophet models from Supabase data
python training/train_prophet.py
# Train KMeans clustering model
python training/train_clusters.py
# Upload models to Hugging Face Hub
python training/upload_models.py
5. Run the API
uvicorn app.main:app --reload --port 7860
API will be available at: http://localhost:7860
6. Test the API
python scripts/test_api.py
API Endpoints
GET /health
Health check with model count and version.
curl http://localhost:7860/health
POST /predict
Forecast demand for an existing restaurant with trained Prophet model.
curl -X POST http://localhost:7860/predict \
-H "Content-Type: application/json" \
-d '{
"restaurant_id": "rest_001",
"item_name": "biriyani",
"city": "Kochi",
"days": 7
}'
POST /cold-start
Forecast demand for a new restaurant using cluster-based averaging.
curl -X POST http://localhost:7860/cold-start \
-H "Content-Type: application/json" \
-d '{
"latitude": 9.9312,
"longitude": 76.2673,
"cuisine_type": "indian",
"avg_daily_quantity": 25.0,
"item_name": "puttu",
"days": 7
}'
Calling from Next.js
// In your Next.js kiosk dashboard page:
const HF_API = process.env.NEXT_PUBLIC_NUTRILOOP_AI_URL
// e.g. "https://your-username-nutriloop-ai.hf.space"
export async function getForecast(restaurantId: string, itemName: string, city: string) {
const res = await fetch(`${HF_API}/predict`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
restaurant_id: restaurantId,
item_name: itemName,
city: city,
days: 7
})
})
return res.json()
// Returns: { predictions: [{date, quantity, adjusted_quantity}], news_multiplier, source, ... }
}
Deployment to Hugging Face Spaces
1. Create a new Space
Go to https://huggingface.co/new-space and create a Docker-based Space named nutriloop-ai.
2. Push to HF
git init
git add .
git commit -m "NutriLoop AI initial commit"
git remote add origin https://huggingface.co/spaces/<your-username>/nutriloop-ai
git push origin main
3. Set Secrets in HF Space Settings
In your HF Space settings, add these secrets:
SUPABASE_URLSUPABASE_KEYNEWSAPI_KEYHF_TOKENHF_REPO_ID
4. Access your deployed API
Your API will be live at: https://<your-username>-nutriloop-ai.hf.space
Supabase Schema
Run this SQL in your Supabase SQL editor:
-- Enable PostGIS extension
CREATE EXTENSION IF NOT EXISTS postgis;
-- Table: sales_logs
CREATE TABLE sales_logs (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
restaurant_id text NOT NULL,
item_name text NOT NULL,
quantity integer NOT NULL,
sale_date date NOT NULL,
location geography(Point, 4326),
created_at timestamptz DEFAULT now()
);
CREATE INDEX idx_sales_logs_restaurant_id ON sales_logs(restaurant_id);
CREATE INDEX idx_sales_logs_sale_date ON sales_logs(sale_date);
CREATE INDEX idx_sales_logs_restaurant_item ON sales_logs(restaurant_id, item_name);
-- Table: restaurants
CREATE TABLE restaurants (
restaurant_id text PRIMARY KEY,
restaurant_name text,
latitude double precision,
longitude double precision,
cuisine_type text,
avg_daily_quantity double precision,
created_at timestamptz DEFAULT now()
);
-- Table: retrain_log
CREATE TABLE retrain_log (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
run_at timestamptz DEFAULT now(),
model_version text NOT NULL,
rows_used integer,
mae_score float,
status text CHECK (status IN ('success', 'failed')),
error_msg text
);
Nightly Retraining (GitHub Actions)
The .github/workflows/retrain.yml workflow runs automatically at 1:00 AM IST daily.
It executes scripts/retrain.py which:
- Pulls latest data from Supabase
- Retrains all Prophet models
- Retrains KMeans clusters
- Uploads updated models to Hugging Face Hub
You can also trigger manually from the GitHub Actions tab.
Environment Variables
| Variable | Description |
|---|---|
SUPABASE_URL |
Your Supabase project URL |
SUPABASE_KEY |
Supabase anon/public key |
NEWSAPI_KEY |
NewsAPI key (free tier at newsapi.org) |
HF_TOKEN |
Hugging Face access token |
HF_REPO_ID |
HF Space repo ID (e.g. username/nutriloop-ai) |
Project Structure
nutriloop-ai/
βββ app/
β βββ main.py # FastAPI app entry point
β βββ predict.py # Prophet model loading and inference
β βββ cold_start.py # KMeans cold-start forecasting
β βββ news_adjuster.py # NewsAPI-based demand multiplier
β βββ schemas.py # Pydantic request/response models
βββ training/
β βββ train_prophet.py # Full Prophet training pipeline
β βββ train_clusters.py# KMeans clustering training
β βββ load_kaggle_data.py # Kaggle CSV loader and cleaner
β βββ upload_models.py # Hugging Face model upload
βββ scripts/
β βββ retrain.py # Master retraining orchestrator
β βββ seed_supabase.py # First-run data seeding
β βββ test_api.py # End-to-end API tests
βββ models/ # Trained .pkl files (gitignored)
βββ data/ # Raw Kaggle CSV (gitignored)
βββ .github/workflows/
β βββ retrain.yml # GitHub Actions nightly cron
βββ Dockerfile
βββ requirements.txt
βββ README.md
Tech Stack
- Runtime: Python 3.11
- Web Framework: FastAPI + Uvicorn
- Forecasting: Facebook Prophet (with Indian holidays)
- Clustering: scikit-learn KMeans
- Database: Supabase (PostgreSQL + PostGIS)
- Model Registry: joblib + JSON
- Model Storage: Hugging Face Spaces
- CI/CD: GitHub Actions
- Hosting: Hugging Face Spaces (Docker)## Contributing
Contributions are welcome! To contribute:
- Fork the repository
- Create a new branch for your feature or bugfix
- Make your changes and add tests if applicable
- Submit a pull request with a clear description
Please follow the existing code style and add documentation where needed.
License
This project is licensed under the MIT License. See the LICENSE file for details.
Contact & Support
For questions, issues, or feature requests, please open an issue on GitHub or contact the maintainer:
- GitHub Issues: https://github.com/your-username/nutriloop-ai/issues
- Email: your.email@example.com