Spaces:
Sleeping
Sleeping
| from fastapi import FastAPI, HTTPException, Request | |
| from pydantic import BaseModel | |
| from typing import Dict | |
| from datetime import datetime | |
| import uuid | |
| import model # your existing model.py | |
| import joblib | |
| import pandas as pd | |
| import tensorflow as tf # Import TensorFlow here | |
| import asyncio | |
| app = FastAPI() | |
| # Load or train model at startup | |
| ml_model = model.load_or_train_model() | |
| SCALER_PATH = "/tmp/scaler.pkl" | |
| # ------------------------- | |
| # Request & Response Schemas | |
| # ------------------------- | |
| class FamilyInput(BaseModel): | |
| adult_male: int | |
| adult_female: int | |
| child: int | |
| class UserInput(BaseModel): | |
| user_id: str | |
| region: str | |
| season: str | |
| event: str | |
| family: FamilyInput | |
| stock: Dict[str, float] # product_name: quantity | |
| class RetrainRequest(BaseModel): | |
| user_id: str | |
| # ------------------------- | |
| # API Routes | |
| # ------------------------- | |
| # Define request body schema | |
| class Item(BaseModel): | |
| name: str | |
| quantity: int | |
| def read_root(): | |
| return {"message": "✅ GrocyGenie API is running."} | |
| def test_post(item: Item): | |
| return {"message": f"Received item '{item.name}' with quantity {item.quantity}"} | |
| def predict(input_data: UserInput): | |
| try: | |
| user_dict = input_data.dict() | |
| user_id = user_dict["user_id"] | |
| predictions = model.predict_user_input(user_dict) | |
| model.store_predictions(user_id, predictions, user_dict) | |
| feedback = pd.DataFrame([{ | |
| 'date': datetime.today().strftime('%Y-%m-%d'), | |
| 'product': k, | |
| 'region': user_dict['region'], | |
| 'season': user_dict['season'], | |
| 'event': user_dict['event'], | |
| 'adult_male': user_dict['family']['adult_male'], | |
| 'adult_female': user_dict['family']['adult_female'], | |
| 'child': user_dict['family']['child'], | |
| 'consumption': v['predicted_consumption'], | |
| 'finish_error': v['predicted_finish_error'], | |
| 'finish_days': v['predicted_finish_days'], | |
| 'stock_quantity': user_dict['stock'][k] # <--- Added stock quantity here | |
| } for k, v in predictions.items()]) | |
| model.insert_feedback(user_id, feedback) | |
| return { | |
| "user_id": user_id, | |
| "predictions": predictions | |
| } | |
| except Exception as e: | |
| raise HTTPException(status_code=500, detail=str(e)) | |
| def retrain_model(request: RetrainRequest): | |
| success = model.retrain_model_with_feedback(request.user_id) | |
| if success: | |
| # Reload model and scaler globally for future predictions | |
| model.ml_model = tf.keras.models.load_model(model.MODEL_PATH) | |
| model.scaler = joblib.load(SCALER_PATH) | |
| return {"message": f"Model retrained using feedback for user {request.user_id}."} | |
| else: | |
| raise HTTPException(status_code=404, detail="No feedback found for retraining.") | |
| async def train_model_from_api(): | |
| try: | |
| # Call your existing training function | |
| model.ml_model = model.load_or_train_model() | |
| # Reload the scaler as well | |
| model.scaler = joblib.load(SCALER_PATH) | |
| return {"message": "✅ Model retrained from scratch using latest data."} | |
| except Exception as e: | |
| raise HTTPException(status_code=500, detail=str(e)) | |