import base64 import json import os import requests from flask import Flask, jsonify, request app = Flask(__name__) MAX_IMAGE_BYTES = 10 * 1024 * 1024 ALLOWED_TYPES = {"image/jpeg", "image/png", "image/webp"} GEMINI_URL = "https://generativelanguage.googleapis.com/v1beta/models" def settings() -> tuple[str, dict]: key = os.environ.get("GEMINI_API_KEY") if not key: raise RuntimeError("GEMINI_API_KEY is not configured") try: config = json.loads(os.environ.get("GEMINI_GENERATION_CONFIG", "{}")) except json.JSONDecodeError as exc: raise RuntimeError("GEMINI_GENERATION_CONFIG is invalid") from exc if not isinstance(config, dict): raise RuntimeError("GEMINI_GENERATION_CONFIG must be an object") return key, config @app.get("/health") def health(): return jsonify(status="ok") @app.post("/recipe") def recipe(): image = request.files.get("image") prompt = request.form.get("prompt") if image is None or not prompt: return jsonify(error="image and prompt are required"), 400 if image.mimetype not in ALLOWED_TYPES: return jsonify(error="unsupported image type"), 415 image_data = image.read(MAX_IMAGE_BYTES + 1) if len(image_data) > MAX_IMAGE_BYTES: return jsonify(error="image is too large"), 413 try: key, config = settings() response = requests.post( f"{GEMINI_URL}/{os.environ.get('GEMINI_MODEL', 'gemini-3.6-flash')}:generateContent", params={"key": key}, json={ "contents": [{"parts": [{"text": prompt}, {"inline_data": { "mime_type": image.mimetype, "data": base64.b64encode(image_data).decode("ascii"), }}]}], "generationConfig": config, }, timeout=180, ) except (requests.RequestException, RuntimeError) as exc: return jsonify(error=str(exc) if isinstance(exc, RuntimeError) else "Gemini unavailable"), 503 if response.status_code != 200: try: detail = response.json().get("error", {}).get("message", "Gemini request failed") except ValueError: detail = "Gemini request failed" return jsonify(error=detail), 502 data = response.json() return jsonify( text=data.get("candidates", [{}])[0].get("content", {}).get("parts", [{}])[0].get("text"), usage=data.get("usageMetadata", {}), )