faceauhuissier / app.py
roystraque's picture
Update app.py
ed169af verified
import gradio as gr
import requests
from PIL import Image
import io
import base64
import os
import shutil
import uuid
from openai import OpenAI
# Récupérer le token depuis les secrets
HF_TOKEN = os.getenv("HF_TOKEN")
# Client OpenAI compatible avec Hugging Face
client = OpenAI(
base_url="https://router.huggingface.co/v1",
api_key=HF_TOKEN,
)
def nettoyer_temp():
"""Supprime les fichiers temporaires"""
temp_dir = "/tmp"
if os.path.exists(temp_dir):
for filename in os.listdir(temp_dir):
file_path = os.path.join(temp_dir, filename)
try:
if os.path.isfile(file_path) or os.path.islink(file_path):
os.unlink(file_path)
elif os.path.isdir(file_path):
shutil.rmtree(file_path)
except Exception:
pass
# PROMPT SYSTÈME ULTRA-PRÉCIS POUR ANALYSE COMPLÈTE
PROMPT_SYSTEME = """
Tu es un expert en procédures civiles d'exécution, spécialiste du Code des procédures civiles d'exécution (CPCE) et du Code de procédure civile (CPC).
Ta mission est d'analyser l'acte d'huissier/commissaire de justice avec une précision absolue pour détecter TOUTE irrégularité qui pourrait entraîner la nullité de l'acte ou la caducité de la saisie.
================================================================================
📌 1. IDENTIFICATION DU DOCUMENT
================================================================================
Détermine avec précision le type d'acte parmi :
- Commandement de payer (Art. L211-1 CPCE)
- Saisie-attribution (compte bancaire - Art. L211-1 CPCE)
- Saisie-vente (Art. L221-1 CPCE)
- Saisie sur rémunération (Art. L3252-1 Code travail)
- Saisie immobilière (Art. L311-1 CPCE)
- Saisie conservatoire (Art. L511-1 CPCE)
- Signification de jugement (Art. 651 CPC)
- Avis de passage / sommation (Art. 656 CPC)
- Procès-verbal de constat
- Dénonciation de saisie
================================================================================
📋 2. VÉRIFICATION DES MENTIONS OBLIGATOIRES (Art. 648 CPC)
================================================================================
Pour CHAQUE mention, indique : ✅ PRÉSENTE / ❌ ABSENTE / ⚠️ PARTIELLEMENT
**2.1 DATE DE L'ACTE** (jour/mois/année) : [statut et valeur]
**2.2 IDENTITÉ DU CRÉANCIER** :
- Nom / raison sociale : [statut et valeur]
- Adresse complète : [statut et valeur]
- SIRET / RCS (si personne morale) : [statut et valeur]
**2.3 IDENTITÉ DU DÉBITEUR (VOUS)** :
- Nom et prénom / raison sociale : [statut et valeur]
- Adresse complète : [statut et valeur]
**2.4 IDENTITÉ DU COMMISSAIRE DE JUSTICE (HUISSIER)** :
- Nom et prénom : [statut et valeur]
- Adresse professionnelle : [statut et valeur]
- Mention de la chambre départementale : [statut]
**2.5 SIGNATURE** :
- Signature manuscrite ou électronique : [PRÉSENTE / ABSENTE / ILLISIBLE]
- Nom imprimé du signataire : [statut]
================================================================================
📅 3. VÉRIFICATION DES DATES (CPCE et CPC)
================================================================================
**3.1 DATE DE L'ACTE** : [date exacte]
**3.2 DATE DE SIGNIFICATION** (bas de l'acte) : [date exacte]
**3.3 DÉLAI DE CADUCITÉ (Art. R211-3 CPCE) - Pour saisie-attribution** :
- Date de l'acte de saisie (PV banque) : [date ou NA]
- Date de dénonciation au débiteur : [date ou NA]
- Écart en jours : [X jours]
- SI ÉCART > 8 JOURS : **CADUCITÉ DE PLEIN DROIT**
**3.4 DATE DU TITRE EXÉCUTOIRE** :
- Date du jugement/ordonnance/contrainte : [date]
- Âge du titre : [X] ans
- SI > 10 ANS : **PRESCRIPTION ACQUISE (Art. L111-4 CPCE)**
**3.5 DÉLAI DE COMMANDEMENT (Art. L211-1 CPCE)** :
- Date du commandement : [date]
- Délai écoulé : [X] jours
- SI > 8 JOURS sans paiement : saisie possible
================================================================================
👤 4. VÉRIFICATION DES IDENTITÉS ET COMPÉTENCES
================================================================================
**4.1 COMPÉTENCE TERRITORIALE (Art. R121-1 CPCE)** :
- État d'huissier situé dans le ressort de la cour d'appel du domicile ? [OUI/NON]
- SI NON : **IRRÉGULARITÉ DE COMPÉTENCE**
**4.2 CAPACITÉ DU CRÉANCIER** :
- Le créancier est-il clairement identifié ? [OUI/NON]
- Existe-t-il un mandat ou une représentation ? [détail]
**4.3 QUALITÉ DU SIGNATAIRE** :
- L'acte précise-t-il le nom du clerc ou de l'huissier signataire ? [OUI/NON]
================================================================================
💰 5. VÉRIFICATION DES MONTANTS (Art. A444-15 C. com.)
================================================================================
**5.1 MONTANT PRINCIPAL** :
- Montant : [€]
- Correspond au titre exécutoire ? [OUI/NON]
**5.2 INTÉRÊTS** :
- Taux appliqué : [%]
- Période de calcul : [début → fin]
- Calcul conforme ? [OUI/NON]
**5.3 FRAIS D'HUISSIER** :
- Détail des frais : [lister chaque acte et montant]
- **SAISIE INFRUCTUEUSE** (Art. A444-15) :
- Y a-t-il une saisie sur compte inexistant/clôturé ? [OUI/NON]
- SI OUI ET FRAIS FACTURÉS : **ILLÉGAL → REMBOURSEMENT OBLIGATOIRE**
**5.4 TOTAL RÉCLAMÉ** :
- Montant total : [€]
- Cohérence du calcul : [OUI/NON]
================================================================================
📬 6. VÉRIFICATION DE LA SIGNIFICATION (Art. 654-659 CPC)
================================================================================
**6.1 MODE DE REMISE** :
- [ ] Remis en mains propres
- [ ] Remis à domicile (à une personne présente)
- [ ] Déposé à l'étude (après passage)
- [ ] Signifié par voie électronique
**6.2 SI REMIS À UNE PERSONNE** :
- Nom et prénom de la personne : [détail]
- Qualité (conjoint, voisin, gardien...) : [détail]
- Ces mentions figurent-elles dans l'acte ? [OUI/NON]
**6.3 SI DÉPOSÉ À L'ÉTUDE** :
- Avis de passage laissé ? [OUI/NON]
- Lettre simple envoyée ? [OUI/NON]
- SI NON : **IRRÉGULARITÉ DE SIGNIFICATION**
**6.4 SI VOIE ÉLECTRONIQUE** :
- Consentement explicite du destinataire ? [OUI/NON]
- SI NON : **NULLITÉ DE LA SIGNIFICATION**
================================================================================
🚨 7. LISTE EXHAUSTIVE DES MENTIONS MANQUANTES
================================================================================
[Énumérer CHAQUE élément obligatoire qui est ABSENT ou INCOMPLET dans l'acte]
Exemple :
❌ Date de l'acte manquante (Art. 648 CPC)
❌ Identité du créancier incomplète (adresse absente) (Art. 648 CPC)
❌ Signature absente (Art. 648 CPC)
❌ Date de signification non indiquée (Art. 654 CPC)
================================================================================
⚡ 8. CADUCITÉS ET NULLITÉS DÉTECTÉES
================================================================================
| Type d'irrégularité | Article | Constat | Conséquence juridique |
|---------------------|---------|--------|----------------------|
| Caducité (délai 8j) | R211-3 CPCE | [OUI/NON - détail] | Annulation de la saisie |
| Nullité de forme | 648 CPC | [OUI/NON - mentions manquantes] | Annulation de l'acte |
| Nullité de fond | L111-4 CPCE | [OUI/NON - prescription] | Prescription du titre |
| Frais indus | A444-15 C. com. | [OUI/NON - montant] | Remboursement forcé |
| Signification irrégulière | 654-659 CPC | [OUI/NON - détail] | Nullité de l'acte |
| Incompétence territoriale | R121-1 CPCE | [OUI/NON - détail] | Nullité de la procédure |
================================================================================
📜 9. ARTICLES DE LOI APPLICABLES POUR LA CONTESTATION
================================================================================
[Lister TOUS les articles pertinents avec leur texte exact]
Exemple :
- Art. 648 CPC : "Tout acte d'huissier de justice indique... à peine de nullité"
- Art. R211-3 CPCE : "La saisie-attribution est dénoncée au débiteur dans les huit jours, à peine de caducité"
- Art. A444-15 C. com. : "Le droit d'engagement de poursuite n'est pas dû lorsque la saisie est infructueuse"
================================================================================
📝 10. TEXTE PRÊT POUR L'AVOCAT (À COPIER-COLLER)
================================================================================
[Rédige un texte juridique concis et complet avec TOUS les arguments, citations d'articles, et demandes à formuler]
================================================================================
🎯 11. PLAN D'ACTION DEVANT LE JEX
================================================================================
**Délai de contestation** : 1 mois après signification (date limite : [calculée])
**Juridiction compétente** : Juge de l'exécution (JEX) du tribunal judiciaire de [ville]
**Demandes à formuler (cochez ce qui s'applique) :**
☐ Annulation de l'acte pour nullité de forme (Art. 648 CPC)
☐ Constat de caducité de la saisie (Art. R211-3 CPCE)
☐ Mainlevée de la saisie
☐ Remboursement des frais indus (montant : [€])
☐ Sursis à exécution
☐ Délais de grâce (Art. 1343-5 Code civil)
☐ Dommages et intérêts pour procédure abusive
**Pièces à joindre :**
☐ Copie de l'acte contesté
☐ Décompte des sommes
☐ Preuve de réception du recommandé
☐ Relevés bancaires (pour insaisissabilité)
☐ Correspondance avec l'étude
================================================================================
🏛️ 12. CONCLUSION
================================================================================
- **IRRÉGULARITÉS MAJEURES DÉTECTÉES** : [oui/non - lesquelles]
- **DÉFENDABILITÉ** : [EXCELLENTE / BONNE / MOYENNE / FAIBLE]
- **PROBABILITÉ D'ANNULATION** : [100% / 75% / 50% / 25% / 0%]
- **ARGUMENTS PRINCIPAUX** : [les 3 arguments les plus forts]
- **PROCHAINES ÉTAPES** : [actions concrètes à entreprendre]
"""
def encoder_image_en_base64(image):
"""Convertit une image PIL en base64"""
buffered = io.BytesIO()
image.save(buffered, format="JPEG")
return base64.b64encode(buffered.getvalue()).decode()
def analyser_image(image):
if HF_TOKEN is None:
return """❌ **ERREUR DE CONFIGURATION**
Le token Hugging Face n'est pas défini dans les secrets du Space.
🔧 **SOLUTION :**
1. Allez dans l'onglet **Settings** de votre Space
2. Descendez jusqu'à **Secrets and variables**
3. Cliquez sur **New secret**
4. **Name** : `HF_TOKEN`
5. **Value** : collez votre token (commence par `hf_`)
6. Cliquez sur **Save**
Après avoir ajouté le secret, le Space redémarrera automatiquement."""
try:
nettoyer_temp()
# Encoder l'image en base64
img_base64 = encoder_image_en_base64(image)
# Appel à l'API
completion = client.chat.completions.create(
model="zai-org/GLM-4.5V",
messages=[
{
"role": "system",
"content": "Tu es un expert juridique spécialisé en procédures civiles d'exécution. Analyse avec une précision absolue. Cite les articles de loi exacts. Structure ta réponse selon les 12 sections ci-dessous."
},
{
"role": "user",
"content": [
{
"type": "text",
"text": PROMPT_SYSTEME + "\n\nAnalyse cet acte d'huissier avec la plus grande précision. SOIS EXTRÊMEMENT DÉTAILLÉ. Détecte TOUTE anomalie, même mineure. Cite les articles de loi exacts pour chaque irrégularité :"
},
{
"type": "image_url",
"image_url": {
"url": f"data:image/jpeg;base64,{img_base64}"
}
}
]
}
],
max_tokens=6000,
temperature=0.05
)
# Extraire la réponse
content = completion.choices[0].message.content
if content and len(content) > 100:
return content
return f"⚠️ **ANALYSE INCOMPLÈTE**\n\n{content[:500] if content else 'Aucun contenu généré'}"
except Exception as e:
error_msg = str(e)
if "model_not_supported" in error_msg:
return """❌ **MODÈLE NON DISPONIBLE**
Le modèle 'zai-org/GLM-4.5V' n'est pas accessible.
**Modèles alternatifs :**
- `meta-llama/Llama-4-Maverick-17B-128E-Instruct:sambanova`
- `Qwen/Qwen2.5-7B-Instruct-1M`
- `deepseek-ai/DeepSeek-R1`
Pour changer le modèle, modifiez la ligne `model` dans le code."""
if "authentication" in error_msg.lower() or "401" in error_msg:
return "❌ **ERREUR D'AUTHENTIFICATION**\n\nLe token n'est pas valide. Vérifiez votre secret HF_TOKEN."
return f"❌ **ERREUR TECHNIQUE**\n\n{error_msg}"
finally:
nettoyer_temp()
# CSS
css = """
.gradio-container {
max-width: 1400px !important;
margin: 0 auto !important;
}
#result {
font-family: 'Inter', monospace;
line-height: 1.6;
background: #fef9e6;
padding: 20px;
border-radius: 12px;
border-left: 4px solid #e67e22;
color: #1a1a1a !important;
}
#result * {
color: #1a1a1a !important;
}
#result h1, #result h2, #result h3, #result h4 {
color: #2c3e50 !important;
}
#result strong, #result b {
color: #2c3e50 !important;
}
#result table {
background: white !important;
border-collapse: collapse;
width: 100%;
}
#result th, #result td {
border: 1px solid #ddd;
padding: 8px;
text-align: left;
}
#result th {
background: #2c3e50 !important;
color: white !important;
}
.print-btn {
background: #e67e22;
color: white;
border: none;
padding: 8px 20px;
border-radius: 6px;
cursor: pointer;
font-size: 14px;
font-weight: 500;
margin-bottom: 10px;
transition: background 0.2s;
}
.print-btn:hover {
background: #d35400;
}
@media print {
body * {
visibility: hidden;
}
#result, #result * {
visibility: visible;
}
#result {
position: absolute;
top: 0;
left: 0;
width: 100%;
margin: 0;
padding: 20px;
background: white !important;
color: black !important;
}
button, .btn, .gr-button, .print-btn {
display: none !important;
}
}
"""
with gr.Blocks(title="Analyseur d'acte d'huissier", theme=gr.themes.Soft(), css=css) as demo:
# En-tête stylisé
gr.HTML("""
<div style="text-align: center; margin-bottom: 25px; padding: 20px; background: linear-gradient(135deg, #2c3e50 0%, #1a252f 100%); border-radius: 16px;">
<h1 style="font-size: 2.2em; color: #ffffff; margin: 0; font-weight: 700;">⚖️ ANALYSEUR JURIDIQUE</h1>
<h1 style="font-size: 1.8em; color: #e67e22; margin: 5px 0 0 0; font-weight: 600;">D'ACTE D'HUISSIER</h1>
<p style="color: #bdc3c7; font-size: 1em; margin-top: 12px;">
📸 Importez une photo ou un scan d'un acte d'huissier<br>
🔍 Obtenez une analyse juridique complète prête pour votre avocat
</p>
<div style="background: #e67e22; width: 80px; height: 3px; margin: 15px auto 0 auto; border-radius: 2px;"></div>
</div>
""")
with gr.Row():
with gr.Column(scale=1):
image_input = gr.Image(type="pil", label="📸 IMPORTEZ L'ACTE", height=500)
analyze_btn = gr.Button("🔍 ANALYSER L'ACTE", variant="primary", size="lg")
clear_btn = gr.Button("🗑️ EFFACER", variant="secondary", size="sm")
gr.HTML("""
<div style="background: #f8f9fa; padding: 15px; border-radius: 12px; margin-top: 20px; border: 1px solid #e0e0e0;">
<h4 style="color: #2c3e50; margin-top: 0;">📌 FORMAT ACCEPTÉ</h4>
<p style="color: #2c3e50;">Images : PNG, JPG, JPEG</p>
<h4 style="color: #2c3e50; margin-top: 12px;">⚡ CONSEILS</h4>
<ul style="color: #2c3e50; margin: 0; padding-left: 20px;">
<li style="color: #2c3e50;">Photographiez l'acte en entier</li>
<li style="color: #2c3e50;">Assurez une bonne luminosité</li>
<li style="color: #2c3e50;">Cadrez les mentions en bas (signature, date)</li>
</ul>
<h4 style="color: #2c3e50; margin-top: 12px;">🛡️ CONFIDENTIALITÉ</h4>
<p style="color: #2c3e50;">Aucune donnée conservée après analyse.</p>
</div>
""")
with gr.Column(scale=2):
print_btn = gr.Button("🖨️ IMPRIMER LE RÉSULTAT", elem_classes="print-btn", variant="secondary", size="sm")
with gr.Accordion("📋 RÉSULTAT COMPLET DE L'ANALYSE", open=True):
output = gr.Markdown(
"✨ **RÉSULTAT**\n\nL'analyse apparaîtra ici après avoir importé une image.",
elem_id="result"
)
analyze_btn.click(fn=analyser_image, inputs=image_input, outputs=output)
def effacer():
nettoyer_temp()
return None, "✨ **RÉSULTAT**\n\nL'analyse a été effacée. Importez une nouvelle image."
clear_btn.click(fn=effacer, outputs=[image_input, output])
def imprimer():
return """
<script>
window.print();
</script>
"""
print_btn.click(fn=imprimer, inputs=[], outputs=[])
demo.launch(server_name="0.0.0.0", server_port=7860)