from fastapi import FastAPI, UploadFile, File, Form from fastapi.middleware.cors import CORSMiddleware from groq import Groq import os import io import json import base64 from PIL import Image from dotenv import load_dotenv load_dotenv() app = FastAPI() app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_methods=["*"], allow_headers=["*"], ) client = Groq(api_key=os.getenv("GROQ_API_KEY")) # SỬ DỤNG MODEL LLAMA 4 SCOUT NHƯ BẠN YÊU CẦU MODEL_NAME = "meta-llama/llama-4-scout-17b-16e-instruct" @app.post("/analyze") async def analyze(file: UploadFile = File(...), goal: str = Form("Giảm cân")): try: content = await file.read() image = Image.open(io.BytesIO(content)).convert("RGB") image.thumbnail((800, 800)) buffer = io.BytesIO() image.save(buffer, format="JPEG", quality=85) base64_image = base64.b64encode(buffer.getvalue()).decode("utf-8") # Gọi Groq API với Llama 4 Scout completion = client.chat.completions.create( model=MODEL_NAME, messages=[ { "role": "user", "content": [ { "type": "text", "text": f"Phân tích ảnh món ăn này cho mục tiêu: {goal}. Trả về JSON: " '{"food_items": [], "macros": {"calories": 0, "protein": 0, "carbs": 0, "fat": 0}, "advice": ""}' }, { "type": "image_url", "image_url": {"url": f"data:image/jpeg;base64,{base64_image}"} } ] } ], temperature=0.1, response_format={"type": "json_object"} ) return json.loads(completion.choices[0].message.content) except Exception as e: # Nếu model Scout không hỗ trợ ảnh, lỗi sẽ được báo ở đây return { "error": "Lỗi thực thi với Llama 4 Scout", "details": str(e), "note": "Nếu lỗi 'Image input not supported', bạn cần đổi sang model có hậu tố -vision." } if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=7860)