NutriLoop / README.md
AB1N05's picture
Fix README frontmatter for Hugging Face Space
95e2503
|
Raw
History Blame Contribute Delete
8.49 kB
---
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 `restaurants` table 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
```bash
# Use Python 3.13 for this project
# Create or refresh the venv if needed, then install dependencies
uv sync
```
### 2. Configure Environment
```bash
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
```bash
# 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
```bash
# 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
```bash
uvicorn app.main:app --reload --port 7860
```
API will be available at: http://localhost:7860
### 6. Test the API
```bash
python scripts/test_api.py
```
## API Endpoints
### GET /health
Health check with model count and version.
```bash
curl http://localhost:7860/health
```
### POST /predict
Forecast demand for an existing restaurant with trained Prophet model.
```bash
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.
```bash
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
```typescript
// 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
```bash
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_URL`
- `SUPABASE_KEY`
- `NEWSAPI_KEY`
- `HF_TOKEN`
- `HF_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:
```sql
-- 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:
1. Pulls latest data from Supabase
2. Retrains all Prophet models
3. Retrains KMeans clusters
4. 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:
1. Fork the repository
2. Create a new branch for your feature or bugfix
3. Make your changes and add tests if applicable
4. 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](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
## Acknowledgements
- [Facebook Prophet](https://facebook.github.io/prophet/)
- [scikit-learn](https://scikit-learn.org/)
- [Supabase](https://supabase.com/)
- [Hugging Face Spaces](https://huggingface.co/spaces)
- [NewsAPI](https://newsapi.org/)