priyaprabakaran01/IdScanner
0
1"""2FastAPI backend for the ID Card Scanner.3Deploy this as a Hugging Face Space with SDK = Docker (use the Dockerfile4alongside this file).5 6Endpoints:7 POST /records -> add a record {name, dept, regNo, year}8 GET /records -> list all records (JSON)9 GET /download -> download students.xlsx10 DELETE /records/{reg} -> remove a record by reg no11 12Storage: students.xlsx on local disk.13NOTE: Hugging Face Spaces storage is ephemeral by default — the file is14wiped on every Space restart/rebuild. For data that must survive restarts,15either:16 (a) enable "Persistent Storage" for the Space (paid, mounts a disk at17 a path you choose — point EXCEL_PATH there), or18 (b) swap the storage functions below for a Google Sheet / database.19"""20 21import os22from typing import List, Optional23 24from fastapi import FastAPI, HTTPException25from fastapi.middleware.cors import CORSMiddleware26from fastapi.responses import FileResponse27from pydantic import BaseModel28from openpyxl import Workbook, load_workbook29 30EXCEL_PATH = os.environ.get("EXCEL_PATH", "students.xlsx")31HEADERS = ["Name", "Department", "RegNo", "Year"]32 33app = FastAPI(title="ID Card Scanner Backend")34 35# Allow the static frontend (hosted on a different Space/domain) to call this API.36# Tighten allow_origins to your exact frontend URL once you know it.37app.add_middleware(38 CORSMiddleware,39 allow_origins=["*"],40 allow_methods=["*"],41 allow_headers=["*"],42)43 44 45class Record(BaseModel):46 name: str = ""47 dept: str = ""48 regNo: str49 year: str = ""50 51 52def _ensure_workbook():53 if not os.path.exists(EXCEL_PATH):54 wb = Workbook()55 ws = wb.active56 ws.title = "Students"57 ws.append(HEADERS)58 wb.save(EXCEL_PATH)59 60 61def _load_all() -> List[Record]:62 _ensure_workbook()63 wb = load_workbook(EXCEL_PATH)64 ws = wb.active65 out = []66 for row in ws.iter_rows(min_row=2, values_only=True):67 if not row or not row[2]:68 continue69 out.append(Record(name=row[0] or "", dept=row[1] or "", regNo=str(row[2]), year=str(row[3] or "")))70 return out71 72 73@app.get("/records")74def list_records():75 return _load_all()76 77 78@app.post("/records")79def add_record(record: Record):80 if not record.regNo.strip():81 raise HTTPException(400, "regNo is required")82 83 _ensure_workbook()84 wb = load_workbook(EXCEL_PATH)85 ws = wb.active86 87 existing = {str(row[0].value) for row in ws.iter_rows(min_row=2, min_col=3, max_col=3) if row[0].value}88 if record.regNo in existing:89 raise HTTPException(409, f"RegNo {record.regNo} already exists")90 91 ws.append([record.name, record.dept, record.regNo, record.year])92 wb.save(EXCEL_PATH)93 return {"status": "ok", "record": record}94 95 96@app.delete("/records/{reg_no}")97def delete_record(reg_no: str):98 _ensure_workbook()99 wb = load_workbook(EXCEL_PATH)100 ws = wb.active101 102 target_row = None103 for row in ws.iter_rows(min_row=2):104 if row[2].value and str(row[2].value) == reg_no:105 target_row = row[0].row106 break107 108 if target_row is None:109 raise HTTPException(404, f"RegNo {reg_no} not found")110 111 ws.delete_rows(target_row)112 wb.save(EXCEL_PATH)113 return {"status": "deleted", "regNo": reg_no}114 115 116@app.get("/download")117def download():118 _ensure_workbook()119 return FileResponse(120 EXCEL_PATH,121 media_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",122 filename="students.xlsx",123 )124 125 126@app.get("/")127def health():128 return {"status": "running"}129 