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"} PROXY_URL = "http://95.179.252.111:8768/gemini" def settings() -> dict: 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 config def authorized() -> bool: expected = os.environ.get("RECIPE_API_TOKEN") authorization = request.headers.get("Authorization", "") return bool(expected and authorization == f"Bearer {expected}") @app.get("/health") def health(): return jsonify(status="ok") @app.post("/recipe") def recipe(): if not authorized(): return jsonify(error="unauthorized"), 401 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: config = settings() response = requests.post( os.environ.get("GEMINI_PROXY_URL", PROXY_URL), files={"image": (image.filename or "image", image_data, image.mimetype)}, data={"prompt": prompt, "generation_config": json.dumps(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("text"), usage=data.get("usage", {}), )