CoolFace
Apppublic

fallingbody/local-ai

sourceHugging Faceupdated 24d agoView on Hugging Face
0likes
face_ai.py201 linesDownload Raw Back to scripts
1from flask import Flask, request, jsonify2from flask_cors import CORS3import os4import tempfile5import shutil6from pathlib import Path7from uuid import uuid48 9import pymupdf as fitz  # PDF (using pymupdf instead of deprecated fitz)10from deepface import DeepFace11 12app = Flask(__name__)13CORS(app)14 15UPLOADS_DIR = Path("uploads")16UPLOADS_DIR.mkdir(exist_ok=True)17 18session_store = {}19resume_store = {}20 21# ========================22# SESSION23# ========================24def create_session():25    return {26        "reference_image": None,27        "verified_frames": 0,28        "total_frames": 0,29        "terminated": False30    }31 32def get_session(session_id):33    if session_id not in session_store:34        session_store[session_id] = create_session()35    return session_store[session_id]36 37# ========================38# EXTRACT IMAGE FROM PDF39# ========================40def extract_image_from_pdf(file_path, resume_id):41    doc = fitz.open(file_path)42 43    for page_index in range(len(doc)):44        page = doc[page_index]45        images = page.get_images(full=True)46 47        for img in images:48            xref = img[0]49            base = doc.extract_image(xref)50            image_bytes = base["image"]51 52            img_path = UPLOADS_DIR / f"{resume_id}.jpg"53            with open(img_path, "wb") as f:54                f.write(image_bytes)55 56            return str(img_path)57 58    return None59 60# ========================61# UPLOAD RESUME62# ========================63@app.route("/api/resumes/upload", methods=["POST"])64def upload_resume():65    file = request.files.get("file")66    name = request.form.get("name")67    email = request.form.get("email")68 69    if not file:70        return jsonify({"error": "No file"}), 40071 72    resume_id = str(uuid4())73    file_path = UPLOADS_DIR / f"{resume_id}.pdf"74    file.save(file_path)75 76    # Extract image77    image_path = extract_image_from_pdf(file_path, resume_id)78 79    if not image_path:80        return jsonify({81            "error": "Resume must contain a clear photo"82        }), 40083 84    resume_store[resume_id] = {85        "image_path": image_path86    }87 88    return jsonify({89        "message": "Resume uploaded",90        "resume_id": resume_id91    })92 93# ========================94# START SESSION95# ========================96@app.route("/start", methods=["POST"])97def start():98    data = request.json99    session_id = data.get("session_id")100    resume_id = data.get("resume_id")101 102    if resume_id not in resume_store:103        return jsonify({"error": "Invalid resume"}), 400104 105    session = create_session()106    session["reference_image"] = resume_store[resume_id]["image_path"]107 108    session_store[session_id] = session109 110    return jsonify({"message": "Session started"})111 112# ========================113# VERIFY FACE114# ========================115@app.route("/verify-face", methods=["POST"])116def verify_face():117    session_id = request.form.get("session_id")118    image = request.files.get("image")119 120    session = get_session(session_id)121 122    if session.get("terminated"):123        return jsonify({124            "terminated": True,125            "reason": "Already terminated"126        }), 403127 128    if not image:129        return jsonify({"error": "No image"}), 400130 131    with tempfile.NamedTemporaryFile(delete=False, suffix=".jpg") as temp:132        path = temp.name133        image.save(path)134 135    try:136        result = DeepFace.verify(137            img1_path=session["reference_image"],138            img2_path=path,139            enforce_detection=False140        )141 142        verified = result["verified"]143        distance = result["distance"]144 145        session["total_frames"] += 1146 147        if verified:148            session["verified_frames"] += 1149 150        # 🚨 CHEATING DETECTION151        if not verified:152            session["terminated"] = True153 154            return jsonify({155                "terminated": True,156                "reason": "CHEATING DETECTED",157                "verified": False158            }), 403159 160        return jsonify({161            "verified": True,162            "distance": distance163        })164 165    except Exception as e:166        return jsonify({"error": str(e)}), 500167 168    finally:169        os.remove(path)170 171# ========================172# END SESSION173# ========================174@app.route("/end", methods=["POST"])175def end():176    data = request.json177    session_id = data.get("session_id")178 179    session = get_session(session_id)180 181    total_frames = session.get("total_frames", 0)182    verified_frames = session.get("verified_frames", 0)183 184    verification_rate = (185        (verified_frames / total_frames) * 100186        if total_frames else 0187    )188 189    return jsonify({190        "verification_rate": round(verification_rate, 2),191        "status": "verified" if verification_rate > 60 else "suspicious",192        "terminated": session.get("terminated", False),193        "total_frames": total_frames,194        "verified_frames": verified_frames,195    })196 197# ========================198# RUN199# ========================200if __name__ == "__main__":201    app.run(port=5000, debug=True)