Spaces:
Runtime error
Runtime error
| from fastapi import FastAPI, File, UploadFile, Request | |
| from fastapi.responses import HTMLResponse, FileResponse, JSONResponse | |
| from fastapi.staticfiles import StaticFiles | |
| from fastapi.middleware.cors import CORSMiddleware | |
| import os, json, base64, re | |
| from dotenv import load_dotenv | |
| import requests | |
| os.environ["HF_HOME"] = "./cache" | |
| os.makedirs("./cache", exist_ok=True) | |
| os.makedirs("images", exist_ok=True) | |
| import torch | |
| from diffusers import StableDiffusionPipeline | |
| from PIL import Image | |
| load_dotenv() | |
| api_key = os.getenv("GOOGLE_API") | |
| app = FastAPI() | |
| app.add_middleware( | |
| CORSMiddleware, | |
| allow_origins=["*"], | |
| allow_methods=["*"], | |
| allow_headers=["*"], | |
| ) | |
| app.mount("/images", StaticFiles(directory="images"), name="images") | |
| app.mount("/templates", StaticFiles(directory="templates"), name="templates") | |
| os.makedirs("images", exist_ok=True) | |
| device = "cuda" if torch.cuda.is_available() else "cpu" | |
| pipe = StableDiffusionPipeline.from_pretrained("runwayml/stable-diffusion-v1-5", torch_dtype=torch.float16 if device == "cuda" else torch.float32) | |
| pipe.to(device) | |
| def clean_filename(text): | |
| return re.sub(r'[^\w\-_\. ]', '_', text.strip().lower().replace(" ", "_")) | |
| def generate_image(food_name): | |
| prompt = f"Professional food photography of {food_name}, top-down view, realistic lighting" | |
| image = pipe(prompt).images[0] | |
| file_path = f"images/{clean_filename(food_name)}.png" | |
| image.save(file_path) | |
| return f"/{file_path}" | |
| def extract_menu_from_image(image_bytes): | |
| base64_image = base64.b64encode(image_bytes).decode('utf-8') | |
| url = f"https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key={api_key}" | |
| prompt = """ | |
| Extract the menu items from this image and return ONLY a JSON array like: | |
| [ | |
| { | |
| "food": "Dish Name", | |
| "description": "Short description or empty string", | |
| "price": 10, | |
| "category": "Category" | |
| } | |
| ] | |
| """ | |
| payload = { | |
| "contents": [{"parts": [{"text": prompt}, {"inline_data": {"mime_type": "image/jpeg", "data": base64_image}}]}], | |
| "generationConfig": {"responseMimeType": "application/json"} | |
| } | |
| headers = {'Content-Type': 'application/json'} | |
| try: | |
| res = requests.post(url, headers=headers, json=payload) | |
| res.raise_for_status() | |
| text = res.json()['candidates'][0]['content']['parts'][0]['text'] | |
| return json.loads(text) | |
| except Exception as e: | |
| print("Error extracting:", e) | |
| return [] | |
| async def serve_home(): | |
| return FileResponse("templates/index.html") | |
| async def upload_json(menu_image: UploadFile = File(...)): | |
| image_bytes = await menu_image.read() | |
| menu_items = extract_menu_from_image(image_bytes) | |
| for item in menu_items: | |
| img_path = generate_image(item["food"]) | |
| item["img_path"] = img_path | |
| return JSONResponse(content=menu_items) | |