Skip to content

zhu-j-faceonlive/age-verification-api-python

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Facial Age Verification API (Python / FastAPI)

CI

License: MIT Python 3.11 FastAPI

A privacy-friendly age verification and age assurance API built with Python and FastAPI. It performs facial age estimation together with a liveness / anti-spoofing check to implement an age gate for age-restricted content, checkout flows, or sign-up — a privacy-friendly alternative to uploading a government ID. Everything runs on-premises: no image ever leaves your infrastructure, and there is no ID upload for the common case.

This is an honest, MIT-licensed example integration for the FaceOnLive on-premises biometric SDK suite — face recognition, liveness/anti-spoofing, ID OCR/MRZ, deepfake detection, face attributes (incl. age estimation) and eKYC. Website: https://faceonlive.com · Docs: https://faceonlive.com/docs/ · GitHub: https://github.com/FaceOnLive · Contact: [email protected]

Honesty note (please read)

Facial age estimation is probabilistic, not an exact measurement. Treat the returned age as an estimate with error bars. For any real deployment we recommend:

  • A challenge-age buffer. Only auto-approve subjects estimated clearly above the minimum age (MIN_AGE + AGE_BUFFER). Estimates inside the borderline band return decision="challenge".
  • A fallback to document verification (ID OCR/MRZ, also part of the FaceOnLive suite) for borderline cases and appeals.

This is engineering guidance to reduce false-approvals of underage users — it is not a legal-compliance claim. Whether facial age estimation satisfies a given regulation (and the exact thresholds/buffers/fallbacks required) is your determination. This example ships no accuracy benchmarks or certifications.

Features

  • Facial age estimation from a single selfie image.
  • Liveness / anti-spoofing so the age gate reflects a live person, not a photo.
  • Threshold + buffer decision logic returning allow | challenge | deny.
  • On-premises: the native engine runs locally; images stay on your servers.
  • Privacy-friendly: no ID upload in the common path.
  • Clean FastAPI surface with OpenAPI docs at /docs.
  • Native engine bound at runtime via a small, clearly-commented ctypes seam — missing library/license raises a clear error; it never fabricates an age.

How it works

selfie ──> [decode/RGB] ──> [liveness check] ──> [age estimate] ──> [decision]
                                   │                                     │
                              not live? ─────────────────────────────> deny
                                                                        │
                     age >= MIN_AGE + AGE_BUFFER ───────────────────> allow
                     MIN_AGE - buffer <= age < MIN_AGE + buffer ───> challenge
                     age <  MIN_AGE - AGE_BUFFER ─────────────────> deny
  1. Liveness first. A failed liveness check yields deny regardless of age.
  2. Age estimate. The engine returns an estimated age in years.
  3. Threshold decision. Compared against MIN_AGE with an AGE_BUFFER borderline band; borderline cases become challenge (route to document verification).

Requirements

  • Python 3.11+
  • The FaceOnLive on-premises SDK (native shared library + a valid license key). Request access at https://faceonlive.com/.
  • OS packages for Pillow (bundled in the provided Dockerfile).

Quickstart

# 1. Install dependencies
python -m venv .venv && source .venv/bin/activate   # Windows: .venv\Scripts\activate
pip install -r requirements.txt

# 2. Configure
cp .env.example .env
# edit .env: set FACEONLIVE_LICENSE_KEY and FACEONLIVE_SDK_LIB

# 3. Load env and run
export $(grep -v '^#' .env | xargs)   # or use your process manager / direnv
uvicorn app.main:app --reload

Open http://127.0.0.1:8000/docs for interactive API docs.

Without the native library/license the server still starts (degraded mode): GET /health works and POST /v1/age/verify returns HTTP 503 with a clear message. It never invents an age.

API Reference

POST /v1/age/verify

Multipart form upload of a selfie image.

Field Type Description
image file (multipart) JPEG/PNG containing one face.

Response 200

{
  "estimated_age": 27.4,
  "is_live": true,
  "decision": "allow",
  "threshold": 18,
  "buffer": 3
}

decision is one of:

  • allow — estimated age is clearly at/above MIN_AGE + AGE_BUFFER.
  • challenge — borderline; fall back to document verification / manual review.
  • deny — clearly below MIN_AGE - AGE_BUFFER, or liveness failed.

Error responses

Status Meaning
400 Empty or unreadable image.
413 Image exceeds the size limit.
503 Biometric engine unavailable (library/license).

GET /health

{ "status": "ok", "sdk_available": true, "version": "1.0.0" }

Returns status: "degraded" and sdk_available: false when the native engine did not load.

Example curl

curl -X POST http://127.0.0.1:8000/v1/age/verify \
  -F "[email protected]"
curl http://127.0.0.1:8000/health

How the SDK integration works (the ctypes seam)

The native engine is bound in app/faceonlive.py using ctypes. That module is the single integration point:

  • activate() — validates the license key (FACEONLIVE_LICENSE_KEY).
  • init() — loads the models into memory.
  • detect_liveness(rgb, w, h) — anti-spoofing check.
  • estimate_age(rgb, w, h) — age estimate in years.

The C prototypes (argtypes / restype / symbol names) in that file are representative — adjust them to match the header shipped with your licensed build (see https://faceonlive.com/docs/). If the library or license is missing or invalid, every call raises SdkUnavailableError, which the API surfaces as HTTP 503. No result is ever fabricated.

Docker

docker build -t age-verification-api .

docker run -p 8000:8000 \
  -e FACEONLIVE_LICENSE_KEY=<YOUR_LICENSE_KEY> \
  -e FACEONLIVE_SDK_LIB=/opt/faceonlive/libfaceonlive.so \
  -e MIN_AGE=18 -e AGE_BUFFER=3 \
  -v /opt/faceonlive:/opt/faceonlive:ro \
  age-verification-api

The native engine is not bundled in the image; mount it at runtime.

License & links

Licensed under the MIT License.

About

Facial age verification / age estimation API (Python / FastAPI). Privacy-friendly age gate with liveness, on-premises with the FaceOnLive SDK.

Topics

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors