face-intel / docs /CONFIGURATION.md
Marwan
Restructure + add reverse face search (PimEyes-style)
f5eeb1c
|
Raw
History Blame Contribute Delete
31.8 kB

Face Intel β€” Configuration Guide

This document is the complete reference for every configuration knob in Face Intel. All settings are environment-driven via pydantic-settings with the FI_ prefix.

Source of truth: config/settings.py. This doc is generated from that file β€” if you add a setting there, add a row here too.


Table of Contents

  1. How Settings Work
  2. Quick Reference: All Settings
  3. Core
  4. Provider Enable Flags
  5. Detection Tuning
  6. Recognition Tuning
  7. Scraping
  8. Reverse Image Search
  9. Orchestrator
  10. Cache
  11. Health & Circuit Breaker
  12. Storage
  13. API
  14. New-Capability Enable Flags
  15. Logging
  16. How to Enable/Disable Providers
  17. How to Configure API Keys
  18. Production vs Development
  19. Verifying Your Configuration

1. How Settings Work

The FI_ prefix

Every field on the Settings class is automatically mapped to an environment variable by uppercasing the field name and prepending FI_. Examples:

Field Env var
enable_haar FI_ENABLE_HAAR
dnn_confidence_threshold FI_DNN_CONFIDENCE_THRESHOLD
serpapi_key FI_SERPAPI_KEY
cache_ttl_seconds FI_CACHE_TTL_SECONDS

Env var names are case-insensitive (case_sensitive=False).

Loading order

pydantic-settings loads values in this order (later wins):

  1. Field defaults declared in config/settings.py.
  2. Values from the .env file at the project root (if present).
  3. Actual environment variables.

The .env file

Copy .env.example to .env and edit:

cp .env.example .env

The .env file is not committed (it's in .gitignore). Each line is KEY=value. Comments start with #.

Programmatic overrides

For tests or scripted runs, use the make_settings() factory:

from config.settings import make_settings

settings = make_settings(
    environment="test",
    cache_enabled=False,
    enable_dnn=False,
    db_path=":memory:",
)

This is exactly what tests/conftest.py does.

The settings singleton

config/settings.py exports a module-level settings = Settings() instance. Read-only consumers (like provider tuning knobs) may import it directly. Stateful services (Database, Cache, Orchestrator, services) MUST receive their dependencies via constructor injection β€” they never import this module. The DI container at api/container.py is the composition root.


2. Quick Reference: All Settings

Setting Env var Type Default Section
app_name FI_APP_NAME str "Face Intel" Core
app_version FI_APP_VERSION str "1.0.0" Core
environment FI_ENVIRONMENT str "development" Core
host FI_HOST str "0.0.0.0" Core
port FI_PORT int 8000 Core
debug FI_DEBUG bool False Core
enable_haar FI_ENABLE_HAAR bool True Providers
enable_dnn FI_ENABLE_DNN bool True Providers
enable_mtcnn FI_ENABLE_MTCNN bool True Providers
enable_retinaface FI_ENABLE_RETINAFACE bool False Providers
enable_face_recognition FI_ENABLE_FACE_RECOGNITION bool True Providers
enable_deepface FI_ENABLE_DEEPFACE bool False Providers
enable_insightface FI_ENABLE_INSIGHTFACE bool False Providers
enable_beautifulsoup_scraper FI_ENABLE_BEAUTIFULSOUP_SCRAPER bool True Providers
enable_selenium_scraper FI_ENABLE_SELENIUM_SCRAPER bool True Providers
enable_bing_scraper FI_ENABLE_BING_SCRAPER bool False Providers
enable_duckduckgo_scraper FI_ENABLE_DUCKDUCKGO_SCRAPER bool True Providers
enable_google_lens FI_ENABLE_GOOGLE_LENS bool True Providers
enable_serpapi FI_ENABLE_SERPAPI bool False Providers
enable_yandex FI_ENABLE_YANDEX bool False Providers
enable_tineye FI_ENABLE_TINEYE bool False Providers
dnn_confidence_threshold FI_DNN_CONFIDENCE_THRESHOLD float 0.7 Detection
mtcnn_min_face_size FI_MTCNN_MIN_FACE_SIZE int 20 Detection
haar_scale_factor FI_HAAR_SCALE_FACTOR float 1.1 Detection
haar_min_neighbors FI_HAAR_MIN_NEIGHBORS int 5 Detection
face_recognition_tolerance FI_FACE_RECOGNITION_TOLERANCE float 0.6 Recognition
face_recognition_model FI_FACE_RECOGNITION_MODEL str "hog" Recognition
deepface_backend FI_DEEPFACE_BACKEND str "arcface" Recognition
insightface_model_pack FI_INSIGHTFACE_MODEL_PACK str "buffalo_l" Recognition
recognition_match_threshold FI_RECOGNITION_MATCH_THRESHOLD float 0.5 Recognition
scrape_timeout FI_SCRAPE_TIMEOUT int 30 Scraping
scrape_max_images FI_SCRAPE_MAX_IMAGES int 50 Scraping
selenium_headless FI_SELENIUM_HEADLESS bool True Scraping
selenium_implicit_wait FI_SELENIUM_IMPLICIT_WAIT int 10 Scraping
selenium_scroll_iterations FI_SELENIUM_SCROLL_ITERATIONS int 5 Scraping
user_agent FI_USER_AGENT str (Chrome 121 string) Scraping
reverse_search_max_results FI_REVERSE_SEARCH_MAX_RESULTS int 20 Reverse
serpapi_key FI_SERPAPI_KEY str "" Reverse
bing_api_key FI_BING_API_KEY str "" Reverse
tineye_public_key FI_TINEYE_PUBLIC_KEY str "" Reverse
tineye_private_key FI_TINEYE_PRIVATE_KEY str "" Reverse
orchestrator_timeout_seconds FI_ORCHESTRATOR_TIMEOUT_SECONDS float 90.0 Orchestrator
orchestrator_max_concurrency FI_ORCHESTRATOR_MAX_CONCURRENCY int 8 Orchestrator
retry_max_attempts FI_RETRY_MAX_ATTEMPTS int 3 Orchestrator
retry_initial_backoff_seconds FI_RETRY_INITIAL_BACKOFF_SECONDS float 0.5 Orchestrator
retry_max_backoff_seconds FI_RETRY_MAX_BACKOFF_SECONDS float 8.0 Orchestrator
cache_enabled FI_CACHE_ENABLED bool True Cache
cache_ttl_seconds FI_CACHE_TTL_SECONDS int 3600 Cache
cache_max_entries FI_CACHE_MAX_ENTRIES int 1000 Cache
health_check_interval_seconds FI_HEALTH_CHECK_INTERVAL_SECONDS int 60 Health
circuit_breaker_failure_threshold FI_CIRCUIT_BREAKER_FAILURE_THRESHOLD int 5 Health
circuit_breaker_recovery_seconds FI_CIRCUIT_BREAKER_RECOVERY_SECONDS int 120 Health
db_path FI_DB_PATH str data/face_intel.db Storage
audit_log_path FI_AUDIT_LOG_PATH str data/audit.log Storage
job_retention_days FI_JOB_RETENTION_DAYS int 7 Storage
rate_limit_per_minute FI_RATE_LIMIT_PER_MINUTE int 30 API
cors_origins FI_CORS_ORIGINS list[str] ["*"] API
require_consent_header FI_REQUIRE_CONSENT_HEADER bool True API
consent_header_name FI_CONSENT_HEADER_NAME str "X-Consent-Statement" API
max_image_bytes FI_MAX_IMAGE_BYTES int 20971520 (20 MB) API
job_timeout_seconds FI_JOB_TIMEOUT_SECONDS float 300.0 API
max_request_body_bytes FI_MAX_REQUEST_BODY_BYTES int 26214400 (25 MB) API
enable_image_quality FI_ENABLE_IMAGE_QUALITY bool True New caps
enable_image_properties FI_ENABLE_IMAGE_PROPERTIES bool True New caps
enable_visual_features FI_ENABLE_VISUAL_FEATURES bool False New caps
enable_exif FI_ENABLE_EXIF bool True New caps
enable_xmp FI_ENABLE_XMP bool False New caps
enable_image_integrity FI_ENABLE_IMAGE_INTEGRITY bool True New caps
enable_duplicate_detector FI_ENABLE_DUPLICATE_DETECTOR bool True New caps
enable_manipulation_analyzer FI_ENABLE_MANIPULATION_ANALYZER bool False New caps
log_level FI_LOG_LEVEL str "INFO" Logging
log_json FI_LOG_JSON bool False Logging

3. Core

Setting Env var Type Default Description
app_name FI_APP_NAME str "Face Intel" Display name shown in OpenAPI title and / root.
app_version FI_APP_VERSION str "1.0.0" Version string exposed in /health/providers and OpenAPI.
environment FI_ENVIRONMENT str "development" Free-form label (development, staging, production, test). Currently informational only.
host FI_HOST str "0.0.0.0" Bind address for uvicorn.run() in app.py.
port FI_PORT int 8000 Bind port.
debug FI_DEBUG bool False If True, uvicorn runs with --reload (auto-restart on code changes). Never enable in production.

Example

FI_ENVIRONMENT=production
FI_HOST=0.0.0.0
FI_PORT=8000
FI_DEBUG=false

4. Provider Enable Flags

Each provider has a enable_<name> flag. Default values follow this rule:

  • Default True for providers that ship with the platform and have no external dependencies: haar, dnn, mtcnn, face_recognition, beautifulsoup_scraper, selenium_scraper, duckduckgo_scraper, google_lens.
  • Default False for providers that require paid API keys or heavy optional dependencies: retinaface, deepface, insightface, bing_scraper, serpapi, yandex, tineye.
Setting Env var Default Capability
enable_haar FI_ENABLE_HAAR True detection
enable_dnn FI_ENABLE_DNN True detection
enable_mtcnn FI_ENABLE_MTCNN True detection
enable_retinaface FI_ENABLE_RETINAFACE False detection
enable_face_recognition FI_ENABLE_FACE_RECOGNITION True recognition
enable_deepface FI_ENABLE_DEEPFACE False recognition
enable_insightface FI_ENABLE_INSIGHTFACE False recognition
enable_beautifulsoup_scraper FI_ENABLE_BEAUTIFULSOUP_SCRAPER True scraping
enable_selenium_scraper FI_ENABLE_SELENIUM_SCRAPER True scraping
enable_bing_scraper FI_ENABLE_BING_SCRAPER False scraping
enable_duckduckgo_scraper FI_ENABLE_DUCKDUCKGO_SCRAPER True scraping
enable_google_lens FI_ENABLE_GOOGLE_LENS True reverse_search
enable_serpapi FI_ENABLE_SERPAPI False reverse_search
enable_yandex FI_ENABLE_YANDEX False reverse_search
enable_tineye FI_ENABLE_TINEYE False reverse_search

Notes

  • A flag set to True does not guarantee the provider is healthy β€” the provider's is_available() may still return False if an optional dependency is missing or an API key is not set. In that case it shows up as not_configured in /providers.
  • See Β§16 for the workflow.

5. Detection Tuning

Setting Env var Type Default Description
dnn_confidence_threshold FI_DNN_CONFIDENCE_THRESHOLD float 0.7 Minimum confidence (0–1) for the DNN Caffe SSD detector to accept a detection. Lower = more faces (more false positives).
mtcnn_min_face_size FI_MTCNN_MIN_FACE_SIZE int 20 Minimum face size in pixels for MTCNN. Increase for speed on high-resolution images.
haar_scale_factor FI_HAAR_SCALE_FACTOR float 1.1 Scale factor for Haar Cascade multiscale detection. Lower = more thorough, slower.
haar_min_neighbors FI_HAAR_MIN_NEIGHBORS int 5 Min neighbors for Haar group rect merging. Higher = fewer detections, more confident.

Example: tuning for accuracy

FI_DNN_CONFIDENCE_THRESHOLD=0.5
FI_MTCNN_MIN_FACE_SIZE=40
FI_HAAR_SCALE_FACTOR=1.05
FI_HAAR_MIN_NEIGHBORS=8

Example: tuning for speed

FI_DNN_CONFIDENCE_THRESHOLD=0.9
FI_MTCNN_MIN_FACE_SIZE=80
FI_HAAR_SCALE_FACTOR=1.3
FI_HAAR_MIN_NEIGHBORS=3

6. Recognition Tuning

Setting Env var Type Default Description
face_recognition_tolerance FI_FACE_RECOGNITION_TOLERANCE float 0.6 dlib distance tolerance for face_recognition provider. Lower = stricter (fewer false positives).
face_recognition_model FI_FACE_RECOGNITION_MODEL str "hog" dlib model: "hog" (CPU, fast) or "cnn" (CUDA, accurate).
deepface_backend FI_DEEPFACE_BACKEND str "arcface" DeepFace backend: arcface, facenet, vggface, openface, etc.
insightface_model_pack FI_INSIGHTFACE_MODEL_PACK str "buffalo_l" InsightFace model pack name.
recognition_match_threshold FI_RECOGNITION_MATCH_THRESHOLD float 0.5 Generic similarity threshold for considering a face "matched".

Example: stricter recognition

FI_FACE_RECOGNITION_TOLERANCE=0.4
FI_RECOGNITION_MATCH_THRESHOLD=0.65

7. Scraping

Setting Env var Type Default Description
scrape_timeout FI_SCRAPE_TIMEOUT int 30 HTTP timeout in seconds for scraper requests.
scrape_max_images FI_SCRAPE_MAX_IMAGES int 50 Maximum images to extract from a single page.
selenium_headless FI_SELENIUM_HEADLESS bool True Run Chrome/Chromium headless. Set False for debugging.
selenium_implicit_wait FI_SELENIUM_IMPLICIT_WAIT int 10 Selenium implicit wait seconds.
selenium_scroll_iterations FI_SELENIUM_SCROLL_ITERATIONS int 5 Number of times to scroll the page (loads lazy images).
user_agent FI_USER_AGENT str (Chrome 121 string) User-Agent header for HTTP requests and Selenium.

Example: scraping authenticated intranet pages

FI_USER_AGENT="MyCorp Internal Bot/1.0 (contact: ops@mycorp.example)"
FI_SELENIUM_HEADLESS=true
FI_SELENIUM_IMPLICIT_WAIT=20
FI_SELENIUM_SCROLL_ITERATIONS=10
FI_SCRAPE_MAX_IMAGES=200

8. Reverse Image Search

Setting Env var Type Default Description
reverse_search_max_results FI_REVERSE_SEARCH_MAX_RESULTS int 20 Max results to return per reverse-search provider.
serpapi_key FI_SERPAPI_KEY str "" SerpAPI API key. Required for serpapi provider to be available.
bing_api_key FI_BING_API_KEY str "" Bing Image Search API key. Required for bing scraper.
tineye_public_key FI_TINEYE_PUBLIC_KEY str "" TinEye OAuth public key.
tineye_private_key FI_TINEYE_PRIVATE_KEY str "" TinEye OAuth private key.

Example: enabling SerpAPI

FI_ENABLE_SERPAPI=true
FI_SERPAPI_KEY=your_serpapi_key_here
FI_REVERSE_SEARCH_MAX_RESULTS=50

See Β§17 for the full key setup workflow.


9. Orchestrator

Setting Env var Type Default Description
orchestrator_timeout_seconds FI_ORCHESTRATOR_TIMEOUT_SECONDS float 90.0 Per-provider hard timeout. If a single provider takes longer, the orchestrator cancels it and records a TimeoutError result.
orchestrator_max_concurrency FI_ORCHESTRATOR_MAX_CONCURRENCY int 8 Max number of providers to invoke concurrently. Lower this on memory-constrained hosts.
retry_max_attempts FI_RETRY_MAX_ATTEMPTS int 3 Max retry attempts per provider invocation (including the first).
retry_initial_backoff_seconds FI_RETRY_INITIAL_BACKOFF_SECONDS float 0.5 Initial backoff. Doubles each attempt up to retry_max_backoff_seconds, with full jitter.
retry_max_backoff_seconds FI_RETRY_MAX_BACKOFF_SECONDS float 8.0 Upper bound on backoff delay.

Retriable exceptions

Only TimeoutError, ConnectionError, and OSError are retried. Other exceptions (e.g. RuntimeError from a bad API response) are not retried β€” see docs/PROVIDERS.md Β§10 for how to convert transient errors into retriable ones.

Example: aggressive retry for flaky networks

FI_RETRY_MAX_ATTEMPTS=5
FI_RETRY_INITIAL_BACKOFF_SECONDS=1.0
FI_RETRY_MAX_BACKOFF_SECONDS=30.0
FI_ORCHESTRATOR_TIMEOUT_SECONDS=180
FI_ORCHESTRATOR_MAX_CONCURRENCY=4

Example: fast-fail for low-latency APIs

FI_RETRY_MAX_ATTEMPTS=1
FI_ORCHESTRATOR_TIMEOUT_SECONDS=15
FI_ORCHESTRATOR_MAX_CONCURRENCY=16

10. Cache

The cache stores successful ProviderResult objects keyed by f"{provider_name}:{image_hash}". On a cache hit, the provider is not invoked β€” the cached result is returned (with metadata.cache_hit=True).

Setting Env var Type Default Description
cache_enabled FI_CACHE_ENABLED bool True Master switch. Set False to disable cache entirely (every request invokes providers).
cache_ttl_seconds FI_CACHE_TTL_SECONDS int 3600 Time-to-live for cache entries (seconds). Entries expire even if not evicted by LRU.
cache_max_entries FI_CACHE_MAX_ENTRIES int 1000 Maximum entries. When exceeded, the oldest entry is evicted (LRU).

Cache eviction

Two policies compose:

  • TTL: cache_ttl_seconds after set(), the entry expires.
  • LRU: when adding a new entry would exceed cache_max_entries, the least-recently-accessed entry is evicted. Eviction counter is exposed in GET /cache as evictions.

Example: development (always-fresh)

FI_CACHE_ENABLED=false

Example: high-throughput production

FI_CACHE_ENABLED=true
FI_CACHE_TTL_SECONDS=86400
FI_CACHE_MAX_ENTRIES=10000

Inspecting the cache

curl http://localhost:8000/cache
curl -X DELETE http://localhost:8000/cache

See docs/API_REFERENCE.md Β§9.


11. Health & Circuit Breaker

Setting Env var Type Default Description
health_check_interval_seconds FI_HEALTH_CHECK_INTERVAL_SECONDS int 60 Reserved for future background health polling (currently informational).
circuit_breaker_failure_threshold FI_CIRCUIT_BREAKER_FAILURE_THRESHOLD int 5 Consecutive failures before the circuit opens for a provider.
circuit_breaker_recovery_seconds FI_CIRCUIT_BREAKER_RECOVERY_SECONDS int 120 Seconds before an open circuit transitions to half-open (allows one trial call).

Circuit breaker lifecycle

  1. Provider fails β†’ consecutive_failures += 1.
  2. When consecutive_failures >= circuit_breaker_failure_threshold, the circuit opens and the orchestrator skips this provider.
  3. After circuit_breaker_recovery_seconds elapses, the circuit transitions to half-open: the next request is allowed through.
  4. If the trial call succeeds, the circuit closes and consecutive_failures resets to 0.
  5. If the trial call fails, the circuit re-opens for another recovery window.

Example: aggressive failover

FI_CIRCUIT_BREAKER_FAILURE_THRESHOLD=3
FI_CIRCUIT_BREAKER_RECOVERY_SECONDS=30

Example: tolerant of transient blips

FI_CIRCUIT_BREAKER_FAILURE_THRESHOLD=10
FI_CIRCUIT_BREAKER_RECOVERY_SECONDS=300

Inspecting circuit state

curl http://localhost:8000/health/providers | jq '.providers[] | {name, circuit_open, consecutive_failures}'

12. Storage

Setting Env var Type Default Description
db_path FI_DB_PATH str data/face_intel.db SQLite database path. Use :memory: for in-memory (tests).
audit_log_path FI_AUDIT_LOG_PATH str data/audit.log JSONL audit log path. Appended to on sensitive operations.
job_retention_days FI_JOB_RETENTION_DAYS int 7 Days to keep completed jobs. Older jobs are deleted by Database.cleanup_old_jobs() (call from a cron/scheduler).

Storage directory layout

The settings module auto-creates these directories on import:

data/
β”œβ”€β”€ face_intel.db     # SQLite database (jobs, results)
β”œβ”€β”€ audit.log         # JSONL audit trail
β”œβ”€β”€ models/           # Auto-downloaded model files (DNN Caffe, etc.)
β”œβ”€β”€ gallery/          # Known-faces reference store
β”‚   β”œβ”€β”€ manifest.json
β”‚   └── alice_0.npy   # Per-person embeddings
β”œβ”€β”€ uploads/          # Source images saved by ArtifactStore
└── generated/        # Annotated images, montages

Example: production paths

FI_DB_PATH=/var/lib/face-intel/face_intel.db
FI_AUDIT_LOG_PATH=/var/log/face-intel/audit.log
FI_JOB_RETENTION_DAYS=30

Example: tests (in-memory)

make_settings(db_path=":memory:")

13. API

Setting Env var Type Default Description
rate_limit_per_minute FI_RATE_LIMIT_PER_MINUTE int 30 Max requests per client IP per 60s sliding window. /health/* is excluded.
cors_origins FI_CORS_ORIGINS list[str] ["*"] Allowed CORS origins. Comma-separated in env: FI_CORS_ORIGINS=["https://app.example.com","https://admin.example.com"].
require_consent_header FI_REQUIRE_CONSENT_HEADER bool True Whether consent is required (currently informational β€” enforce at your gateway).
consent_header_name FI_CONSENT_HEADER_NAME str "X-Consent-Statement" Header name to look for.
max_image_bytes FI_MAX_IMAGE_BYTES int 20971520 (20 MB) Max decoded image size, enforced by InputValidator.
job_timeout_seconds FI_JOB_TIMEOUT_SECONDS float 300.0 Overall job timeout. A job exceeding this is marked timeout.
max_request_body_bytes FI_MAX_REQUEST_BODY_BYTES int 26214400 (25 MB) Hard HTTP body cap. Returns 413 if exceeded.

Example: locked-down production

FI_RATE_LIMIT_PER_MINUTE=120
FI_CORS_ORIGINS=["https://app.example.com"]
FI_REQUIRE_CONSENT_HEADER=true
FI_MAX_IMAGE_BYTES=10485760
FI_JOB_TIMEOUT_SECONDS=60
FI_MAX_REQUEST_BODY_BYTES=12582912

Example: permissive development

FI_RATE_LIMIT_PER_MINUTE=10000
FI_CORS_ORIGINS=["*"]
FI_REQUIRE_CONSENT_HEADER=false
FI_DEBUG=true

14. New-Capability Enable Flags

These enable flags cover the non-detection/recognition capabilities added in Phase 4+.

Setting Env var Type Default Capability
enable_image_quality FI_ENABLE_IMAGE_QUALITY bool True image_analysis
enable_image_properties FI_ENABLE_IMAGE_PROPERTIES bool True image_analysis
enable_visual_features FI_ENABLE_VISUAL_FEATURES bool False image_analysis
enable_exif FI_ENABLE_EXIF bool True metadata
enable_xmp FI_ENABLE_XMP bool False metadata
enable_image_integrity FI_ENABLE_IMAGE_INTEGRITY bool True forensics
enable_duplicate_detector FI_ENABLE_DUPLICATE_DETECTOR bool True forensics
enable_manipulation_analyzer FI_ENABLE_MANIPULATION_ANALYZER bool False forensics

15. Logging

Setting Env var Type Default Description
log_level FI_LOG_LEVEL str "INFO" Loguru level: TRACE, DEBUG, INFO, WARNING, ERROR, CRITICAL.
log_json FI_LOG_JSON bool False Emit newline-delimited JSON for log aggregators (Loki, Datadog, CloudWatch).

Log format

Default (human-readable):

2026-07-10 14:30:00.123 | INFO     | eid=abc123def456 | pid=haar | retry=0 | status=started | invoking haar

JSON mode (FI_LOG_JSON=true):

{"timestamp":"2026-07-10T14:30:00.123Z","level":"INFO","execution_id":"abc123def456","provider_id":"haar","retry_count":0,"status":"started","message":"invoking haar"}

Every log line inside an execution carries eid (execution id), pid (provider id), retry, and status fields. See docs/ARCHITECTURE.md Β§7 for details.

Example: production JSON logging

FI_LOG_LEVEL=INFO
FI_LOG_JSON=true

Example: debug verbosity

FI_LOG_LEVEL=DEBUG
FI_LOG_JSON=false

16. How to Enable/Disable Providers

Workflow

  1. Edit .env (or set the env var directly).
  2. Set FI_ENABLE_<NAME>=true (or false).
  3. Restart the server.
  4. Verify via GET /providers.

Example: enable dnn + mtcnn, disable haar

FI_ENABLE_HAAR=false
FI_ENABLE_DNN=true
FI_ENABLE_MTCNN=true

Restart and check:

curl -s http://localhost:8000/providers | jq '.providers[] | {name, status}'

What "disabled" vs "not_configured" means

Status Cause
disabled enable_<name> = False in settings. The provider class is never even imported.
not_configured enable_<name> = True but the optional dependency is missing OR is_available() returned False (e.g. API key not set).
healthy Enabled, instantiated, is_available() == True.

Disabling vs uninstalling

Disabling a provider via enable_<name>=False is enough β€” the provider class won't be imported, so even broken optional dependencies won't break startup. You don't need to uninstall the package.


17. How to Configure API Keys

SerpAPI (Google Reverse Image Search)

  1. Sign up at https://serpapi.com/.
  2. Get your API key from the dashboard.
  3. Set in .env:
FI_ENABLE_SERPAPI=true
FI_SERPAPI_KEY=your_key_here
  1. Restart and verify:
curl -s http://localhost:8000/providers/serpapi | jq '.available'
# β†’ true

Bing Image Search API

  1. Provision a Bing Search v7 resource in Azure.
  2. Get the API key from "Keys and Endpoint".
  3. Set in .env:
FI_ENABLE_BING_SCRAPER=true
FI_BING_API_KEY=your_key_here

TinEye (OAuth)

TinEye uses public/private keypair authentication.

  1. Sign up at https://tineye.com/developers.
  2. Generate a keypair.
  3. Set in .env:
FI_ENABLE_TINEYE=true
FI_TINEYE_PUBLIC_KEY=your_public_key
FI_TINEYE_PRIVATE_KEY=your_private_key

Secret management

For production, do not store API keys in .env. Use your orchestrator's secret store:

  • Kubernetes: Secret mounted as env vars.
  • AWS: Secrets Manager + entrypoint script that fetches and exports.
  • HashiCorp Vault: vault kv get in the entrypoint.

The platform reads keys from env vars only β€” it doesn't care how they got there.


18. Production vs Development

Development profile

.env.dev:

FI_ENVIRONMENT=development
FI_DEBUG=true
FI_LOG_LEVEL=DEBUG
FI_LOG_JSON=false
FI_RATE_LIMIT_PER_MINUTE=10000
FI_CORS_ORIGINS=["*"]
FI_REQUIRE_CONSENT_HEADER=false
FI_CACHE_ENABLED=false
FI_DB_PATH=data/face_intel.dev.db

# Enable most providers for testing
FI_ENABLE_HAAR=true
FI_ENABLE_DNN=true
FI_ENABLE_MTCNN=true
FI_ENABLE_FACE_RECOGNITION=true
FI_ENABLE_BEAUTIFULSOUP_SCRAPER=true
FI_ENABLE_SELENIUM_SCRAPER=true
FI_ENABLE_DUCKDUCKGO_SCRAPER=true
FI_ENABLE_GOOGLE_LENS=true
FI_ENABLE_IMAGE_QUALITY=true
FI_ENABLE_IMAGE_PROPERTIES=true
FI_ENABLE_EXIF=true
FI_ENABLE_IMAGE_INTEGRITY=true
FI_ENABLE_DUPLICATE_DETECTOR=true

# Disable paid/heavy providers
FI_ENABLE_RETINAFACE=false
FI_ENABLE_DEEPFACE=false
FI_ENABLE_INSIGHTFACE=false
FI_ENABLE_BING_SCRAPER=false
FI_ENABLE_SERPAPI=false
FI_ENABLE_YANDEX=false
FI_ENABLE_TINEYE=false
FI_ENABLE_VISUAL_FEATURES=false
FI_ENABLE_XMP=false
FI_ENABLE_MANIPULATION_ANALYZER=false

Run with:

cp .env.dev .env
python app.py

Production profile

.env.prod:

FI_ENVIRONMENT=production
FI_DEBUG=false
FI_LOG_LEVEL=INFO
FI_LOG_JSON=true
FI_RATE_LIMIT_PER_MINUTE=120
FI_CORS_ORIGINS=["https://app.example.com"]
FI_REQUIRE_CONSENT_HEADER=true
FI_CACHE_ENABLED=true
FI_CACHE_TTL_SECONDS=86400
FI_CACHE_MAX_ENTRIES=10000
FI_DB_PATH=/var/lib/face-intel/face_intel.db
FI_AUDIT_LOG_PATH=/var/log/face-intel/audit.log
FI_JOB_RETENTION_DAYS=30
FI_JOB_TIMEOUT_SECONDS=120
FI_MAX_IMAGE_BYTES=10485760
FI_MAX_REQUEST_BODY_BYTES=12582912

# Circuit breaker β€” aggressive failover
FI_CIRCUIT_BREAKER_FAILURE_THRESHOLD=3
FI_CIRCUIT_BREAKER_RECOVERY_SECONDS=60

# Orchestrator
FI_ORCHESTRATOR_TIMEOUT_SECONDS=60
FI_ORCHESTRATOR_MAX_CONCURRENCY=16
FI_RETRY_MAX_ATTEMPTS=3
FI_RETRY_INITIAL_BACKOFF_SECONDS=1.0
FI_RETRY_MAX_BACKOFF_SECONDS=15.0

# Providers β€” only the ones you've validated
FI_ENABLE_HAAR=true
FI_ENABLE_DNN=true
FI_ENABLE_FACE_RECOGNITION=true
FI_ENABLE_IMAGE_QUALITY=true
FI_ENABLE_IMAGE_PROPERTIES=true
FI_ENABLE_EXIF=true
FI_ENABLE_IMAGE_INTEGRITY=true
FI_ENABLE_DUPLICATE_DETECTOR=true

# Disable everything else
FI_ENABLE_MTCNN=false
FI_ENABLE_RETINAFACE=false
FI_ENABLE_DEEPFACE=false
FI_ENABLE_INSIGHTFACE=false
FI_ENABLE_BEAUTIFULSOUP_SCRAPER=false
FI_ENABLE_SELENIUM_SCRAPER=false
FI_ENABLE_BING_SCRAPER=false
FI_ENABLE_DUCKDUCKGO_SCRAPER=false
FI_ENABLE_GOOGLE_LENS=false
FI_ENABLE_SERPAPI=false
FI_ENABLE_YANDEX=false
FI_ENABLE_TINEYE=false
FI_ENABLE_VISUAL_FEATURES=false
FI_ENABLE_XMP=false
FI_ENABLE_MANIPULATION_ANALYZER=false

Test profile (used by tests/conftest.py)

Settings(
    environment="test",
    enable_dnn=False,
    enable_mtcnn=False,
    # ... all optional providers disabled ...
    enable_visual_features=False,
    enable_xmp=False,
    enable_manipulation_analyzer=False,
    db_path=":memory:",
    cache_enabled=False,
    rate_limit_per_minute=10000,
)

This keeps tests fast and deterministic β€” only pure-OpenCV providers (haar, image_quality, image_properties, exif, image_integrity, duplicate_detector) are enabled.


19. Verifying Your Configuration

1. Check the loaded settings

python -c "from config.settings import settings; print(settings.model_dump_json(indent=2))"

2. Check provider status

curl -s http://localhost:8000/providers | jq '.providers[] | {name, status, available}'

Expected output:

{"name": "haar", "status": "healthy", "available": true}
{"name": "dnn", "status": "healthy", "available": true}
{"name": "retinaface", "status": "disabled", "available": false}
{"name": "insightface", "status": "not_configured", "available": false}

3. Check manifest errors

curl -s http://localhost:8000/providers | jq '.errors'

If errors is non-empty, those providers failed to instantiate (e.g. missing optional dependency):

{
  "insightface": "missing dependency: No module named 'insightface'"
}

4. Check health

curl -s http://localhost:8000/health/providers | jq '.status'
# β†’ "healthy" or "degraded"

5. Check stats

curl -s http://localhost:8000/stats | jq '.counters'

See Also