Spaces:
Sleeping
Sleeping
| title: KYC POC Backend | |
| emoji: π | |
| colorFrom: blue | |
| colorTo: purple | |
| sdk: docker | |
| app_port: 7860 | |
| pinned: false | |
| license: mit | |
| # KYC POC API | |
| A proof-of-concept API for KYC (Know Your Customer) verification using: | |
| - **AuraFace** for face recognition and matching | |
| - **Silent-Face-Anti-Spoofing** for liveness detection | |
| ## Features | |
| - Face matching between KTP (ID card) and selfie | |
| - Liveness detection to prevent spoofing attacks | |
| - Face quality analysis (blur, brightness, pose) | |
| - Age and gender estimation | |
| - Automatic face extraction from KTP images | |
| - Multiple faces rejection | |
| ## Requirements | |
| - Python 3.9+ | |
| - Git (for cloning Silent-Face-Anti-Spoofing) | |
| ## Installation | |
| ### 1. Create Virtual Environment | |
| ```bash | |
| # Windows | |
| python -m venv venv | |
| venv\Scripts\activate | |
| # Linux/Mac | |
| python -m venv venv | |
| source venv/bin/activate | |
| ``` | |
| ### 2. Install Dependencies | |
| ```bash | |
| pip install -r requirements.txt | |
| ``` | |
| ### 3. Download ML Models | |
| Run the setup script to download the required models: | |
| ```bash | |
| python setup_models.py | |
| ``` | |
| This will: | |
| - Download AuraFace model from HuggingFace | |
| - Clone Silent-Face-Anti-Spoofing repository | |
| - Copy model files to the correct locations | |
| ### 4. Run the Application | |
| ```bash | |
| uvicorn app.main:app --reload --host 0.0.0.0 --port 8000 | |
| ``` | |
| The API will be available at: http://localhost:8000 | |
| ## API Documentation | |
| - **Swagger UI**: http://localhost:8000/docs | |
| - **ReDoc**: http://localhost:8000/redoc | |
| ## API Endpoints | |
| ### Health Check | |
| ``` | |
| GET /health | |
| ``` | |
| ### File Upload Endpoints | |
| These endpoints accept `multipart/form-data`: | |
| | Endpoint | Method | Description | | |
| |----------|--------|-------------| | |
| | `/api/v1/kyc/verify` | POST | Full KYC verification | | |
| | `/api/v1/kyc/face-match` | POST | Face matching only | | |
| | `/api/v1/kyc/liveness` | POST | Liveness detection only | | |
| | `/api/v1/kyc/quality` | POST | Face quality check only | | |
| ### Base64 Endpoints | |
| These endpoints accept `application/json` with base64 encoded images: | |
| | Endpoint | Method | Description | | |
| |----------|--------|-------------| | |
| | `/api/v1/kyc/base64/verify` | POST | Full KYC verification | | |
| | `/api/v1/kyc/base64/face-match` | POST | Face matching only | | |
| | `/api/v1/kyc/base64/liveness` | POST | Liveness detection only | | |
| | `/api/v1/kyc/base64/quality` | POST | Face quality check only | | |
| ## Usage Examples | |
| ### Using curl (File Upload) | |
| **Full KYC Verification:** | |
| ```bash | |
| curl -X POST "http://localhost:8000/api/v1/kyc/verify" \ | |
| -F "ktp_image=@/path/to/ktp.jpg" \ | |
| -F "selfie_image=@/path/to/selfie.jpg" \ | |
| -F "threshold=0.5" | |
| ``` | |
| **Face Match Only:** | |
| ```bash | |
| curl -X POST "http://localhost:8000/api/v1/kyc/face-match" \ | |
| -F "ktp_image=@/path/to/ktp.jpg" \ | |
| -F "selfie_image=@/path/to/selfie.jpg" | |
| ``` | |
| **Liveness Check:** | |
| ```bash | |
| curl -X POST "http://localhost:8000/api/v1/kyc/liveness" \ | |
| -F "image=@/path/to/selfie.jpg" | |
| ``` | |
| ### Using Insomnia/Postman (Base64) | |
| **Full KYC Verification:** | |
| ```http | |
| POST /api/v1/kyc/base64/verify | |
| Content-Type: application/json | |
| { | |
| "ktp_image": "base64_encoded_ktp_image_here...", | |
| "selfie_image": "base64_encoded_selfie_image_here...", | |
| "threshold": 0.5 | |
| } | |
| ``` | |
| **Face Match Only:** | |
| ```http | |
| POST /api/v1/kyc/base64/face-match | |
| Content-Type: application/json | |
| { | |
| "image1": "base64_encoded_image1_here...", | |
| "image2": "base64_encoded_image2_here...", | |
| "threshold": 0.5 | |
| } | |
| ``` | |
| **Liveness Check:** | |
| ```http | |
| POST /api/v1/kyc/base64/liveness | |
| Content-Type: application/json | |
| { | |
| "image": "base64_encoded_image_here..." | |
| } | |
| ``` | |
| **Quality Check:** | |
| ```http | |
| POST /api/v1/kyc/base64/quality | |
| Content-Type: application/json | |
| { | |
| "image": "base64_encoded_image_here..." | |
| } | |
| ``` | |
| ## Response Examples | |
| ### Successful Verification | |
| ```json | |
| { | |
| "success": true, | |
| "face_match": { | |
| "is_match": true, | |
| "similarity_score": 0.87, | |
| "threshold": 0.5 | |
| }, | |
| "liveness": { | |
| "is_real": true, | |
| "confidence": 0.95, | |
| "label": "Real Face", | |
| "prediction_class": 1, | |
| "models_used": 2 | |
| }, | |
| "quality": { | |
| "ktp": { | |
| "blur_score": 125.5, | |
| "is_blurry": false, | |
| "brightness": 0.65, | |
| "is_too_dark": false, | |
| "is_too_bright": false, | |
| "is_good_quality": true | |
| }, | |
| "selfie": { | |
| "blur_score": 200.3, | |
| "is_blurry": false, | |
| "brightness": 0.58, | |
| "is_too_dark": false, | |
| "is_too_bright": false, | |
| "pose": { | |
| "yaw": 5.2, | |
| "pitch": -3.1, | |
| "roll": 1.5, | |
| "is_frontal": true | |
| }, | |
| "is_good_quality": true | |
| } | |
| }, | |
| "demographics": { | |
| "ktp": { "age": 28, "gender": "Male" }, | |
| "selfie": { "age": 29, "gender": "Male" } | |
| }, | |
| "face_boxes": { | |
| "ktp": { "x": 120, "y": 80, "width": 150, "height": 180 }, | |
| "selfie": { "x": 200, "y": 100, "width": 250, "height": 300 } | |
| }, | |
| "message": "KYC verification successful" | |
| } | |
| ``` | |
| ### Error Response | |
| ```json | |
| { | |
| "error_code": "FACE_NOT_DETECTED", | |
| "message": "No face detected in image" | |
| } | |
| ``` | |
| ## Error Codes | |
| | Code | HTTP | Description | | |
| |------|------|-------------| | |
| | `FACE_NOT_DETECTED` | 400 | No face found in uploaded image | | |
| | `MULTIPLE_FACES_DETECTED` | 400 | Multiple faces detected - rejected | | |
| | `LIVENESS_FAILED` | 400 | Spoofing attempt detected | | |
| | `IMAGE_INVALID` | 400 | Invalid or corrupt image file | | |
| | `IMAGE_TOO_LARGE` | 413 | Image exceeds size limit | | |
| | `UNSUPPORTED_FORMAT` | 415 | Image format not JPEG/PNG | | |
| | `MODEL_NOT_LOADED` | 503 | ML models not initialized | | |
| ## Configuration | |
| Configuration can be set via environment variables or `.env` file: | |
| | Variable | Default | Description | | |
| |----------|---------|-------------| | |
| | `DEBUG` | `true` | Enable debug mode | | |
| | `FACE_MATCH_THRESHOLD` | `0.5` | Face similarity threshold | | |
| | `LIVENESS_THRESHOLD` | `0.5` | Liveness confidence threshold | | |
| | `BLUR_THRESHOLD` | `100.0` | Blur detection threshold | | |
| | `BRIGHTNESS_MIN` | `0.2` | Minimum brightness | | |
| | `BRIGHTNESS_MAX` | `0.8` | Maximum brightness | | |
| | `USE_GPU` | `false` | Enable GPU acceleration | | |
| | `MAX_IMAGE_SIZE_MB` | `10.0` | Maximum upload size | | |
| ## Project Structure | |
| ``` | |
| sentinel/ | |
| βββ app/ | |
| β βββ __init__.py | |
| β βββ main.py # FastAPI application entry point | |
| β βββ config.py # Configuration settings | |
| β βββ api/ | |
| β β βββ __init__.py | |
| β β βββ dependencies.py # Shared dependencies | |
| β β βββ routes/ | |
| β β βββ __init__.py | |
| β β βββ health.py # Health check endpoint | |
| β β βββ kyc.py # File upload endpoints | |
| β β βββ kyc_base64.py # Base64 endpoints | |
| β βββ services/ | |
| β β βββ __init__.py | |
| β β βββ face_recognition.py # AuraFace service | |
| β β βββ face_quality.py # Quality analysis service | |
| β β βββ liveness_detection.py # Anti-spoofing service | |
| β βββ models/ | |
| β β βββ __init__.py | |
| β β βββ schemas.py # Pydantic models | |
| β βββ utils/ | |
| β βββ __init__.py | |
| β βββ image_utils.py # Image processing | |
| β βββ ktp_extractor.py # KTP face extraction | |
| βββ models/ # ML model files | |
| β βββ auraface/ # AuraFace model | |
| β βββ anti_spoof/ # Anti-spoofing models | |
| βββ Silent-Face-Anti-Spoofing/ # Cloned repository | |
| βββ requirements.txt | |
| βββ setup_models.py # Model download script | |
| βββ README.md | |
| ``` | |
| ## Notes | |
| - AuraFace produces 512-dimensional face embeddings | |
| - Similarity threshold of 0.5 is balanced; increase for higher security | |
| - Silent-Face-Anti-Spoofing uses 2 models for fusion (MiniFASNetV1SE + MiniFASNetV2) | |
| - First request may be slow due to model warm-up | |
| - CPU mode is used by default; set `USE_GPU=true` for GPU acceleration | |
| ## License | |
| This is a proof-of-concept for educational purposes. | |