flowchart LR
A[Client / Frontend] -->|POST /api/v1/kyc/process| B[FastAPI Router]
B --> C[KYCAgent.process]
C --> D[OpenRouter Vision]
C --> E[InsightFace]
C --> F[OCR Engine]
C --> G[Mailtrap]
C --> H[KYC Callback]
D -->|Analyse texte document| C
E -->|Comparaison visage profil vs document| C
F -->|Extraction images| C
C -->|Mail si champs invalides| G
C -->|POST callback| H
C -->|Réponse JSON| B
B -->|200 + KYCOutputResponse| A
- Réception : La route
POST /api/v1/kyc/processreçoit un formulairemultipart/form-datacontenant les champs textuels et les fichiers images. - Extraction images : Les octets des fichiers sont extraits via
ocr_engine. - Analyse document (OpenRouter Vision) : Les images du document (CNI recto/verso ou passeport) sont envoyées au modèle
meta-llama/llama-4-scoutqui vérifie la cohérence des champs textuels déclarés. - Reconnaissance faciale (InsightFace) : Le
photo_profileest comparé à la photo du document viabuffalo_l+ cosine similarity. Si les visages ne correspondent pas,photo_profileest marquéinvalid. - Validation locale : Les champs
date_naissance,date_expiration,sexe,num_CNI_passeportetnom_et_prenomsont validés localement (format, bornes, valeurs autorisées). - Calcul du score :
total_percentagecommence à 100. Chaque champ invalide dans les champs à pénalité retire sa pénalité.state_statusestvalideuniquement sitotal_percentage >= 60. - Notification email : Si des champs sont invalides, un email de type
warningest envoyé via Mailtrap avec les raisons d'invalidité. - Callback HTTP : Un
POSTest envoyé àKYC_CALLBACK_URLavec le score et la raison du rejet. - Réponse : Retour d'un objet
KYCOutputResponseavec le statut par champ, le score global et la description des champs invalides.
| Composant | Technologie | Rôle |
|---|---|---|
| API | FastAPI + Uvicorn | Route principale, validation Pydantic |
| IA / Vision | OpenRouter API (meta-llama/llama-4-scout) |
Analyse OCR et validation des champs textuels |
| Reconnaissance faciale | InsightFace (buffalo_l, ONNX Runtime) |
Comparaison photo_profile vs photo document |
| Mailtrap (SMTP) | Notification des champs invalides | |
| Callback | httpx | Notification du service appelant |
| Images | Pillow + OpenCV | Traitement et décodage des images |
| Conteneurisation | Docker + Docker Compose | Build et run de l'API |
| Tests | pytest + pytest-asyncio | Tests unitaires et d'intégration |
| Auth | JWT (PyJWT) | Protection de la route /api/v1/kyc/process |
- OpenRouter Vision :
meta-llama/llama-4-scout,temperature=0.0 - InsightFace : modèle
buffalo_l, seuil de similarité cosinus >=0.40par défaut - Score global : commence à 100, pénalités par champ invalide, seuil de validité à 60
- Tesseract : non utilisé dans le pipeline final (seul OpenRouter Vision valide les textes)
- JWT : algorithme
HS256, expiration configurable viaJWT_EXPIRE_MINUTES(False,0ou chaîne vide = pas d'expiration)
- Python 3.12+
- Docker & Docker Compose
- Clé API OpenRouter (
OPENROUTER_API_KEY) - Compte Mailtrap (SMTP)
- (Optionnel) GPU NVIDIA pour InsightFace sinon CPU
git clone <repo-url>
cd kyc-validation-pipelinepython3 -m venv .venv
source .venv/bin/activatepip install -r requirements.txtCopier .env.example en .env et remplir les valeurs :
cp .env.example .envVariables obligatoires :
OPENROUTER_API_KEY=...
SMTP_HOST=sandbox.smtp.mailtrap.io
SMTP_PORT=2525
SMTP_USER=...
SMTP_PASSWORD=...
EMAIL_FROM=...
KYC_CALLBACK_URL=...
KYC_CALLBACK_TOKEN=...
JWT_SECRET_KEY=...
JWT_EXPIRE_MINUTES=60Pour générer des tokens sans expiration :
JWT_EXPIRE_MINUTES=FalseVariables optionnelles InsightFace :
INSIGHTFACE_MODEL=buffalo_l
INSIGHTFACE_PROVIDERS=CPUExecutionProvider
INSIGHTFACE_THRESHOLD=0.40
INSIGHTFACE_CTX_ID=-1uvicorn app.main:app --host 0.0.0.0 --port 8000 --reloadL'API est accessible sur http://localhost:8000.
La route /api/v1/kyc/process est protégée par JWT.
Générer un token avec la clé définie dans .env (JWT_SECRET_KEY) :
python3 -c "import jwt; print(jwt.encode({'sub':'user-123'}, '<JWT_SECRET_KEY>', algorithm='HS256'))"Puis l’utiliser dans le header :
Authorization: Bearer <token>
curl http://localhost:8000/healthLancer tous les tests :
pytest tests/ -vLancer un fichier de tests spécifique :
pytest tests/test_agent.py -v
pytest tests/test_api.py -v
pytest tests/test_validation.py -vLancer les tests avec couverture :
pytest tests/ -v --cov=app --cov-report=term-missingdocker compose builddocker compose up -ddocker compose ps
docker logs kyc-validation-apicurl http://localhost:8000/healthdocker compose down- Le premier lancement télécharge les modèles InsightFace (~280 MB) dans
.insightface/. - Le répertoire
.insightface/est exclu de git via.gitignore. - Le port exposé est
8000.
Voir docs/integration.md pour le détail de l'endpoint /api/v1/kyc/process (requête, réponse, codes d'erreur, exemples).