Download backend/main.py from ImgAuth/app: direct link, hf CLI and curl.
- Browser
- Download file 2.75 kB
-
https://huggingface.co/spaces/ImgAuth/app/resolve/main/backend/main.py
- Command line
-
hf download hf://spaces/ImgAuth/app/backend/main.py
-
curl -L -o main.py https://huggingface.co/spaces/ImgAuth/app/resolve/main/backend/main.py
2.75 kB
| from fastapi import FastAPI, File, UploadFile, HTTPException | |
| from fastapi.staticfiles import StaticFiles | |
| from fastapi.responses import FileResponse, JSONResponse | |
| from fastapi.middleware.cors import CORSMiddleware | |
| import uvicorn | |
| from datetime import datetime | |
| from pathlib import Path | |
| from backend.detectors.image_detector import analyze_image_models | |
| from backend.detectors.metadata_detector import analyze_metadata | |
| from backend.detectors.scoring_engine import calculate_final_score | |
| from backend.detectors.style_detector import analyze_visual_style | |
| from PIL import Image | |
| import io | |
| app = FastAPI(title="ImgAuth AI API") | |
| app.add_middleware(CORSMiddleware, allow_origins=["*"], allow_methods=["*"], allow_headers=["*"]) | |
| BASE_DIR = Path(__file__).parent | |
| FRONTEND = BASE_DIR.parent / "frontend" | |
| PUBLIC = BASE_DIR.parent / "public" | |
| app.mount("/static", StaticFiles(directory=str(FRONTEND / "static")), name="static") | |
| app.mount("/public", StaticFiles(directory=str(PUBLIC)), name="public") | |
| async def startup(): | |
| print("ImgAuth AI started -> http://localhost:5000") | |
| try: | |
| print("[ImgAuth] Preloading models on startup...") | |
| from backend.detectors.image_detector import load_models | |
| load_models() | |
| print("[ImgAuth] Models preloaded successfully.") | |
| except Exception as e: | |
| print(f"[ImgAuth] Warning: failed to preload models: {e}") | |
| async def root(): | |
| return FileResponse(str(FRONTEND / "index.html")) | |
| async def detect(file: UploadFile = File(...)): | |
| if not file.content_type.startswith("image/"): | |
| raise HTTPException(400, "Only image files are accepted.") | |
| contents = await file.read() | |
| if len(contents) > 10 * 1024 * 1024: | |
| raise HTTPException(400, "File too large. Max 10 MB.") | |
| fn = {} | |
| md = analyze_metadata(contents) | |
| ml = analyze_image_models(contents) | |
| try: | |
| img_full = Image.open(io.BytesIO(contents)).convert("RGB") | |
| st = analyze_visual_style(img_full) | |
| except Exception as e: | |
| st = {"ai_points": 0, "real_points": 0, "signals": [f"[ERROR] Style loading: {str(e)[:50]}"]} | |
| ml["style"] = st | |
| if "signals" in ml and "signals" in st: | |
| ml["signals"].extend(st["signals"]) | |
| res = calculate_final_score(fn, md, ml) | |
| return JSONResponse({ | |
| "filename": file.filename, | |
| "verdict": res["verdict"], | |
| "ai_score": res["ai_score"], | |
| "real_score": res["real_score"], | |
| "confidence": res["confidence"], | |
| "color": res["color"], | |
| "layers": {"filename": fn, "metadata": md, "models": ml}, | |
| "breakdown": res["breakdown"], | |
| "summary": res["summary"], | |
| "timestamp": datetime.now().isoformat() | |
| }) | |