docuresume-backend / API_ENDPOINTS_CLOUD.md
K2MAR's picture
docs: Update API documentation v2.0 - FAISS + Gemini
4929780

📡 API DocuResume Pro - Endpoints Cloud (Hugging Face)

Base URL: https://k2mar-docuresume-backend.hf.space

Version: 2.0.0
Déployé sur: Hugging Face Spaces
Status: ✅ Production
Mis à jour: 27 janvier 2026

Nouvelles fonctionnalités:

  • ✅ FAISS activé (recherche sémantique)
  • ✅ Gemini API intégrée (résumés et Q&A intelligents)
  • ✅ 22 endpoints disponibles

📚 Table des matières

  1. Authentification - Register, Login
  2. Gestion des Documents - Upload, Liste, Contenu
  3. Résumés - Sauvegarde et historique
  4. Recherche FAISS - Recherche sémantique
  5. IA Générative (Gemini) - Résumés et Q&A
  6. Analytics - Statistiques utilisateur
  7. Système - Health check

🔐 Authentification

1. POST /users/register

Créer un nouveau compte utilisateur.

Request Body:

{
  "email": "user@example.com",
  "username": "johndoe",
  "password": "securepassword123"
}

Response 200:

{
  "message": "Utilisateur créé avec succès",
  "user_id": "uuid-v4",
  "email": "user@example.com",
  "username": "johndoe"
}

Errors:

  • 400: Email ou username déjà utilisé
  • 500: Erreur serveur

Exemple cURL:

curl -X POST https://k2mar-docuresume-backend.hf.space/users/register \
  -H "Content-Type: application/json" \
  -d '{"email":"test@example.com","username":"testuser","password":"test123"}'

2. POST /users/login

Connexion utilisateur existant.

Request Body:

{
  "email": "user@example.com",
  "password": "securepassword123"
}

Response 200:

{
  "message": "Connexion réussie",
  "user_id": "uuid-v4",
  "email": "user@example.com",
  "username": "johndoe"
}

Errors:

  • 401: Email ou mot de passe incorrect
  • 500: Erreur serveur

Exemple cURL:

curl -X POST https://k2mar-docuresume-backend.hf.space/users/login \
  -H "Content-Type: application/json" \
  -d '{"email":"test@example.com","password":"test123"}'

📄 Gestion des Documents

3. POST /documents/upload

Upload un document PDF avec extraction OCR automatique.

Content-Type: multipart/form-data

Form Fields:

  • file: PDF file (required)
  • user_id: UUID de l'utilisateur (required)
  • tags: JSON array de tags (optional, default: [])
  • document_type: Type de document (optional)

Response 200:

{
  "message": "Document uploadé avec succès",
  "document_id": "uuid-v4",
  "filename": "uuid_original.pdf",
  "status": "completed",
  "pages": 5,
  "text_length": 3450,
  "faiss_indexed": false,
  "chunks": 0
}

Exemple cURL:

curl -X POST https://k2mar-docuresume-backend.hf.space/documents/upload \
  -F "file=@document.pdf" \
  -F "user_id=your-user-id" \
  -F "tags=[]"

Exemple JavaScript (Fetch):

const formData = new FormData()
formData.append('file', pdfFile)
formData.append('user_id', userId)
formData.append('tags', JSON.stringify(['important', 'work']))

const response = await fetch('https://k2mar-docuresume-backend.hf.space/documents/upload', {
  method: 'POST',
  body: formData
})
const data = await response.json()

Exemple Kotlin (Android):

val file = File(filePath)
val requestFile = file.asRequestBody("application/pdf".toMediaType())
val filePart = MultipartBody.Part.createFormData("file", file.name, requestFile)
val userIdBody = user_id.toRequestBody("text/plain".toMediaType())

val response = apiService.uploadDocument(userIdBody, filePart)

4. GET /documents/user/{user_id}

Récupérer tous les documents d'un utilisateur.

Query Parameters:

  • limit: Nombre max de documents (default: 100)
  • archived: Inclure archives (default: false)

Response 200:

{
  "documents": [
    {
      "id": "uuid-v4",
      "user_id": "uuid-v4",
      "filename": "uuid_document.pdf",
      "original_filename": "Mon Document.pdf",
      "file_size": 245780,
      "page_count": 5,
      "processing_status": "completed",
      "uploaded_at": "2026-01-27T10:30:00",
      "mime_type": "application/pdf",
      "tags": ["important"],
      "is_archived": false
    }
  ],
  "count": 1
}

Exemple cURL:

curl https://k2mar-docuresume-backend.hf.space/documents/user/YOUR_USER_ID?limit=50

5. GET /documents/{document_id}

Récupérer les détails d'un document spécifique.

Response 200:

{
  "id": "uuid-v4",
  "user_id": "uuid-v4",
  "filename": "uuid_document.pdf",
  "original_filename": "Mon Document.pdf",
  "file_path": "user_id/uuid_document.pdf",
  "file_size": 245780,
  "page_count": 5,
  "processing_status": "completed",
  "contenu": "Texte extrait du PDF...",
  "uploaded_at": "2026-01-27T10:30:00",
  "mime_type": "application/pdf",
  "tags": ["important"]
}

Exemple cURL:

curl https://k2mar-docuresume-backend.hf.space/documents/DOCUMENT_ID

6. GET /documents/{document_id}/content

Récupérer le contenu textuel extrait d'un document (pour résumé local).

Response 200:

{
  "document_id": "uuid-v4",
  "filename": "Mon Document.pdf",
  "content": "Texte extrait complet du document...",
  "page_count": 5,
  "file_size": 245780,
  "content_length": 3450
}

Usage:

  • Option 1 (Recommandé): Utiliser /generate/summary/gemini pour un résumé cloud avec Gemini API
  • Option 2: Récupérer le contenu et générer un résumé localement sur le device avec TinyLlama (si implémenté)

Exemple cURL:

curl https://k2mar-docuresume-backend.hf.space/documents/DOCUMENT_ID/content

7. GET /documents/user/{user_id}/contents

Récupérer le contenu de TOUS les documents d'un utilisateur (pour résumé global).

Query Parameters:

  • limit: Nombre max de documents (default: 100)
  • include_content: Inclure le contenu textuel (default: true)

Response 200:

{
  "user_id": "uuid-v4",
  "documents": [
    {
      "document_id": "uuid-v4",
      "filename": "Document1.pdf",
      "content": "Texte du document 1...",
      "content_length": 2340,
      "page_count": 3,
      "file_size": 156000,
      "uploaded_at": "2026-01-27T10:30:00",
      "processing_status": "completed"
    },
    {
      "document_id": "uuid-v4-2",
      "filename": "Document2.pdf",
      "content": "Texte du document 2...",
      "content_length": 3450,
      "page_count": 5,
      "file_size": 245780,
      "uploaded_at": "2026-01-27T11:00:00",
      "processing_status": "completed"
    }
  ],
  "count": 2,
  "total_content_length": 5790
}

Usage: Utiliser ce endpoint pour générer un résumé global on-device de tous les documents.

Exemple cURL:

curl https://k2mar-docuresume-backend.hf.space/documents/user/YOUR_USER_ID/contents

8. GET /documents/{document_id}/download

Télécharger le fichier PDF original.

Response: Binary PDF file with Content-Disposition: attachment

Exemple cURL:

curl -O https://k2mar-docuresume-backend.hf.space/documents/DOCUMENT_ID/download

9. PATCH /documents/{document_id}

Mettre à jour un document (tags, archived, etc.).

Request Body:

{
  "tags": ["nouveau", "tag"],
  "is_archived": true
}

Response 200:

{
  "message": "Document mis à jour",
  "document_id": "uuid-v4"
}

10. DELETE /documents/{document_id}

Supprimer un document (cascade: chunks, embeddings, summaries).

Response 200:

{
  "message": "Document supprimé",
  "document_id": "uuid-v4"
}

📝 Résumés

11. POST /documents/{document_id}/summaries

Sauvegarder un résumé généré localement sur le device.

Request Body:

{
  "content": "Résumé généré par TinyLlama...",
  "summary_type": "abstractive",
  "summary_level": "medium",
  "model_name": "TinyLlama-1.1B",
  "model_version": "Q4_K_M",
  "compression_ratio": 0.15,
  "rouge_1_score": 0.42,
  "rouge_2_score": 0.28,
  "rouge_l_score": 0.35
}

Response 200:

{
  "message": "Résumé créé avec succès",
  "summary_id": "uuid-v4",
  "document_id": "uuid-v4",
  "summary_type": "abstractive",
  "created_at": "2026-01-27T12:00:00"
}

12. POST /summaries/batch

Créer plusieurs résumés en batch (après génération locale multi-documents).

Request Body:

[
  {
    "document_id": "uuid-v4-1",
    "content": "Résumé document 1...",
    "summary_type": "abstractive",
    "model_name": "TinyLlama-1.1B"
  },
  {
    "document_id": "uuid-v4-2",
    "content": "Résumé document 2...",
    "summary_type": "abstractive",
    "model_name": "TinyLlama-1.1B"
  }
]

Response 200:

{
  "message": "2 résumés créés avec succès",
  "count": 2,
  "summary_ids": ["uuid-v4-a", "uuid-v4-b"]
}

13. GET /documents/{document_id}/summaries

Récupérer les résumés d'un document.

Query Parameters:

  • summary_type: Filtrer par type (optional: extractive, abstractive)

Response 200:

{
  "document_id": "uuid-v4",
  "summaries": [
    {
      "id": "uuid-v4",
      "document_id": "uuid-v4",
      "content": "Résumé du document...",
      "summary_type": "abstractive",
      "summary_level": "medium",
      "model_name": "TinyLlama-1.1B",
      "created_at": "2026-01-27T12:00:00",
      "compression_ratio": 0.15
    }
  ],
  "count": 1
}

14. GET /summaries/user/{user_id}

Récupérer tous les résumés d'un utilisateur.

Query Parameters:

  • limit: Nombre max de résumés (default: 50)
  • summary_type: Filtrer par type (optional)

Response 200:

{
  "user_id": "uuid-v4",
  "summaries": [
    {
      "id": "uuid-v4",
      "document_id": "uuid-v4",
      "content": "Résumé...",
      "summary_type": "abstractive",
      "documents": {
        "original_filename": "Document.pdf"
      },
      "created_at": "2026-01-27T12:00:00"
    }
  ],
  "count": 1
}

🔍 Recherche Sémantique (FAISS)

FAISS activé sur le cloud (ENABLE_FAISS=true)

15. POST /search/semantic

Recherche sémantique dans un document avec FAISS.

Query Parameters:

  • document_id (string, required): UUID du document
  • query (string, required): Texte de recherche
  • k (int, optional): Nombre de résultats (défaut: 5)

Response 200:

{
  "document_id": "555eb078-b49b-4cea-bb8a-2139358b5f42",
  "query": "invoice date",
  "results": [
    {
      "text": "Due: Dec 16, 2025...",
      "score": 0.44012526606025987,
      "chunk_id": 1
    },
    {
      "text": "GitHub Student Organization...",
      "score": 0.41195771365111133,
      "chunk_id": 0
    }
  ],
  "count": 2
}

Exemple cURL:

curl -X POST "https://k2mar-docuresume-backend.hf.space/search/semantic?document_id=555eb078-b49b-4cea-bb8a-2139358b5f42&query=invoice%20date&k=3"

16. POST /search/semantic/multi

Recherche dans tous les documents d'un utilisateur avec FAISS.

Query Parameters:

  • user_id (string, required): UUID de l'utilisateur
  • query (string, required): Texte de recherche
  • k (int, optional): Nombre de résultats (défaut: 5)

Response 200:

{
  "user_id": "07b83616-a528-4720-9fd4-dab8b2cdc4a1",
  "query": "data science",
  "results": [
    {
      "text": "Document excerpt...",
      "score": 0.35305043899364014,
      "chunk_id": 0,
      "document_id": "555eb078-b49b-4cea-bb8a-2139358b5f42"
    }
  ],
  "count": 2,
  "searched_documents": 3
}

Exemple cURL:

curl -X POST "https://k2mar-docuresume-backend.hf.space/search/semantic/multi?user_id=07b83616-a528-4720-9fd4-dab8b2cdc4a1&query=data%20science&k=5"

📊 Analytics & Stats

17. GET /analytics/user/{user_id}

Récupérer les analytics d'un utilisateur.

Response 200:

{
  "user_id": "uuid-v4",
  "analytics": {
    "user_id": "uuid-v4",
    "total_documents": 15,
    "total_queries": 42,
    "total_summaries": 12,
    "storage_used_mb": 25.5,
    "last_activity": "2026-01-27T12:00:00"
  }
}

18. GET /stats/global

Statistiques globales de la plateforme.

Response 200:

{
  "total_users": 127,
  "total_documents": 543,
  "total_queries": 1845,
  "timestamp": "2026-01-27T12:00:00"
}

🩺 Système

19. GET /

Point d'entrée de l'API.

Response 200:

{
  "service": "DocuResume Pro API",
  "version": "1.0.0",
  "status": "running",
  "supabase_connected": true
}

Exemple cURL:

curl https://k2mar-docuresume-backend.hf.space/

20. GET /health

Health check de l'API et de la base de données.

Response 200:

{
  "status": "healthy",
  "database": "connected",
  "timestamp": "2026-01-27T12:00:00"
}

Exemple cURL:

curl https://k2mar-docuresume-backend.hf.space/health

🚀 Workflow Complet (Exemple Android/Mobile)

Étape 1: Inscription

POST /users/register
Body: { email, username, password }
→ Obtenir user_id

Étape 2: Upload de documents

POST /documents/upload
Form-data: { file, user_id }
→ Obtenir document_id

Étape 3: Récupérer le contenu

GET /documents/{document_id}/content
→ Obtenir content (texte extrait)

Étape 4: Générer résumé avec Gemini (Cloud)

POST /generate/summary/gemini?document_id={id}&max_length=100
→ Obtenir summary généré par IA

Étape 5: Poser une question sur le document

POST /query/gemini?document_id={id}&question=Quel%20est%20le%20sujet%3F
→ Obtenir answer contextuelle

Étape 6: Recherche sémantique (FAISS)

POST /search/semantic?document_id={id}&query=montant&k=5
→ Trouver passages pertinents


🤖 IA Générative (Gemini API)

21. POST /generate/summary/gemini

Génère un résumé intelligent avec Google Gemini.

Query Parameters:

  • document_id (string, required): UUID du document
  • max_length (int, optional): Longueur max en mots (défaut: 150)

Response 200:

{
  "document_id": "555eb078-b49b-4cea-bb8a-2139358b5f42",
  "summary": "Cette facture d'Appwrite confirme un montant de 0,00 $ pour le forfait GitHub Student Pack...",
  "length": 47,
  "method": "gemini-pro"
}

Errors:

  • 404: Document non trouvé
  • 400: Document vide
  • 429: Quota Gemini dépassé
  • 500: Erreur API Gemini

Exemple cURL:

curl -X POST "https://k2mar-docuresume-backend.hf.space/generate/summary/gemini?document_id=555eb078-b49b-4cea-bb8a-2139358b5f42&max_length=60"

Exemple Kotlin:

@POST("generate/summary/gemini")
suspend fun generateSummaryGemini(
    @Query("document_id") documentId: String,
    @Query("max_length") maxLength: Int = 150
): Response<GeminiSummaryResponse>

data class GeminiSummaryResponse(
    val document_id: String,
    val summary: String,
    val length: Int,
    val method: String
)

22. POST /query/gemini

Répond à une question sur un document avec Gemini.

Query Parameters:

  • document_id (string, required): UUID du document
  • question (string, required): Question à poser
  • use_context (bool, optional): Utiliser FAISS pour le contexte (défaut: true)

Response 200:

{
  "document_id": "555eb078-b49b-4cea-bb8a-2139358b5f42",
  "question": "Quel est le montant total?",
  "answer": "Le montant total de cette facture est de 0,00 $ car il s'agit d'un forfait gratuit pour étudiants.",
  "method": "gemini-pro",
  "context_used": true
}

Errors:

  • 404: Document non trouvé
  • 400: Document vide
  • 429: Quota Gemini dépassé
  • 500: Erreur API Gemini

Exemple cURL:

curl -X POST "https://k2mar-docuresume-backend.hf.space/query/gemini?document_id=555eb078-b49b-4cea-bb8a-2139358b5f42&question=Quel%20est%20le%20montant%20total%3F&use_context=true"

Exemple Kotlin:

@POST("query/gemini")
suspend fun queryDocumentGemini(
    @Query("document_id") documentId: String,
    @Query("question") question: String,
    @Query("use_context") useContext: Boolean = true
): Response<GeminiQueryResponse>

data class GeminiQueryResponse(
    val document_id: String,
    val question: String,
    val answer: String,
    val method: String,
    val context_used: Boolean
)

⚙️ Fonctionnalités Cloud

✅ Activées

  • FAISS (ENABLE_FAISS=true) - ✅ Recherche sémantique opérationnelle
  • Gemini API - ✅ Résumés et Q&A intelligents (gemini-3-flash-preview)
  • Stockage - Supabase Storage (1GB free tier)
  • OCR - Tesseract pour extraction de texte des PDFs

⚠️ Limitations

  • T5 désactivé (ENABLE_T5=false) - Utilisez Gemini à la place
  • Quota Gemini - 15 requêtes/minute gratuit (créer votre clé API sur https://aistudio.google.com/apikey)
  • Rate limiting - HuggingFace peut limiter les requêtes

🛠️ Configuration Client

JavaScript/TypeScript (React, Vue, etc.)

const API_URL = 'https://k2mar-docuresume-backend.hf.space'

const headers = {
  'Content-Type': 'application/json'
}

// Exemple: Login
const response = await fetch(`${API_URL}/users/login`, {
  method: 'POST',
  headers,
  body: JSON.stringify({ email, password })
})
const data = await response.json()

Kotlin/Android

object ApiClient {
    private const val BASE_URL = "https://k2mar-docuresume-backend.hf.space/"
    
    private val retrofit = Retrofit.Builder()
        .baseUrl(BASE_URL)
        .addConverterFactory(GsonConverterFactory.create())
        .client(OkHttpClient.Builder()
            .addInterceptor(HttpLoggingInterceptor().apply {
                level = HttpLoggingInterceptor.Level.BODY
            })
            .build())
        .build()
    
    val apiService: ApiService = retrofit.create(ApiService::class.java)
}

interface ApiService {
    @POST("users/login")
    suspend fun login(@Body credentials: LoginRequest): Response<LoginResponse>
    
    @GET("documents/user/{userId}")
    suspend fun getDocuments(@Path("userId") userId: String): Response<DocumentsResponse>
    
    @Multipart
    @POST("documents/upload")
    suspend fun uploadDocument(
        @Part("user_id") userId: RequestBody,
        @Part file: MultipartBody.Part
    ): Response<UploadResponse>
}

📞 Support



📚 Guide d'Utilisation Complet

✅ Tests Validés (27 janvier 2026)

Compte de test:

  • Email: visiteur@gmail.com
  • Password: 123456789
  • User ID: 07b83616-a528-4720-9fd4-dab8b2cdc4a1

🔄 Workflow Complet Testé

1. Connexion

curl -X POST https://k2mar-docuresume-backend.hf.space/users/login \
  -H "Content-Type: application/json" \
  -d '{"email":"visiteur@gmail.com","password":"123456789"}'

Résultat:

{
  "message": "Connexion réussie",
  "user_id": "07b83616-a528-4720-9fd4-dab8b2cdc4a1",
  "email": "visiteur@gmail.com",
  "username": "visiteur"
}

2. Récupérer les documents

USER_ID="07b83616-a528-4720-9fd4-dab8b2cdc4a1"
curl "https://k2mar-docuresume-backend.hf.space/documents/user/$USER_ID?limit=10"

Résultat (3 documents):

{
  "count": 3,
  "documents": [
    {
      "id": "555eb078-b49b-4cea-bb8a-2139358b5f42",
      "filename": "invoice_a78624a8799919b509beb8a76742e74f.pdf",
      "pages": 1,
      "size_kb": 57,
      "status": "completed"
    },
    {
      "id": "74e50d0d-80ac-44f4-be6e-7517bd95e3e2",
      "filename": "Data_science_avec_Python_Seance_3.pdf",
      "pages": 17,
      "size_kb": 242,
      "status": "completed"
    },
    {
      "id": "f00acf10-a5d0-471f-8165-90017b980141",
      "filename": "Projet_data_analystics_SPARK (1).pdf",
      "pages": 4,
      "size_kb": 136,
      "status": "completed"
    }
  ]
}

3. Récupérer le contenu d'un document

DOC_ID="555eb078-b49b-4cea-bb8a-2139358b5f42"
curl "https://k2mar-docuresume-backend.hf.space/documents/$DOC_ID/content"

Résultat:

{
  "document_id": "555eb078-b49b-4cea-bb8a-2139358b5f42",
  "filename": "invoice_a78624a8799919b509beb8a76742e74f.pdf",
  "content": "© 2025 Appwrite Code, Inc. All rights reserved...",
  "content_length": 608,
  "page_count": 1,
  "file_size": 58432
}

💡 Usage: Ce contenu peut être utilisé pour générer un résumé localement sur le device avec TinyLlama ou T5.


4. Récupérer tous les contenus (pour résumé global)

curl "https://k2mar-docuresume-backend.hf.space/documents/user/$USER_ID/contents?include_content=true&limit=50"

Résultat: Liste de tous les documents avec leur contenu complet.

💡 Usage: Idéal pour générer un résumé global de tous les documents en une seule fois.


5. Générer un résumé localement (sur device)

// Kotlin/Android - Exemple avec TinyLlama
val response = apiService.getDocumentContent(documentId)
val content = response.content

// Générer résumé avec TinyLlama on-device
val summary = tinyLlamaSummarizer.summarize(listOf(
    Pair(response.filename, content)
))

6. Sauvegarder le résumé généré

curl -X POST "https://k2mar-docuresume-backend.hf.space/documents/$DOC_ID/summaries" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "Résumé généré par TinyLlama: Ce document est une facture...",
    "summary_type": "abstractive",
    "summary_level": "medium",
    "model_name": "TinyLlama-1.1B",
    "model_version": "Q4_K_M",
    "compression_ratio": 0.15
  }'

Résultat:

{
  "message": "Résumé créé avec succès",
  "summary_id": "new-uuid",
  "document_id": "555eb078-b49b-4cea-bb8a-2139358b5f42"
}

7. Récupérer les analytics

curl "https://k2mar-docuresume-backend.hf.space/analytics/user/$USER_ID"

Résultat:

{
  "user_id": "07b83616-a528-4720-9fd4-dab8b2cdc4a1",
  "analytics": {
    "total_documents": 3,
    "total_queries": 0,
    "total_summaries": 0,
    "last_active": "2026-01-27T05:03:04Z"
  }
}

🧪 Script de Test Complet

#!/bin/bash

API="https://k2mar-docuresume-backend.hf.space"

echo "🔍 Test 1: Health Check"
curl -s "$API/health" | jq .status

echo -e "\n🔐 Test 2: Login"
LOGIN=$(curl -s -X POST "$API/users/login" \
  -H "Content-Type: application/json" \
  -d '{"email":"visiteur@gmail.com","password":"123456789"}')
USER_ID=$(echo $LOGIN | jq -r .user_id)
echo "User ID: $USER_ID"

echo -e "\n📄 Test 3: Documents"
DOCS=$(curl -s "$API/documents/user/$USER_ID?limit=5")
DOC_COUNT=$(echo $DOCS | jq '.count')
echo "Documents trouvés: $DOC_COUNT"

echo -e "\n📖 Test 4: Premier document"
DOC_ID=$(echo $DOCS | jq -r '.documents[0].id')
DOC_NAME=$(echo $DOCS | jq -r '.documents[0].original_filename')
echo "Document: $DOC_NAME (ID: $DOC_ID)"

echo -e "\n📝 Test 5: Contenu du document"
CONTENT=$(curl -s "$API/documents/$DOC_ID/content")
CONTENT_LENGTH=$(echo $CONTENT | jq .content_length)
echo "Contenu extrait: $CONTENT_LENGTH caractères"

echo -e "\n📊 Test 6: Analytics"
curl -s "$API/analytics/user/$USER_ID" | jq '.analytics | {total_documents, total_summaries, last_active}'

echo -e "\n✅ Tous les tests passés!"

Sauvegarder dans: test_api.sh

Exécuter:

chmod +x test_api.sh
./test_api.sh

📱 Exemple Mobile (Kotlin/Android)

// 1. Configuration du client
object ApiClient {
    private const val BASE_URL = "https://k2mar-docuresume-backend.hf.space/"
    
    val apiService: ApiService = Retrofit.Builder()
        .baseUrl(BASE_URL)
        .addConverterFactory(GsonConverterFactory.create())
        .build()
        .create(ApiService::class.java)
}

// 2. Interface API
interface ApiService {
    @POST("users/login")
    suspend fun login(@Body credentials: LoginRequest): LoginResponse
    
    @GET("documents/user/{userId}")
    suspend fun getDocuments(@Path("userId") userId: String): DocumentsResponse
    
    @GET("documents/{docId}/content")
    suspend fun getDocumentContent(@Path("docId") docId: String): ContentResponse
    
    @POST("documents/{docId}/summaries")
    suspend fun saveSummary(
        @Path("docId") docId: String,
        @Body summary: SummaryRequest
    ): SummaryResponse
}

// 3. Workflow complet
class SummaryViewModel : ViewModel() {
    
    suspend fun generateAndSaveSummary(documentId: String) {
        // Étape 1: Récupérer le contenu
        val contentResponse = ApiClient.apiService.getDocumentContent(documentId)
        val content = contentResponse.content
        
        // Étape 2: Générer résumé localement avec TinyLlama
        val summary = tinyLlamaSummarizer.summarize(listOf(
            Pair(contentResponse.filename, content)
        ))
        
        // Étape 3: Sauvegarder le résumé dans le cloud
        val summaryRequest = SummaryRequest(
            content = summary,
            summary_type = "abstractive",
            summary_level = "medium",
            model_name = "TinyLlama-1.1B",
            compression_ratio = calculateCompression(content, summary)
        )
        
        val result = ApiClient.apiService.saveSummary(documentId, summaryRequest)
        
        Log.d("Summary", "✓ Résumé sauvegardé: ${result.summary_id}")
    }
}

🌐 Exemple Web (JavaScript/React)

// Configuration
const API_URL = 'https://k2mar-docuresume-backend.hf.space'

// 1. Login
const login = async (email, password) => {
  const response = await fetch(`${API_URL}/users/login`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ email, password })
  })
  const data = await response.json()
  localStorage.setItem('user_id', data.user_id)
  return data
}

// 2. Récupérer documents
const getDocuments = async () => {
  const userId = localStorage.getItem('user_id')
  const response = await fetch(`${API_URL}/documents/user/${userId}`)
  return await response.json()
}

// 3. Récupérer contenu
const getContent = async (documentId) => {
  const response = await fetch(`${API_URL}/documents/${documentId}/content`)
  return await response.json()
}

// 4. Upload document
const uploadDocument = async (file) => {
  const userId = localStorage.getItem('user_id')
  const formData = new FormData()
  formData.append('file', file)
  formData.append('user_id', userId)
  
  const response = await fetch(`${API_URL}/documents/upload`, {
    method: 'POST',
    body: formData
  })
  return await response.json()
}

// 5. Workflow complet
const processDocument = async (file) => {
  // Upload
  console.log('📤 Upload...')
  const uploadResult = await uploadDocument(file)
  
  // Récupérer contenu
  console.log('📖 Extraction du texte...')
  const content = await getContent(uploadResult.document_id)
  
  // Note: Génération de résumé se fait sur le device mobile
  // Pour web, utiliser une instance locale avec T5 activé
  console.log(`✅ Document traité: ${content.content_length} caractères`)
}

🐛 Troubleshooting

❌ Erreur 401: "Email ou mot de passe incorrect"

Solution: Vérifier les credentials. Compte test disponible:

  • Email: visiteur@gmail.com
  • Password: 123456789

❌ Erreur 503: "FAISS non disponible"

Solution (OBSOLÈTE): FAISS est maintenant activé sur Hugging Face! Les endpoints /search/semantic et /search/semantic/multi fonctionnent.

❌ Erreur 503: "T5 non disponible"

Solution: T5 est désactivé sur le cloud. Utilisez les endpoints Gemini /generate/summary/gemini et /query/gemini pour les résumés et Q&A.

❌ Erreur 429: "Quota Gemini dépassé"

Solution: La clé API Gemini gratuite a une limite de 15 req/min. Créez votre propre clé sur https://aistudio.google.com/apikey ou attendez 1 minute.

❌ Document upload timeout

Solution: Le backend utilise Tesseract OCR qui peut prendre 10-30s pour les gros PDFs. Augmenter le timeout client à 60s.

❌ CORS Error (Web)

Solution: CORS est activé avec allow_origins=["*"]. Vérifier que le navigateur envoie bien les headers.


📊 Limites & Quotas

Ressource Limite Notes
Taille fichier 10MB Limité par Hugging Face Spaces
Documents/user Illimité Limité par Supabase storage (1GB free)
Requests/minute ~60 Rate limiting HF Spaces
OCR Processing 30s timeout Tesseract peut être lent
Gemini API 15 req/min Quota gratuit (créer votre clé)
FAISS ✅ Activé sentence-transformers (384 dimensions)

🎉 Résumé des fonctionnalités

✅ Actif sur le cloud

  • Authentification - Register, Login
  • Upload PDF - Avec OCR Tesseract automatique
  • Stockage - Supabase PostgreSQL + Storage
  • FAISS - Recherche sémantique vectorielle
  • Gemini API - Résumés et Q&A intelligents (gemini-3-flash-preview)
  • Analytics - Statistiques utilisateur et globales

⚠️ Désactivé sur le cloud

  • T5 local - Utilisez Gemini API à la place
  • TinyLlama - Difficile à déployer sur HF (600MB) | FAISS | ❌ Désactivé | Cloud uniquement | | T5 Generation | ❌ Désactivé | Cloud uniquement |

🔗 Liens Utiles

  • API Swagger/OpenAPI: https://k2mar-docuresume-backend.hf.space/docs
  • Redoc: https://k2mar-docuresume-backend.hf.space/redoc
  • Health Check: https://k2mar-docuresume-backend.hf.space/health
  • Stats: https://k2mar-docuresume-backend.hf.space/stats/global

Dernière mise à jour: 27 janvier 2026
Version API: 1.0.0
Tests validés: ✅ 27 janvier 2026