Microservice Python FastAPI + OpenCV YuNet/SFace untuk kebutuhan face verification 1:1 pada aplikasi absensi.
Service ini dibuat sebagai pengganti API face compare eksternal seperti Face++ atau KBY-AI, dengan tujuan:
- Gratis dan open-source.
- Bisa jalan CPU-only tanpa GPU.
- Mudah dipanggil dari backend lain, misalnya Go Gin.
- Cocok untuk alur absensi 1:1: foto referensi karyawan dibandingkan dengan foto absensi terbaru.
- Endpoint
POST /verify,POST /extract, danPOST /verify-embeddingdilindungi auth code melalui headerX-Auth-Code.
Aplikasi Absensi / Backend Go Gin
|
| POST multipart/form-data
| Header: X-Auth-Code
v
Face Compare Service
|
| OpenCV YuNet: deteksi wajah
| OpenCV SFace: ekstraksi dan compare wajah
v
Response JSON
Flow absensi:
1. User upload foto absensi
2. Backend mengambil foto referensi karyawan dari server/database
3. Backend bisa ekstrak embedding dari foto referensi lewat endpoint /extract
4. Backend bisa verifikasi embedding referensi vs foto absensi lewat endpoint /verify-embedding
5. Alternatif tetap bisa mengirim 2 foto langsung ke endpoint /verify
6. Backend mengirim header X-Auth-Code
7. Service memvalidasi auth code
8. Service mengembalikan similarity dan status match
9. Backend menentukan absensi diterima atau ditolak
face-compare-service/
├── app/
│ ├── __init__.py
│ ├── config.py
│ ├── face_service.py
│ └── main.py
├── models/
│ ├── face_detection_yunet_2023mar.onnx
│ └── face_recognition_sface_2021dec.onnx
├── .env
├── .dockerignore
├── Dockerfile
├── docker-compose.yml
├── requirements.txt
└── README.md
Minimal:
CPU : 2 core
RAM : 2 GB atau lebih
Storage : 1 GB kosong
OS : Linux, contoh LMDE 7 / Ubuntu 20.04+
Docker : Docker Engine + Docker Compose Plugin
GPU : Tidak wajib
Panduan kapasitas berdasarkan skala pegawai:
| Skala Pegawai | UVICORN_WORKERS |
RAM (container) | CPU (container) | Core server |
|---|---|---|---|---|
| < 5.000 | 1 |
512 MB | 1.5 core | 2 core |
| 5.000–10.000 | 2 |
700 MB | 2.5 core | 4 core |
| 10.000–20.000 | 3 |
900 MB | 3.5 core | 4–6 core |
| 20.000+ | 5 |
1.4 GB | 5.5 core | 6–8 core |
Tiap uvicorn worker memuat model ke memory (~180 MB per worker). Alokasikan RAM container minimal
workers × 200 MB + overhead.
sudo apt update
sudo apt install -y ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
sudo tee /etc/apt/sources.list.d/docker.sources <<DOCKER_EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: focal
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
DOCKER_EOF
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo systemctl enable --now docker
sudo docker run hello-worldCek codename Debian:
cat /etc/os-releaseInstall Docker:
sudo apt update
sudo apt install -y ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
sudo tee /etc/apt/sources.list.d/docker.sources <<DOCKER_EOF
Types: deb
URIs: https://download.docker.com/linux/debian
Suites: trixie
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
DOCKER_EOF
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo systemctl enable --now docker
sudo docker run hello-worldJika LMDE 7 yang digunakan tidak memakai codename trixie, ganti bagian Suites: trixie sesuai hasil:
. /etc/os-release && echo "$VERSION_CODENAME"Dari root project:
cd ~/face-compare-service
mkdir -p modelsDownload model:
wget -O models/face_detection_yunet_2023mar.onnx \
https://github.com/opencv/opencv_zoo/raw/main/models/face_detection_yunet/face_detection_yunet_2023mar.onnx
wget -O models/face_recognition_sface_2021dec.onnx \
https://github.com/opencv/opencv_zoo/raw/main/models/face_recognition_sface/face_recognition_sface_2021dec.onnxCek file:
ls -lh modelsPastikan file model tidak berukuran sangat kecil. Jika hanya beberapa KB, kemungkinan yang terdownload adalah halaman HTML error, bukan file ONNX.
File konfigurasi ada di .env.
Contoh isi:
APP_NAME=face-compare-service
FACE_DETECT_MODEL=/app/models/face_detection_yunet_2023mar.onnx
FACE_RECOGNITION_MODEL=/app/models/face_recognition_sface_2021dec.onnx
FACE_THRESHOLD=0.363
DETECT_SCORE_THRESHOLD=0.90
DETECT_NMS_THRESHOLD=0.30
DETECT_TOP_K=5000
MAX_UPLOAD_MB=8
ALLOW_MULTIPLE_FACES=false
# Jumlah thread OpenCV per worker.
# Biarkan 1 jika multi-worker agar tidak berebut core.
OPENCV_THREADS=1
# Jumlah proses uvicorn (setiap proses load model ~180MB RAM).
# Rekomendasi: (core yang dialokasikan) - 1
# Contoh: 4 core → UVICORN_WORKERS=3
UVICORN_WORKERS=1
FACE_API_AUTH_CODE=ganti_dengan_kode_rahasia_panjangPenjelasan variabel:
| Variable | Default | Fungsi |
|---|---|---|
APP_NAME |
face-compare-service |
Nama service |
FACE_DETECT_MODEL |
path di container | Path model YuNet di dalam container |
FACE_RECOGNITION_MODEL |
path di container | Path model SFace di dalam container |
FACE_THRESHOLD |
0.363 |
Ambang batas similarity untuk menentukan match |
DETECT_SCORE_THRESHOLD |
0.90 |
Minimal confidence deteksi wajah |
DETECT_NMS_THRESHOLD |
0.30 |
Nilai NMS untuk deteksi wajah |
DETECT_TOP_K |
5000 |
Jumlah kandidat wajah maksimal |
MAX_UPLOAD_MB |
8 |
Maksimal ukuran upload per file |
ALLOW_MULTIPLE_FACES |
false |
Jika false, foto dengan lebih dari 1 wajah ditolak |
OPENCV_THREADS |
1 |
Thread OpenCV per worker. Biarkan 1 jika multi-worker. |
UVICORN_WORKERS |
1 |
Jumlah proses uvicorn. Tiap worker ~180MB RAM. |
FACE_API_AUTH_CODE |
"" |
Auth code untuk semua endpoint. Wajib diisi di produksi. |
Konfigurasi resource di docker-compose.yml juga dapat dikontrol via .env:
| Variable | Default | Fungsi |
|---|---|---|
FACE_MEM_LIMIT |
512m |
Batas memory container. Sesuaikan: UVICORN_WORKERS × 200MB + overhead. |
FACE_CPUS |
1.5 |
Batas core CPU container. Rekomendasi: UVICORN_WORKERS + 0.5. |
Contoh konfigurasi produksi untuk 3 workers (server 4 core):
UVICORN_WORKERS=3
OPENCV_THREADS=1
FACE_API_AUTH_CODE=face_absensi_2026_X9dPq72LkA88_secret# docker-compose.yml
mem_limit: ${FACE_MEM_LIMIT:-512m} # set FACE_MEM_LIMIT=900m di .env
cpus: "${FACE_CPUS:-1.5}" # set FACE_CPUS=3.5 di .envDefault threshold:
FACE_THRESHOLD=0.363Nilai ini adalah default awal untuk model SFace dengan cosine similarity. Untuk production, threshold sebaiknya dikalibrasi memakai data absensi nyata.
Auth code:
FACE_API_AUTH_CODE=ganti_dengan_kode_rahasia_panjangUntuk production, ganti dengan string panjang/random. Contoh:
FACE_API_AUTH_CODE=face_absensi_2026_X9dPq72LkA88_secretJika FACE_API_AUTH_CODE dikosongkan, endpoint tidak membutuhkan auth. Untuk production, jangan kosongkan variable ini.
Pastikan file ini ada:
app/config.py
Isi minimal sudah harus memiliki konfigurasi ini:
face_api_auth_code: str = os.getenv("FACE_API_AUTH_CODE", "")Jika mengikuti source code versi terbaru, /health akan menampilkan:
"auth_enabled": truejika FACE_API_AUTH_CODE sudah terbaca.
Dari root project:
cd ~/face-compare-service
sudo docker compose buildJika baru mengubah source code Python, gunakan rebuild tanpa cache:
sudo docker compose build --no-cacheJalankan container:
sudo docker compose up -dCek container:
sudo docker psCek log:
sudo docker logs -f face-compare-serviceService berjalan di:
http://127.0.0.1:8088
Secara default di docker-compose.yml, port hanya dibuka ke localhost:
ports:
- "127.0.0.1:8088:8088"Artinya service hanya bisa diakses dari server yang sama. Ini lebih aman untuk production.
Endpoint:
GET /healthContoh request:
curl http://127.0.0.1:8088/healthContoh response:
{
"status": "ok",
"service": "face-compare-service",
"version": "1.0.2",
"opencv_version": "4.12.0",
"threshold": 0.363,
"opencv_threads": 1,
"uvicorn_workers": 3,
"auth_enabled": true
}Keterangan:
| Field | Keterangan |
|---|---|
uvicorn_workers |
Jumlah worker yang dikonfigurasi via UVICORN_WORKERS |
opencv_threads |
Thread OpenCV per worker |
auth_enabled |
true jika FACE_API_AUTH_CODE sudah aktif |
uvicorn_workersdi response ini membaca nilai env saat startup — berguna untuk verifikasi konfigurasi sudah terbaca dengan benar.
Endpoint:
POST /extractContent type:
multipart/form-data
Header wajib jika FACE_API_AUTH_CODE diisi:
X-Auth-Code: isi_auth_code_sesuai_envField:
| Field | Wajib | Keterangan |
|---|---|---|
image |
Ya | Foto wajah untuk diekstrak menjadi embedding |
Contoh request:
curl -X POST http://127.0.0.1:8088/extract \
-H "X-Auth-Code: ganti_dengan_kode_rahasia_panjang" \
-F "image=@/home/ichi/test/ref.jpg"Contoh response:
{
"embedding": [0.01234567, -0.02345678, 0.03456789],
"embedding_size": 128,
"face": {
"face_count": 1,
"box": [120.0, 80.0, 180.0, 180.0],
"score": 0.998123
}
}embedding dari endpoint ini bisa dipakai sebagai reference_embedding pada endpoint /verify-embedding.
Endpoint:
POST /verify-embeddingContent type:
multipart/form-data
Header wajib jika FACE_API_AUTH_CODE diisi:
X-Auth-Code: isi_auth_code_sesuai_envField:
| Field | Wajib | Keterangan |
|---|---|---|
reference_embedding |
Ya | Embedding referensi dalam format JSON array angka |
probe_image |
Ya | Foto absensi terbaru |
threshold |
Tidak | Override threshold dari .env |
Contoh request:
curl -X POST http://127.0.0.1:8088/verify-embedding \
-H "X-Auth-Code: ganti_dengan_kode_rahasia_panjang" \
-F 'reference_embedding=[0.01234567,-0.02345678,0.03456789]' \
-F "probe_image=@/home/ichi/test/absen.jpg"Contoh dengan threshold manual:
curl -X POST http://127.0.0.1:8088/verify-embedding \
-H "X-Auth-Code: ganti_dengan_kode_rahasia_panjang" \
-F 'reference_embedding=[0.01234567,-0.02345678,0.03456789]' \
-F "probe_image=@/home/ichi/test/absen.jpg" \
-F "threshold=0.40"Contoh response:
{
"match": true,
"similarity": 0.512345,
"threshold": 0.363,
"distance_l2": 0.982345,
"message": "same person",
"probe_face": {
"face_count": 1,
"embedding": [0.01234567, -0.02345678, 0.03456789],
"box": [100.0, 70.0, 175.0, 175.0],
"score": 0.997456
}
}Endpoint:
POST /verifyContent type:
multipart/form-data
Header wajib jika FACE_API_AUTH_CODE diisi:
X-Auth-Code: isi_auth_code_sesuai_envField:
| Field | Wajib | Keterangan |
|---|---|---|
reference_image |
Ya | Foto referensi karyawan |
probe_image |
Ya | Foto absensi terbaru |
threshold |
Tidak | Override threshold dari .env |
Contoh request dengan auth:
curl -X POST http://127.0.0.1:8088/verify \
-H "X-Auth-Code: ganti_dengan_kode_rahasia_panjang" \
-F "reference_image=@/home/ichi/test/ref.jpg" \
-F "probe_image=@/home/ichi/test/absen.jpg"Contoh dengan threshold manual:
curl -X POST http://127.0.0.1:8088/verify \
-H "X-Auth-Code: ganti_dengan_kode_rahasia_panjang" \
-F "reference_image=@/home/ichi/test/ref.jpg" \
-F "probe_image=@/home/ichi/test/absen.jpg" \
-F "threshold=0.40"Contoh request tanpa auth:
curl -X POST http://127.0.0.1:8088/verify \
-F "reference_image=@/home/ichi/test/ref.jpg" \
-F "probe_image=@/home/ichi/test/absen.jpg"Jika auth aktif, request tanpa header X-Auth-Code akan ditolak.
Jika wajah cocok:
{
"match": true,
"similarity": 0.512345,
"threshold": 0.363,
"distance_l2": 0.982345,
"message": "same person",
"reference_face": {
"face_count": 1,
"box": [120.0, 80.0, 180.0, 180.0],
"score": 0.998123
},
"probe_face": {
"face_count": 1,
"embedding": [0.01234567, -0.02345678, 0.03456789],
"box": [100.0, 70.0, 175.0, 175.0],
"score": 0.997456
}
}Jika wajah tidak cocok:
{
"match": false,
"similarity": 0.201234,
"threshold": 0.363,
"distance_l2": 1.456789,
"message": "different person",
"reference_face": {
"face_count": 1,
"box": [120.0, 80.0, 180.0, 180.0],
"score": 0.998123
},
"probe_face": {
"face_count": 1,
"embedding": [0.01234567, -0.02345678, 0.03456789],
"box": [100.0, 70.0, 175.0, 175.0],
"score": 0.997456
}
}Jika auth code tidak dikirim:
{
"detail": {
"error": "AUTH_CODE_REQUIRED",
"message": "Header X-Auth-Code wajib dikirim."
}
}Jika auth code salah:
{
"detail": {
"error": "INVALID_AUTH_CODE",
"message": "Auth code tidak valid."
}
}Jika gambar tidak valid:
{
"detail": {
"error": "INVALID_IMAGE",
"message": "File tidak bisa dibaca sebagai gambar. Gunakan JPG/PNG yang valid."
}
}Jika wajah tidak terdeteksi:
{
"detail": {
"error": "NO_FACE_DETECTED",
"message": "Tidak ada wajah yang terdeteksi pada gambar."
}
}Jika terdeteksi lebih dari satu wajah:
{
"detail": {
"error": "MULTIPLE_FACES_DETECTED",
"message": "Terdeteksi 2 wajah. Untuk absensi, kirim foto dengan satu wajah saja."
}
}Tambahkan .env di aplikasi Go:
FACE_COMPARE_PROVIDER=opencv_sface
FACE_COMPARE_URL=http://127.0.0.1:8088/verify
FACE_COMPARE_THRESHOLD=0.363
FACE_COMPARE_AUTH_CODE=ganti_dengan_kode_rahasia_panjangFlow backend:
1. Ambil path foto referensi karyawan dari database
2. Ambil path foto absensi yang baru diupload
3. Kirim keduanya ke FACE_COMPARE_URL
4. Tambahkan header X-Auth-Code
5. Baca response JSON
6. Jika match=true, absensi diterima
7. Simpan similarity_score dan threshold_used ke database
Contoh header di Go:
req.Header.Set("Content-Type", writer.FormDataContentType())
req.Header.Set("X-Auth-Code", os.Getenv("FACE_COMPARE_AUTH_CODE"))Data yang disarankan disimpan di tabel absensi:
similarity_score
threshold_used
face_compare_provider
face_compare_message
face_reference_path
face_probe_path
Untuk memastikan FastAPI mencatat IP asli pengguna (bukan IP dari Load Balancer atau Backend Service), Backend Go akan menyertakan header tambahan:
req.Header.Set("X-Forwarded-For", clientIP)Karena Face Service berjalan di belakang proxy, Uvicorn di dalam Dockerfile sudah dikonfigurasi dengan flag --proxy-headers dan --forwarded-allow-ips='*'. Dengan begitu, log akses FastAPI akan menampilkan IP pengguna (Client IP) secara akurat.
REFERENCE_IMAGE="/path/foto_karyawan.jpg"
PROBE_IMAGE="/path/foto_absensi.jpg"
AUTH_CODE="ganti_dengan_kode_rahasia_panjang"
curl -X POST http://127.0.0.1:8088/verify \
-H "X-Auth-Code: ${AUTH_CODE}" \
-F "reference_image=@${REFERENCE_IMAGE}" \
-F "probe_image=@${PROBE_IMAGE}"Dengan threshold dari environment:
REFERENCE_IMAGE="/path/foto_karyawan.jpg"
PROBE_IMAGE="/path/foto_absensi.jpg"
THRESHOLD="0.363"
AUTH_CODE="ganti_dengan_kode_rahasia_panjang"
curl -X POST http://127.0.0.1:8088/verify \
-H "X-Auth-Code: ${AUTH_CODE}" \
-F "reference_image=@${REFERENCE_IMAGE}" \
-F "probe_image=@${PROBE_IMAGE}" \
-F "threshold=${THRESHOLD}"Start service:
sudo docker compose up -dStop service:
sudo docker compose downRestart service:
sudo docker compose restartLihat log:
sudo docker logs -f face-compare-serviceLihat penggunaan resource:
sudo docker stats face-compare-serviceRebuild setelah ubah code:
sudo docker compose down
sudo docker compose build --no-cache
sudo docker compose up -dJika mengubah .env, restart container:
sudo docker compose restartJika mengubah source code Python, rebuild:
sudo docker compose down
sudo docker compose build --no-cache
sudo docker compose up -dUntuk memastikan auth sudah aktif:
curl http://127.0.0.1:8088/healthPastikan response berisi:
"auth_enabled": trueDefault awal:
FACE_THRESHOLD=0.363Threshold ini belum tentu final untuk kondisi lapangan. Kamera, pencahayaan, kualitas foto referensi, dan sudut wajah dapat mempengaruhi hasil.
Rekomendasi kalibrasi:
1. Simpan similarity setiap absensi
2. Ambil sampel data beberapa hari
3. Tandai manual mana yang benar cocok dan salah cocok
4. Jika terlalu banyak false accept, naikkan threshold
5. Jika terlalu banyak false reject, turunkan threshold
Contoh penyesuaian:
Lebih ketat : 0.38 - 0.42
Default awal : 0.363
Lebih longgar : 0.34 - 0.35
Untuk production, jangan expose service ini langsung ke internet.
Disarankan:
Go Gin Backend dan Face Compare Service berada di server yang sama
Face Compare Service hanya listen di 127.0.0.1
Public request hanya masuk ke Go Gin Backend
Default docker-compose.yml sudah membatasi port:
ports:
- "127.0.0.1:8088:8088"Endpoint /verify juga dilindungi header:
X-Auth-Code: isi_auth_code_sesuai_envJika service harus dipanggil dari server lain, gunakan salah satu:
1. Private network
2. VPN
3. Firewall whitelist IP
4. Internal Docker network
5. Reverse proxy dengan authentication
Cek log:
sudo docker logs -f face-compare-serviceCek struktur file:
find . -maxdepth 3 -type f | sortPastikan file ini ada:
app/__init__.py
app/config.py
app/face_service.py
app/main.py
Setelah itu rebuild:
sudo docker compose down
sudo docker compose build --no-cache
sudo docker compose up -dError contoh:
MODEL_NOT_FOUND
Cek file model:
ls -lh modelsPastikan file ini ada:
models/face_detection_yunet_2023mar.onnx
models/face_recognition_sface_2021dec.onnx
Jika belum ada, download ulang lalu rebuild:
wget -O models/face_detection_yunet_2023mar.onnx \
https://github.com/opencv/opencv_zoo/raw/main/models/face_detection_yunet/face_detection_yunet_2023mar.onnx
wget -O models/face_recognition_sface_2021dec.onnx \
https://github.com/opencv/opencv_zoo/raw/main/models/face_recognition_sface/face_recognition_sface_2021dec.onnx
sudo docker compose build --no-cache
sudo docker compose up -dCek apakah container berjalan:
sudo docker psCek port:
curl http://127.0.0.1:8088/healthCek .env:
cat .envPastikan ada:
FACE_API_AUTH_CODE=ganti_dengan_kode_rahasia_panjangRestart container:
sudo docker compose restartCek health:
curl http://127.0.0.1:8088/healthJika auth_enabled masih false, rebuild:
sudo docker compose down
sudo docker compose build --no-cache
sudo docker compose up -dPastikan request mengirim header:
X-Auth-Code: isi_auth_code_sesuai_envContoh:
curl -X POST http://127.0.0.1:8088/verify \
-H "X-Auth-Code: ganti_dengan_kode_rahasia_panjang" \
-F "reference_image=@ref.jpg" \
-F "probe_image=@absen.jpg"Artinya X-Auth-Code dikirim, tapi nilainya tidak sama dengan FACE_API_AUTH_CODE di .env.
Cek nilai .env:
grep FACE_API_AUTH_CODE .envLalu cocokkan dengan header request.
Kemungkinan:
1. Foto terlalu gelap
2. Wajah terlalu kecil
3. Wajah terlalu miring
4. Foto blur
5. Masker/topi/kacamata menutup wajah
Coba gunakan foto dengan wajah lebih jelas.
Secara default:
ALLOW_MULTIPLE_FACES=falseUntuk absensi, ini lebih aman.
Jika tetap ingin mengambil wajah terbesar, ubah:
ALLOW_MULTIPLE_FACES=trueLalu restart:
sudo docker compose restartCek resource:
sudo docker stats face-compare-serviceOpsi optimasi:
1. Naikkan UVICORN_WORKERS sesuai core yang tersedia
2. Pastikan OPENCV_THREADS=1 (biarkan scaling via workers, bukan threads)
3. Aktifkan USE_FACE_QUEUE=true di backend Go
4. Pastikan semua pegawai sudah punya face_embedding di DB
→ request akan pakai /verify-embedding (~2x lebih cepat dari /verify)
5. Batasi ukuran upload foto (MAX_UPLOAD_MB)
6. Kompres foto di sisi mobile sebelum dikirim
Setelah mengubah UVICORN_WORKERS, rebuild container:
sudo docker compose down
sudo docker compose up -d --buildVerifikasi workers sudah terbaca:
curl http://127.0.0.1:8088/health
# Pastikan "uvicorn_workers" sesuai dengan nilai yang disetJika muncul warning:
Your kernel does not support swap limit capabilities or the cgroup is not mounted.
Memory limited without swap.
Ini bukan error — container tetap berjalan normal. mem_limit tetap berlaku, hanya batas swap yang tidak aktif. Untuk dev/staging, abaikan saja.
Jika ingin mengaktifkan swap limit di production:
sudo nano /etc/default/grub
# Ubah baris GRUB_CMDLINE_LINUX menjadi:
# GRUB_CMDLINE_LINUX="cgroup_enable=memory swapaccount=1"
sudo update-grub && sudo rebootProject microservice ini menggunakan library OpenCV dan model ONNX dari OpenCV Zoo.
Sebelum production skala besar, pastikan kembali lisensi model dan library yang digunakan sesuai kebutuhan organisasi.
| Method | Endpoint | Auth | Fungsi |
|---|---|---|---|
| GET | /health |
Tidak | Cek status service dan konfigurasi aktif |
| POST | /extract |
X-Auth-Code jika aktif |
Ekstrak embedding dari foto wajah |
| POST | /verify |
X-Auth-Code jika aktif |
Compare wajah 1:1 (2 foto) |
| POST | /verify-embedding |
X-Auth-Code jika aktif |
Compare embedding tersimpan vs foto baru |
Untuk performa terbaik di produksi, gunakan alur: ekstrak embedding saat enrollment (
/extract), simpan di DB, lalu pakai/verify-embeddingsetiap absensi. Ini ~2× lebih cepat dibanding/verify(image vs image) karena foto referensi tidak perlu diproses ulang setiap kali.
Field endpoint /verify:
| Field | Type | Keterangan |
|---|---|---|
reference_image |
file | Foto referensi |
probe_image |
file | Foto absensi |
threshold |
form number (opsional) | Override threshold |
Field endpoint /verify-embedding:
| Field | Type | Keterangan |
|---|---|---|
reference_embedding |
text (JSON array) | Embedding dari /extract yang tersimpan di DB |
probe_image |
file | Foto absensi |
threshold |
form number (opsional) | Override threshold |
Contoh paling singkat (/verify):
curl -X POST http://127.0.0.1:8088/verify \
-H "X-Auth-Code: ganti_dengan_kode_rahasia_panjang" \
-F "reference_image=@ref.jpg" \
-F "probe_image=@absen.jpg"Contoh paling singkat (/verify-embedding):
curl -X POST http://127.0.0.1:8088/verify-embedding \
-H "X-Auth-Code: ganti_dengan_kode_rahasia_panjang" \
-F 'reference_embedding=[0.012,-0.023,0.034]' \
-F "probe_image=@absen.jpg"