File size: 2,953 Bytes
d7c862a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
from fastapi import FastAPI, UploadFile, File, HTTPException, Form
import shutil
import os
import traceback
import uuid
import json

# import your function
from attendance_backend2 import (
    get_attendance_from_image,
    get_attendance_from_image_with_references,
)

app = FastAPI()


def _json_safe_faces(recognized_faces: list) -> list[dict]:
    """face_recognition returns numpy scalars and tuples — JSON encoding fails with 500 if not converted."""
    out: list[dict] = []
    for f in recognized_faces:
        loc = f.get("location")
        if loc is not None:
            loc = [int(x) for x in loc]
        conf = f.get("confidence")
        if conf is not None:
            conf = float(conf)
        out.append(
            {
                "name": str(f.get("name", "Unknown")),
                "confidence": conf,
                "location": loc,
            }
        )
    return out


@app.post("/attendance")
async def attendance(image: UploadFile = File(...)):
    # Stable temp name (avoid odd characters in original filename on Windows)
    suffix = os.path.splitext(image.filename or "")[1] or ".jpg"
    temp_path = f"temp_upload_{uuid.uuid4().hex}{suffix}"
    try:
        with open(temp_path, "wb") as buffer:
            shutil.copyfileobj(image.file, buffer)

        marked_ids, recognized_faces = get_attendance_from_image(temp_path, save_excel=True)

        return {
            "marked_ids": [str(x) for x in marked_ids],
            "recognized_faces": _json_safe_faces(recognized_faces),
        }
    except Exception as e:
        traceback.print_exc()
        raise HTTPException(status_code=500, detail=str(e)) from e
    finally:
        if os.path.exists(temp_path):
            try:
                os.remove(temp_path)
            except OSError:
                pass


@app.post("/attendance/section")
async def attendance_section(
    image: UploadFile = File(...),
    references_json: str = Form(...),
):
    suffix = os.path.splitext(image.filename or "")[1] or ".jpg"
    temp_path = f"temp_upload_{uuid.uuid4().hex}{suffix}"
    try:
        with open(temp_path, "wb") as buffer:
            shutil.copyfileobj(image.file, buffer)

        references = json.loads(references_json)
        if not isinstance(references, list):
            raise ValueError("references_json must be a JSON array")

        marked_ids, recognized_faces = get_attendance_from_image_with_references(
            temp_path,
            references,
            save_excel=False,
        )

        return {
            "marked_ids": [str(x) for x in marked_ids],
            "recognized_faces": _json_safe_faces(recognized_faces),
        }
    except Exception as e:
        traceback.print_exc()
        raise HTTPException(status_code=500, detail=str(e)) from e
    finally:
        if os.path.exists(temp_path):
            try:
                os.remove(temp_path)
            except OSError:
                pass