# 📡 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](#-authentification) - Register, Login 2. [Gestion des Documents](#-gestion-des-documents) - Upload, Liste, Contenu 3. [RĂ©sumĂ©s](#-rĂ©sumĂ©s) - Sauvegarde et historique 4. [Recherche FAISS](#-recherche-sĂ©mantique-faiss) - Recherche sĂ©mantique 5. [IA GĂ©nĂ©rative (Gemini)](#-ia-gĂ©nĂ©rative-gemini-api) - RĂ©sumĂ©s et Q&A 6. [Analytics](#-analytics--stats) - Statistiques utilisateur 7. [SystĂšme](#-systĂšme) - Health check --- ## 🔐 Authentification ### 1. **POST** `/users/register` CrĂ©er un nouveau compte utilisateur. **Request Body:** ```json { "email": "user@example.com", "username": "johndoe", "password": "securepassword123" } ``` **Response 200:** ```json { "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:** ```bash 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:** ```json { "email": "user@example.com", "password": "securepassword123" } ``` **Response 200:** ```json { "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:** ```bash 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:** ```json { "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:** ```bash 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):** ```javascript 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):** ```kotlin 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:** ```json { "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:** ```bash 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:** ```json { "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:** ```bash 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:** ```json { "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:** ```bash 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:** ```json { "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:** ```bash 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:** ```bash 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:** ```json { "tags": ["nouveau", "tag"], "is_archived": true } ``` **Response 200:** ```json { "message": "Document mis Ă  jour", "document_id": "uuid-v4" } ``` --- ### 10. **DELETE** `/documents/{document_id}` Supprimer un document (cascade: chunks, embeddings, summaries). **Response 200:** ```json { "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:** ```json { "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:** ```json { "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:** ```json [ { "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:** ```json { "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:** ```json { "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:** ```json { "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:** ```json { "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:** ```bash 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:** ```json { "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:** ```bash 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:** ```json { "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:** ```json { "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:** ```json { "service": "DocuResume Pro API", "version": "1.0.0", "status": "running", "supabase_connected": true } ``` **Exemple cURL:** ```bash curl https://k2mar-docuresume-backend.hf.space/ ``` --- ### 20. **GET** `/health` Health check de l'API et de la base de donnĂ©es. **Response 200:** ```json { "status": "healthy", "database": "connected", "timestamp": "2026-01-27T12:00:00" } ``` **Exemple cURL:** ```bash curl https://k2mar-docuresume-backend.hf.space/health ``` --- ## 🚀 Workflow Complet (Exemple Android/Mobile) ### Étape 1: Inscription ```kotlin POST /users/register Body: { email, username, password } → Obtenir user_id ``` ### Étape 2: Upload de documents ```kotlin POST /documents/upload Form-data: { file, user_id } → Obtenir document_id ``` ### Étape 3: RĂ©cupĂ©rer le contenu ```kotlin GET /documents/{document_id}/content → Obtenir content (texte extrait) ``` ### Étape 4: GĂ©nĂ©rer rĂ©sumĂ© avec Gemini (Cloud) ```kotlin 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 ```kotlin POST /query/gemini?document_id={id}&question=Quel%20est%20le%20sujet%3F → Obtenir answer contextuelle ``` ### Étape 6: Recherche sĂ©mantique (FAISS) ```kotlin 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:** ```json { "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:** ```bash curl -X POST "https://k2mar-docuresume-backend.hf.space/generate/summary/gemini?document_id=555eb078-b49b-4cea-bb8a-2139358b5f42&max_length=60" ``` **Exemple Kotlin:** ```kotlin @POST("generate/summary/gemini") suspend fun generateSummaryGemini( @Query("document_id") documentId: String, @Query("max_length") maxLength: Int = 150 ): Response 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:** ```json { "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:** ```bash 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:** ```kotlin @POST("query/gemini") suspend fun queryDocumentGemini( @Query("document_id") documentId: String, @Query("question") question: String, @Query("use_context") useContext: Boolean = true ): Response 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.) ```javascript 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 ```kotlin 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 @GET("documents/user/{userId}") suspend fun getDocuments(@Path("userId") userId: String): Response @Multipart @POST("documents/upload") suspend fun uploadDocument( @Part("user_id") userId: RequestBody, @Part file: MultipartBody.Part ): Response } ``` --- ## 📞 Support - **GitHub:** [votre-repo](https://github.com/...) - **Email:** support@docuresume.com - **Documentation:** https://k2mar-docuresume-backend.hf.space/docs (Swagger UI) --- --- ## 📚 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** ```bash 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:** ```json { "message": "Connexion rĂ©ussie", "user_id": "07b83616-a528-4720-9fd4-dab8b2cdc4a1", "email": "visiteur@gmail.com", "username": "visiteur" } ``` --- #### 2. **RĂ©cupĂ©rer les documents** ```bash USER_ID="07b83616-a528-4720-9fd4-dab8b2cdc4a1" curl "https://k2mar-docuresume-backend.hf.space/documents/user/$USER_ID?limit=10" ``` **RĂ©sultat (3 documents):** ```json { "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** ```bash DOC_ID="555eb078-b49b-4cea-bb8a-2139358b5f42" curl "https://k2mar-docuresume-backend.hf.space/documents/$DOC_ID/content" ``` **RĂ©sultat:** ```json { "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)** ```bash 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 // 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Ă©** ```bash 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:** ```json { "message": "RĂ©sumĂ© créé avec succĂšs", "summary_id": "new-uuid", "document_id": "555eb078-b49b-4cea-bb8a-2139358b5f42" } ``` --- #### 7. **RĂ©cupĂ©rer les analytics** ```bash curl "https://k2mar-docuresume-backend.hf.space/analytics/user/$USER_ID" ``` **RĂ©sultat:** ```json { "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 ```bash #!/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:** ```bash chmod +x test_api.sh ./test_api.sh ``` --- ### đŸ“± Exemple Mobile (Kotlin/Android) ```kotlin // 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) ```javascript // 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