Spaces:
Runtime error
Runtime error
| """ | |
| app.py β Entry point: khα»i tαΊ‘o Flask, ΔΔng kΓ½ blueprints, xα» lΓ½ lα»i chuαΊ©n. | |
| CαΊ₯u trΓΊc module: | |
| config.py β BiαΊΏn mΓ΄i trΖ°α»ng | |
| utils/image.py β Tiα»n Γch xα» lΓ½ αΊ£nh | |
| storage/ | |
| mongo_storage β MongoDB: raw_images, face_crops, unknown_faces, recognition_payloads | |
| pg_storage β Supabase: persons, visits, face_embeddings, recognition_logs | |
| face_model/ | |
| analyzer β InsightFace singleton + RAM cache | |
| api/ | |
| system β GET /api/health, POST /api/database/reload | |
| recognize β POST /api/recognitions (+ legacy /api/recognize) | |
| faces β POST /api/faces, GET /api/face-crops/<id> | |
| persons β GET/PUT/DELETE /api/persons/<id> | |
| database β GET /api/faces, /api/db, DELETE /api/db/<fn>, GET /api/unknown-faces | |
| """ | |
| import logging | |
| import sys | |
| from flask import Flask, jsonify | |
| from flask_cors import CORS | |
| import config | |
| from face_model.analyzer import face_analyzer | |
| from storage.pg_storage import pg_storage | |
| # ββ Logging βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| logging.basicConfig( | |
| level=logging.INFO, | |
| format="%(asctime)s [%(levelname)s] %(name)s β %(message)s", | |
| ) | |
| logger = logging.getLogger("app") | |
| # ββ Flask Init ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| app = Flask(__name__) | |
| CORS(app, resources={r"/api/*": {"origins": "*"}}, supports_credentials=True) | |
| # ββ Register Blueprints βββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| from api.system import bp as system_bp | |
| from api.recognize import bp as recognize_bp | |
| from api.faces import bp as faces_bp | |
| from api.persons import bp as persons_bp | |
| from api.database import bp as database_bp | |
| app.register_blueprint(system_bp) | |
| app.register_blueprint(recognize_bp) | |
| app.register_blueprint(faces_bp) | |
| app.register_blueprint(persons_bp) | |
| app.register_blueprint(database_bp) | |
| # ββ Root Route ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| def index(): | |
| return jsonify({ | |
| "status": "success", | |
| "message": "FaceID AI Service is running successfully on HuggingFace Spaces!", | |
| "endpoints": { | |
| "health_check": "/api/health", | |
| "recognize": "/api/recognitions", | |
| "faces": "/api/faces" | |
| } | |
| }), 200 | |
| # ββ Global Error Handlers βββββββββββββββββββββββββββββββββββββββββββββββββ | |
| def not_found(e): | |
| return jsonify({"error": {"code": "NOT_FOUND", "message": str(e), "status": 404}}), 404 | |
| def method_not_allowed(e): | |
| return jsonify({"error": {"code": "METHOD_NOT_ALLOWED", "message": str(e), "status": 405}}), 405 | |
| def internal_error(e): | |
| return jsonify({"error": {"code": "INTERNAL_ERROR", "message": str(e), "status": 500}}), 500 | |
| # ββ Startup: Model + DB Cache βββββββββββββββββββββββββββββββββββββββββββββ | |
| def startup(): | |
| # 1. Khα»i tαΊ‘o InsightFace | |
| try: | |
| face_analyzer.initialize() | |
| except Exception as e: | |
| logger.critical(f"Failed to initialize InsightFace: {e}", exc_info=True) | |
| sys.exit(1) | |
| # 2. Load embeddings tα»« Supabase vΓ o RAM | |
| try: | |
| records = pg_storage.load_all_embeddings() | |
| face_analyzer.reload_cache(records) | |
| except Exception as e: | |
| logger.warning(f"[Startup] Supabase load failed: {e}. Falling back to local folder...") | |
| try: | |
| face_analyzer.reload_from_local_folder(config.DB_FOLDER) | |
| except Exception as fe: | |
| logger.warning(f"[Startup] Local fallback also failed: {fe}") | |
| logger.info( | |
| f"[Startup] Ready. Model={config.MODEL_NAME}, " | |
| f"Embeddings={face_analyzer.total}, Port={config.PORT}" | |
| ) | |
| # Khα»i chαΊ‘y startup khi import (cαΊ§n thiαΊΏt cho Gunicorn) | |
| startup() | |
| # ββ Main ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| if __name__ == "__main__": | |
| logger.info(f"Starting Flask RESTful API on {config.HOST}:{config.PORT} ...") | |
| app.run(host=config.HOST, port=config.PORT, debug=False) | |