Skip to content

DmytroGural/deepface-rest-api

Repository files navigation

DeepFace REST API

A production-grade REST API wrapping DeepFace — a lightweight face recognition and analysis library for Python.

Built with Flask, Pydantic v2, and Docker.


Features

  • Face verification — determine whether two images show the same person
  • Face analysis — predict age, gender, emotion, and race
  • Face embedding — extract a numerical vector for downstream storage or comparison
  • Face search — find matching identities in a directory of reference images
  • Face extraction — detect and crop every face in an image
  • All three image input formats supported: file path, URL, base64 data-URI
  • Structured JSON logs with per-request tracing (X-Request-Id header)
  • Typed configuration via pydantic-settings (.env file)
  • Docker + docker-compose ready

Project Structure

deepface-rest-api/
├── main.py                     # Entry point (sets CUDA env before TF import)
├── core/
│   ├── factory.py              # create_app(), error handlers, request lifecycle
│   ├── config.py               # Typed settings via pydantic-settings
│   ├── exceptions.py           # Domain exception hierarchy with HTTP codes
│   ├── images.py               # managed_image_path() context manager
│   └── logging.py              # Structured JSON/text logger + request_id
├── schemas/
│   └── faces.py                # Pydantic v2 request & response models
├── services/
│   └── deepface_service.py     # Business logic — the only place DeepFace is called
├── api/v1/
│   └── routes.py               # Flask Blueprint — HTTP layer only
├── Dockerfile
├── docker-compose.yml
├── requirements.txt
└── .env.example

Architecture

.env ──► core/config.py
          │
   core/exceptions.py   core/images.py   core/logging.py
          │                    │                │
   schemas/faces.py ──────────────────────────────────────────
          │
   services/deepface_service.py   (calls DeepFace here only)
          │
   api/v1/routes.py               (HTTP: parse → call → respond)
          │
   app_factory.py                 (register blueprint, error handlers)
          │
   main.py                        (entry point)

Quick Start

Local

git clone https://github.com/DmytroGural/deepface-rest-api.git
cd deepface-rest-api

pip install -r requirements.txt
cp .env.example .env   # edit as needed

python main.py
# → http://localhost:5000

Docker

cp .env.example .env   # edit as needed
mkdir -p data/faces_db      # or point FACES_DB_PATH to an existing directory

docker compose up --build

First run — DeepFace downloads model weights on the first request (~500 MB total).
They are stored in the deepface_weights Docker volume and reused on subsequent starts.


Configuration

All settings are read from the .env file (or environment variables).

Variable Default Description
HOST 0.0.0.0 Bind address
PORT 5000 Bind port
DEBUG false Flask debug mode
DEFAULT_MODEL VGG-Face Default recognition model
DEFAULT_DETECTOR opencv Default face detector
DEFAULT_METRIC cosine Default distance metric
FACES_DB_PATH (empty) Path to reference faces directory for /find
GPU_DEVICE -1 -1 = CPU only, 0 = first GPU, "" = auto
LOG_LEVEL INFO DEBUG / INFO / WARNING / ERROR
LOG_FORMAT json json (production) or text (development)
MAX_IMAGE_BYTES 10485760 Maximum image size in bytes (default 10 MB)
HOST_PORT 5000 Host port mapping for Docker

API Reference

All endpoints accept Content-Type: application/json.
Every response includes X-Request-Id and X-Response-Time-Ms headers.

Image input formats

// Remote URL
{ "img": "https://example.com/face.jpg" }

// Base64 data-URI
{ "img": "data:image/jpeg;base64,/9j/4AAQ..." }

// Local file path
{ "img": "/data/photos/person.jpg" }

GET /

Returns service info and available endpoints.


GET /health

Liveness probe.

{ "status": "ok", "version": "0.0.1" }

POST /api/v1/verify

Determine whether two images belong to the same person.

Request

{
  "img1": "https://example.com/person_a.jpg",
  "img2": "https://example.com/person_b.jpg",
  "model_name": "VGG-Face",
  "detector_backend": "opencv",
  "distance_metric": "cosine",
  "enforce_detection": true,
  "align": true
}

Response 200

{
  "success": true,
  "verified": true,
  "distance": 0.2134,
  "threshold": 0.4,
  "model": "VGG-Face",
  "detector_backend": "opencv",
  "similarity_metric": "cosine",
  "facial_areas": { "img1": {...}, "img2": {...} },
  "time": 0.34
}

POST /api/v1/analyze

Analyze face attributes. Pass a subset of actions to speed up the response.

Request

{
  "img": "https://example.com/face.jpg",
  "actions": ["age", "gender", "emotion", "race"]
}

Response 200

{
  "success": true,
  "count": 1,
  "result": [
    {
      "age": 27,
      "dominant_gender": "Woman",
      "gender": { "Woman": 96.3, "Man": 3.7 },
      "dominant_emotion": "happy",
      "emotion": { "happy": 95.8, "neutral": 2.2, ... },
      "dominant_race": "asian",
      "race": { "asian": 78.2, "white": 12.1, ... },
      "region": { "x": 10, "y": 20, "w": 120, "h": 120 },
      "face_confidence": 0.97
    }
  ]
}

POST /api/v1/represent

Extract a face embedding vector for storage or custom similarity search.

Request

{
  "img": "https://example.com/face.jpg",
  "model_name": "Facenet512",
  "normalization": "base"
}

Response 200

{
  "success": true,
  "count": 1,
  "result": [
    {
      "embedding": [0.023, -0.142, ...],
      "facial_area": { "x": 10, "y": 20, "w": 120, "h": 120 },
      "face_confidence": 0.98
    }
  ]
}

Embedding dimensions by model: VGG-Face → 2622, Facenet → 128, Facenet512 / ArcFace → 512.


POST /api/v1/find

Search for matching faces in the configured FACES_DB_PATH directory.

On the first call DeepFace builds an index (.pkl file) inside FACES_DB_PATH.
Subsequent calls use the cached index and are significantly faster.

Database directory structure

faces_db/
  alice/
    photo1.jpg
    photo2.jpg
  bob/
    photo1.jpg

Request

{
  "img": "https://example.com/query.jpg",
  "model_name": "VGG-Face",
  "distance_metric": "cosine",
  "threshold": 0.4
}

Response 200

{
  "success": true,
  "faces_queried": 1,
  "result": [
    [
      {
        "identity": "/data/faces_db/alice/photo1.jpg",
        "distance": 0.18,
        "threshold": 0.4
      }
    ]
  ]
}

POST /api/v1/extract_faces

Detect and crop all faces in an image. Cropped faces are returned as base64 PNG strings.

Request

{
  "img": "https://example.com/group.jpg",
  "detector_backend": "retinaface",
  "expand_percentage": 10
}

Response 200

{
  "success": true,
  "faces_found": 2,
  "result": [
    {
      "face_base64": "data:image/png;base64,iVBORw0KGgo...",
      "facial_area": { "x": 10, "y": 20, "w": 120, "h": 120 },
      "confidence": 0.99
    }
  ]
}

Error Responses

All errors share a unified structure:

{
  "success": false,
  "error_code": "validation_error",
  "message": "Request validation failed",
  "request_id": "a3f1c2e9b0d4",
  "details": {
    "fields": [
      { "field": "img1", "msg": "Field required" }
    ]
  }
}
error_code HTTP Cause
validation_error 422 Invalid JSON or missing/wrong fields
image_decode_error 400 Invalid base64, unreachable URL, or file not found
image_too_large 413 Image exceeds MAX_IMAGE_BYTES
no_face_detected 422 DeepFace could not detect a face
db_not_found 400 FACES_DB_PATH directory does not exist
service_unavailable 503 FACES_DB_PATH is not configured
deepface_error 500 Internal DeepFace error
internal_error 500 Unexpected server error
not_found 404 Route does not exist
method_not_allowed 405 Wrong HTTP method

Allowed Parameter Values

Parameter Values
model_name VGG-Face, Facenet, Facenet512, OpenFace, DeepFace, DeepID, ArcFace, Dlib, SFace
detector_backend opencv, ssd, dlib, mtcnn, retinaface, mediapipe, yolov8, yunet, fastmtcnn
distance_metric cosine, euclidean, euclidean_l2
actions age, gender, emotion, race
normalization base, raw, Facenet, Facenet2018, VGGFace, VGGFace2, ArcFace

Design Decisions

Concern Solution
Configuration pydantic-settings — typed, validated at startup, reads .env
Request validation Pydantic v2 model_validate — field-level error messages
Image handling managed_image_path() context manager — temp files always cleaned up
Error handling AppError hierarchy with HTTP code baked in — single @errorhandler covers everything
Logging Structured JSON with request_id via contextvars — no need to pass it through function arguments
GPU config CUDA_VISIBLE_DEVICES set before TensorFlow import in main.py
Layer separation coreschemasservicesapi — each layer knows only the layer below

License

MIT

About

DeepFace REST API is a production-grade REST API for DeepFace — a lightweight face recognition and facial attribute analysis library for Python

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors