Spaces:
Configuration error
Configuration error
| import os | |
| import io | |
| import json | |
| import requests | |
| from flask import Flask, request, jsonify | |
| from flask_cors import CORS | |
| # Optional: but good for local debugging if you run this file directly | |
| try: | |
| from dotenv import load_dotenv | |
| load_dotenv() | |
| except ImportError: | |
| pass | |
| app = Flask(__name__) | |
| CORS(app) | |
| # ββ Configuration (with Defaults to prevent crashes) ββββββββββββββββ | |
| TWILIO_ACCOUNT_SID = os.getenv("TWILIO_ACCOUNT_SID", "") | |
| TWILIO_AUTH_TOKEN = os.getenv("TWILIO_AUTH_TOKEN", "") | |
| TWILIO_FROM_NUMBER = os.getenv("TWILIO_FROM_NUMBER", "+17125825991") | |
| YOUR_PHONE_NUMBER = os.getenv("YOUR_PHONE_NUMBER", "+919047432845") | |
| AI_CONFIDENCE_THRESHOLD = float(os.getenv("AI_CONFIDENCE_THRESHOLD", 0.5)) | |
| # HuggingFace Inference API Config | |
| HF_API_URL = "https://api-inference.huggingface.co/models/umm-maybe/AI-image-detector" | |
| HF_API_TOKEN = os.getenv("HF_API_TOKEN", "") | |
| # ββ Routes ββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| def home(): | |
| return "VisionAI Backend is Live. Use /status or /analyze." | |
| def status(): | |
| return jsonify({ | |
| "status": "online", | |
| "deployment": "vercel", | |
| "alerts_configured": bool(TWILIO_ACCOUNT_SID and TWILIO_AUTH_TOKEN), | |
| "target_phone": YOUR_PHONE_NUMBER, | |
| "threshold": AI_CONFIDENCE_THRESHOLD * 100 | |
| }) | |
| def analyze(): | |
| if "image" not in request.files: | |
| return jsonify({"error": "No image provided"}), 400 | |
| file = request.files["image"] | |
| img_data = file.read() | |
| # Call HuggingFace Inference API | |
| headers = {} | |
| if HF_API_TOKEN: | |
| headers["Authorization"] = f"Bearer {HF_API_TOKEN}" | |
| try: | |
| response = requests.post(HF_API_URL, headers=headers, data=img_data) | |
| results = response.json() | |
| # Handle API loading state (model taking time to boot) | |
| if isinstance(results, dict) and "estimated_time" in results: | |
| return jsonify({ | |
| "error": "Model is warming up on HuggingFace. Please try again in 20 seconds.", | |
| "wait_time": results["estimated_time"] | |
| }), 503 | |
| if isinstance(results, dict) and "error" in results: | |
| return jsonify({"error": results["error"]}), 502 | |
| # Parse results | |
| scores = {r["label"].lower(): r["score"] for r in results} | |
| art_score = scores.get("artificial", 0.0) | |
| real_score = scores.get("real", 1.0 - art_score) | |
| is_ai = art_score > AI_CONFIDENCE_THRESHOLD | |
| except Exception as e: | |
| return jsonify({"error": f"Analysis failed: {str(e)}"}), 502 | |
| # ββ Twilio Alert ββββββββββββββββββββββββββββββββββββββββ | |
| call_placed = False | |
| call_sid = None | |
| call_error = None | |
| if is_ai and TWILIO_ACCOUNT_SID and TWILIO_AUTH_TOKEN: | |
| try: | |
| from twilio.rest import Client | |
| client = Client(TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN) | |
| call = client.calls.create( | |
| twiml=f"""<Response> | |
| <Say voice="alice"> | |
| Alert! An AI generated image has been detected. | |
| Confidence is {round(art_score * 100)} percent. | |
| </Say> | |
| </Response>""", | |
| to=YOUR_PHONE_NUMBER, | |
| from_=TWILIO_FROM_NUMBER, | |
| ) | |
| call_placed = True | |
| call_sid = call.sid | |
| except Exception as e: | |
| call_error = str(e) | |
| return jsonify({ | |
| "filename": file.filename, | |
| "is_ai": is_ai, | |
| "artificial_score": round(art_score * 100, 1), | |
| "real_score": round(real_score * 100, 1), | |
| "all_scores": [{"label": r["label"], "score": round(r["score"] * 100, 1)} for r in results], | |
| "threshold": AI_CONFIDENCE_THRESHOLD * 100, | |
| "call_placed": call_placed, | |
| "call_sid": call_sid, | |
| "call_error": call_error | |
| }) | |
| # The 'app' object is automatically used by Vercel | |