sahges-sdk 0.1.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. sahges_sdk-0.1.1/PKG-INFO +1103 -0
  2. sahges_sdk-0.1.1/README.md +1084 -0
  3. sahges_sdk-0.1.1/pyproject.toml +57 -0
  4. sahges_sdk-0.1.1/setup.cfg +4 -0
  5. sahges_sdk-0.1.1/src/sahges_sdk/__init__.py +3 -0
  6. sahges_sdk-0.1.1/src/sahges_sdk/auth/__init__.py +5 -0
  7. sahges_sdk-0.1.1/src/sahges_sdk/auth/auth_client.py +58 -0
  8. sahges_sdk-0.1.1/src/sahges_sdk/auth/introspect/introspect.py +41 -0
  9. sahges_sdk-0.1.1/src/sahges_sdk/auth/login/login_attempt.py +45 -0
  10. sahges_sdk-0.1.1/src/sahges_sdk/auth/login/login_attempt_schema.py +15 -0
  11. sahges_sdk-0.1.1/src/sahges_sdk/auth/login/login_response_schema.py +17 -0
  12. sahges_sdk-0.1.1/src/sahges_sdk/auth/login/refresh_attempt.py +43 -0
  13. sahges_sdk-0.1.1/src/sahges_sdk/auth/login/refresh_attempt_schema.py +24 -0
  14. sahges_sdk-0.1.1/src/sahges_sdk/auth/logout/logout.py +38 -0
  15. sahges_sdk-0.1.1/src/sahges_sdk/auth/reset_password/reset_password.py +138 -0
  16. sahges_sdk-0.1.1/src/sahges_sdk/auth/reset_password_schemas.py +60 -0
  17. sahges_sdk-0.1.1/src/sahges_sdk/auth/routes.py +31 -0
  18. sahges_sdk-0.1.1/src/sahges_sdk/auth/schemas/auth_organization_schema.py +21 -0
  19. sahges_sdk-0.1.1/src/sahges_sdk/auth/schemas/auth_user_schema.py +24 -0
  20. sahges_sdk-0.1.1/src/sahges_sdk/base/__init__.py +1 -0
  21. sahges_sdk-0.1.1/src/sahges_sdk/base/client.py +148 -0
  22. sahges_sdk-0.1.1/src/sahges_sdk/base/decorators.py +86 -0
  23. sahges_sdk-0.1.1/src/sahges_sdk/base/endpoint.py +20 -0
  24. sahges_sdk-0.1.1/src/sahges_sdk/base/enums.py +17 -0
  25. sahges_sdk-0.1.1/src/sahges_sdk/base/error.py +55 -0
  26. sahges_sdk-0.1.1/src/sahges_sdk/base/logger.py +27 -0
  27. sahges_sdk-0.1.1/src/sahges_sdk/config/__init__.py +44 -0
  28. sahges_sdk-0.1.1/src/sahges_sdk/docs/__init__.py +5 -0
  29. sahges_sdk-0.1.1/src/sahges_sdk/docs/clients/__init__.py +13 -0
  30. sahges_sdk-0.1.1/src/sahges_sdk/docs/clients/create.py +69 -0
  31. sahges_sdk-0.1.1/src/sahges_sdk/docs/clients/download.py +37 -0
  32. sahges_sdk-0.1.1/src/sahges_sdk/docs/clients/find.py +28 -0
  33. sahges_sdk-0.1.1/src/sahges_sdk/docs/clients/list.py +31 -0
  34. sahges_sdk-0.1.1/src/sahges_sdk/docs/docs_client.py +86 -0
  35. sahges_sdk-0.1.1/src/sahges_sdk/docs/documents/__init__.py +19 -0
  36. sahges_sdk-0.1.1/src/sahges_sdk/docs/documents/create.py +69 -0
  37. sahges_sdk-0.1.1/src/sahges_sdk/docs/documents/create_schema.py +18 -0
  38. sahges_sdk-0.1.1/src/sahges_sdk/docs/documents/delete.py +21 -0
  39. sahges_sdk-0.1.1/src/sahges_sdk/docs/documents/download.py +37 -0
  40. sahges_sdk-0.1.1/src/sahges_sdk/docs/documents/find.py +28 -0
  41. sahges_sdk-0.1.1/src/sahges_sdk/docs/documents/list.py +29 -0
  42. sahges_sdk-0.1.1/src/sahges_sdk/docs/documents/list_schema.py +19 -0
  43. sahges_sdk-0.1.1/src/sahges_sdk/docs/documents/update.py +33 -0
  44. sahges_sdk-0.1.1/src/sahges_sdk/docs/documents/update_schema.py +17 -0
  45. sahges_sdk-0.1.1/src/sahges_sdk/docs/documents/visibility.py +33 -0
  46. sahges_sdk-0.1.1/src/sahges_sdk/docs/documents/visibility_schema.py +13 -0
  47. sahges_sdk-0.1.1/src/sahges_sdk/docs/enums.py +42 -0
  48. sahges_sdk-0.1.1/src/sahges_sdk/docs/routes.py +50 -0
  49. sahges_sdk-0.1.1/src/sahges_sdk/docs/schemas/__init__.py +5 -0
  50. sahges_sdk-0.1.1/src/sahges_sdk/docs/schemas/document_schema.py +56 -0
  51. sahges_sdk-0.1.1/src/sahges_sdk/docs/shares/__init__.py +11 -0
  52. sahges_sdk-0.1.1/src/sahges_sdk/docs/shares/create.py +32 -0
  53. sahges_sdk-0.1.1/src/sahges_sdk/docs/shares/delete.py +29 -0
  54. sahges_sdk-0.1.1/src/sahges_sdk/docs/shares/list.py +28 -0
  55. sahges_sdk-0.1.1/src/sahges_sdk/docs/shares/share_schema.py +30 -0
  56. sahges_sdk-0.1.1/src/sahges_sdk/plugins/marshmallow/__init__.py +11 -0
  57. sahges_sdk-0.1.1/src/sahges_sdk/plugins/marshmallow/fields.py +468 -0
  58. sahges_sdk-0.1.1/src/sahges_sdk/test.py +42 -0
  59. sahges_sdk-0.1.1/src/sahges_sdk/utils/__init__.py +5 -0
  60. sahges_sdk-0.1.1/src/sahges_sdk/utils/validators.py +69 -0
  61. sahges_sdk-0.1.1/src/sahges_sdk.egg-info/PKG-INFO +1103 -0
  62. sahges_sdk-0.1.1/src/sahges_sdk.egg-info/SOURCES.txt +72 -0
  63. sahges_sdk-0.1.1/src/sahges_sdk.egg-info/dependency_links.txt +1 -0
  64. sahges_sdk-0.1.1/src/sahges_sdk.egg-info/requires.txt +11 -0
  65. sahges_sdk-0.1.1/src/sahges_sdk.egg-info/top_level.txt +1 -0
  66. sahges_sdk-0.1.1/tests/test_auth_complete.py +265 -0
  67. sahges_sdk-0.1.1/tests/test_auth_login.py +154 -0
  68. sahges_sdk-0.1.1/tests/test_client.py +66 -0
  69. sahges_sdk-0.1.1/tests/test_config.py +24 -0
  70. sahges_sdk-0.1.1/tests/test_decorators.py +74 -0
  71. sahges_sdk-0.1.1/tests/test_docs_complete.py +377 -0
  72. sahges_sdk-0.1.1/tests/test_errors.py +54 -0
  73. sahges_sdk-0.1.1/tests/test_manual_docs.py +635 -0
  74. sahges_sdk-0.1.1/tests/test_manual_login.py +235 -0
@@ -0,0 +1,1103 @@
1
+ Metadata-Version: 2.4
2
+ Name: sahges-sdk
3
+ Version: 0.1.1
4
+ Summary: SDK Python officiel de l'écosystème SAHGES
5
+ Author-email: SAHGES <floriano.gomez@bj.sanlamallianz.com>
6
+ Project-URL: Source, https://gitlab.com/florianogomez/sahges-sdk.git
7
+ Requires-Python: >=3.10
8
+ Description-Content-Type: text/markdown
9
+ Requires-Dist: httpx>=0.27
10
+ Requires-Dist: marshmallow>=3.20
11
+ Requires-Dist: python-dotenv>=1.0.0
12
+ Provides-Extra: dev
13
+ Requires-Dist: pytest>=7.4; extra == "dev"
14
+ Requires-Dist: pytest-cov>=4.1; extra == "dev"
15
+ Requires-Dist: pytest-asyncio>=0.21; extra == "dev"
16
+ Requires-Dist: black>=23.0; extra == "dev"
17
+ Requires-Dist: ruff>=0.1; extra == "dev"
18
+ Requires-Dist: mypy>=1.5; extra == "dev"
19
+
20
+ # SAHGES SDK
21
+
22
+ SDK Python officiel pour l'écosystème SAHGES. Facilite l'intégration avec les services SAHGES via une interface Python simple et robuste.
23
+
24
+ [![Python Version](https://img.shields.io/badge/python-3.10%2B-blue)](https://www.python.org/downloads/)
25
+ [![License](https://img.shields.io/badge/license-MIT-green)](LICENSE)
26
+
27
+ ## 📋 Prérequis
28
+
29
+ - Python 3.10 ou supérieur
30
+ - pip pour l'installation des dépendances
31
+
32
+ ## 🚀 Installation
33
+
34
+ ```bash
35
+ pip install sahges-sdk
36
+ ```
37
+
38
+ Ou depuis les sources :
39
+
40
+ ```bash
41
+ git clone https://gitlab.com/florianogomez/sahges-sdk.git
42
+ cd sahges-sdk
43
+ pip install -e .
44
+ ```
45
+
46
+ ## 🎯 Getting Started (Démarrage rapide)
47
+
48
+ ### Installation et premier test
49
+
50
+ ```bash
51
+ # 1. Installer le SDK
52
+ pip install sahges-sdk
53
+
54
+ # 2. Créer un fichier test.py
55
+ ```
56
+
57
+ ### Exemple minimum : Authentification
58
+
59
+ ```python
60
+ # test.py
61
+ from sahges_sdk.auth import SahgesAuthClient
62
+
63
+ # Initialiser le client
64
+ client = SahgesAuthClient(
65
+ client_id="votre_client_id",
66
+ client_secret="votre_client_secret"
67
+ )
68
+
69
+ # Se connecter
70
+ response = client.login(payload={
71
+ "credential": "user@example.com",
72
+ "password": "mot_de_passe"
73
+ })
74
+
75
+ # Afficher le token
76
+ print(f"Token d'accès: {response['access_token']}")
77
+ print(f"Utilisateur: {response['user']['email']}")
78
+ ```
79
+
80
+ ### Exemple minimum : Gestion documentaire
81
+
82
+ ```python
83
+ # test_docs.py
84
+ from sahges_sdk.docs import SahgesDocsClient
85
+ from pathlib import Path
86
+
87
+ # Initialiser le client
88
+ client = SahgesDocsClient(
89
+ client_id="votre_client_id",
90
+ client_secret="votre_client_secret"
91
+ )
92
+
93
+ # Uploader un document
94
+ document = client.create(
95
+ title="Mon premier document",
96
+ file_path=Path("document.pdf"),
97
+ visibility="ORGANIZATION"
98
+ )
99
+
100
+ print(f"Document créé: {document['id']}")
101
+ print(f"Fichier: {document['file_name']}")
102
+ ```
103
+
104
+ ### Utilisation combinée (Auth + Docs)
105
+
106
+ ```python
107
+ from sahges_sdk.auth import SahgesAuthClient
108
+ from sahges_sdk.docs import SahgesDocsClient
109
+
110
+ # 1. S'authentifier
111
+ auth = SahgesAuthClient(
112
+ client_id="votre_client_id",
113
+ client_secret="votre_client_secret"
114
+ )
115
+
116
+ login = auth.login(payload={
117
+ "credential": "user@example.com",
118
+ "password": "password"
119
+ })
120
+
121
+ print(f"Connecté: {login['user']['email']}")
122
+
123
+ # 2. Gérer des documents
124
+ docs = SahgesDocsClient(
125
+ client_id="votre_client_id",
126
+ client_secret="votre_client_secret"
127
+ )
128
+
129
+ # Lister les documents
130
+ documents = docs.list(payload={})
131
+ print(f"Nombre de documents: {len(documents)}")
132
+ ```
133
+
134
+ ## ⚙️ Configuration
135
+
136
+ ### Variables d'environnement
137
+
138
+ Créez un fichier `.env` à la racine de votre projet :
139
+
140
+ ```env
141
+ # Credentials API (obligatoire)
142
+ SAHGES_CLIENT_ID=votre_client_id
143
+ SAHGES_CLIENT_SECRET=votre_client_secret
144
+
145
+ # URLs des services (optionnel, valeurs par défaut)
146
+ SAHGES_AUTHENTICATION_BASE_URL=https://api.sahges.com
147
+ SAHGES_DOCS_BASE_URL=https://docs.sahges.com
148
+
149
+ # Configuration optionnelle
150
+ SAHGES_TIMEOUT=30
151
+ SAHGES_LOG_LEVEL=INFO
152
+ ```
153
+
154
+ ### Utilisation avec variables d'environnement
155
+
156
+ ```python
157
+ import os
158
+ from dotenv import load_dotenv
159
+ from sahges_sdk.auth import SahgesAuthClient
160
+
161
+ # Charger les variables d'environnement
162
+ load_dotenv()
163
+
164
+ # Utiliser les variables
165
+ client = SahgesAuthClient(
166
+ client_id=os.getenv('SAHGES_CLIENT_ID'),
167
+ client_secret=os.getenv('SAHGES_CLIENT_SECRET')
168
+ )
169
+
170
+ response = client.login(payload={
171
+ "credential": os.getenv('SAHGES_USER_EMAIL'),
172
+ "password": os.getenv('SAHGES_USER_PASSWORD')
173
+ })
174
+ ```
175
+
176
+ ### Obtenir des credentials
177
+
178
+ Pour obtenir vos `client_id` et `client_secret`, contactez l'équipe SAHGES :
179
+ - 📧 Email : floriano.gomez@bj.sanlamallianz.com
180
+ - 🌐 Documentation : https://docs.sahges.com
181
+
182
+ ## 📖 Utilisation
183
+
184
+ Le SDK SAHGES est organisé en deux modules principaux :
185
+ - **Auth** : Authentification et gestion des utilisateurs
186
+ - **Docs** : Gestion documentaire avec upload, partage et traitement IA
187
+
188
+ ### Module Auth - Authentification
189
+
190
+ #### Connexion simple
191
+
192
+ ```python
193
+ from sahges_sdk.auth import SahgesAuthClient
194
+
195
+ # Initialiser le client
196
+ client = SahgesAuthClient(
197
+ client_id="votre_client_id",
198
+ client_secret="votre_client_secret"
199
+ )
200
+
201
+ # Connexion
202
+ response = client.login(payload={
203
+ "credential": "user@example.com",
204
+ "password": "votre_mot_de_passe"
205
+ })
206
+
207
+ print(f"Token: {response['access_token']}")
208
+ print(f"Utilisateur: {response['user']['first_name']} {response['user']['last_name']}")
209
+ print(f"Email: {response['user']['email']}")
210
+ print(f"Organisation: {response['user']['organization']['name']}")
211
+ ```
212
+
213
+ #### Cycle de vie complet d'une session
214
+
215
+ ```python
216
+ from sahges_sdk.auth import SahgesAuthClient
217
+
218
+ client = SahgesAuthClient(
219
+ client_id="votre_client_id",
220
+ client_secret="votre_client_secret"
221
+ )
222
+
223
+ # 1. Connexion
224
+ login_response = client.login(payload={
225
+ "credential": "user@example.com",
226
+ "password": "mot_de_passe"
227
+ })
228
+
229
+ access_token = login_response["access_token"]
230
+ refresh_token = login_response["refresh_token"]
231
+
232
+ # 2. Introspection - Vérifier les infos utilisateur
233
+ user_info = client.introspect(access_token=access_token)
234
+ print(f"Rôle: {user_info['role']}")
235
+ print(f"Actif: {user_info['is_active']}")
236
+
237
+ # 3. Rafraîchir le token
238
+ new_tokens = client.refresh(payload={
239
+ "refresh_token": refresh_token
240
+ })
241
+ access_token = new_tokens["access_token"]
242
+ refresh_token = new_tokens["refresh_token"]
243
+
244
+ # 4. Déconnexion
245
+ client.logout(access_token=access_token)
246
+ print("Déconnexion réussie")
247
+ ```
248
+
249
+ #### Réinitialisation de mot de passe
250
+
251
+ ```python
252
+ from sahges_sdk.auth import SahgesAuthClient
253
+
254
+ client = SahgesAuthClient(
255
+ client_id="votre_client_id",
256
+ client_secret="votre_client_secret"
257
+ )
258
+
259
+ # 1. Demander la réinitialisation (envoie un email)
260
+ response = client.forgot_password(payload={
261
+ "credential": "user@example.com"
262
+ })
263
+ print(response["message"])
264
+
265
+ # 2. Valider le token reçu par email
266
+ token = "token_recu_par_email"
267
+ challenge = client.reset_password_challenge(token=token)
268
+
269
+ if challenge["valid"]:
270
+ # 3. Réinitialiser le mot de passe
271
+ result = client.reset_password(payload={
272
+ "token": token,
273
+ "new_password": "nouveau_mot_de_passe_securise",
274
+ "new_password_confirmation": "nouveau_mot_de_passe_securise"
275
+ })
276
+ print(result["message"])
277
+ ```
278
+
279
+ ### Module Docs - Gestion documentaire
280
+
281
+ #### Upload et création de documents
282
+
283
+ ```python
284
+ from sahges_sdk.docs import SahgesDocsClient
285
+ from pathlib import Path
286
+
287
+ client = SahgesDocsClient(
288
+ client_id="votre_client_id",
289
+ client_secret="votre_client_secret"
290
+ )
291
+
292
+ # Créer un document avec upload
293
+ document = client.create(
294
+ title="Rapport annuel 2025",
295
+ file_path=Path("/path/to/rapport.pdf"),
296
+ description="Rapport financier complet de l'année 2025",
297
+ visibility="ORGANIZATION", # PRIVATE, ORGANIZATION, PUBLIC
298
+ status="DRAFT", # DRAFT, PENDING, VALIDATED, ARCHIVED
299
+ category="finance",
300
+ tags=["rapport", "2025", "finance"]
301
+ )
302
+
303
+ print(f"Document créé: {document['id']}")
304
+ print(f"Fichier: {document['file_name']} ({document['file_size']} bytes)")
305
+ print(f"Format: {document['file_format']}")
306
+
307
+ # Vérifier les résultats du traitement IA
308
+ if document.get('ocr_text'):
309
+ print(f"Texte extrait (OCR): {document['ocr_text'][:100]}...")
310
+
311
+ if document.get('ai_summary'):
312
+ print(f"Résumé IA: {document['ai_summary']}")
313
+
314
+ if document.get('ai_metadata'):
315
+ print(f"Métadonnées IA: {document['ai_metadata']}")
316
+ ```
317
+
318
+ #### Recherche et filtrage de documents
319
+
320
+ ```python
321
+ from sahges_sdk.docs import SahgesDocsClient
322
+
323
+ client = SahgesDocsClient(
324
+ client_id="votre_client_id",
325
+ client_secret="votre_client_secret"
326
+ )
327
+
328
+ # Liste de tous les documents
329
+ all_docs = client.list(payload={})
330
+ print(f"Total de documents: {len(all_docs)}")
331
+
332
+ # Recherche avec filtres
333
+ documents = client.list(payload={
334
+ "page": 1,
335
+ "search": "rapport", # Recherche textuelle
336
+ "visibility": "ORGANIZATION", # Filtre par visibilité
337
+ "status": "VALIDATED", # Filtre par statut
338
+ "category": "finance" # Filtre par catégorie
339
+ })
340
+
341
+ for doc in documents:
342
+ print(f"- {doc['title']} (créé le {doc['created_at']})")
343
+
344
+ # Mes documents uniquement
345
+ my_docs = client.list(payload={"owner_only": True})
346
+
347
+ # Documents partagés avec moi
348
+ shared_docs = client.list(payload={"shared_with_me": True})
349
+ ```
350
+
351
+ #### Gestion complète d'un document
352
+
353
+ ```python
354
+ from sahges_sdk.docs import SahgesDocsClient
355
+ from pathlib import Path
356
+
357
+ client = SahgesDocsClient(
358
+ client_id="votre_client_id",
359
+ client_secret="votre_client_secret"
360
+ )
361
+
362
+ # 1. Créer
363
+ document = client.create(
364
+ title="Contrat client XYZ",
365
+ file_path=Path("contrat.pdf"),
366
+ visibility="PRIVATE",
367
+ status="DRAFT"
368
+ )
369
+ doc_id = document['id']
370
+
371
+ # 2. Récupérer les détails
372
+ doc_details = client.find(payload={"document_id": doc_id})
373
+ print(f"Propriétaire: {doc_details['owner_auth_user_id']}")
374
+
375
+ # 3. Mettre à jour
376
+ updated_doc = client.update(payload={
377
+ "document_id": doc_id,
378
+ "title": "Contrat client XYZ - Version finale",
379
+ "status": "VALIDATED",
380
+ "tags": ["contrat", "2025", "client-xyz"]
381
+ })
382
+
383
+ # 4. Changer la visibilité
384
+ doc = client.update_visibility(payload={
385
+ "document_id": doc_id,
386
+ "visibility": "ORGANIZATION"
387
+ })
388
+
389
+ # 5. Télécharger le fichier
390
+ client.download(
391
+ document_id=doc_id,
392
+ output_path="/path/to/save/contrat_downloaded.pdf"
393
+ )
394
+
395
+ # Ou obtenir le contenu en bytes
396
+ file_bytes = client.download(document_id=doc_id)
397
+ # Traiter les bytes...
398
+
399
+ # 6. Supprimer (optionnel)
400
+ # client.delete(document_id=doc_id)
401
+ ```
402
+
403
+ #### Partage de documents
404
+
405
+ ```python
406
+ from sahges_sdk.docs import SahgesDocsClient
407
+ from datetime import datetime, timedelta
408
+
409
+ client = SahgesDocsClient(
410
+ client_id="votre_client_id",
411
+ client_secret="votre_client_secret"
412
+ )
413
+
414
+ doc_id = "550e8400-e29b-41d4-a716-446655440000"
415
+
416
+ # 1. Partager avec un utilisateur
417
+ share = client.share_create(payload={
418
+ "document_id": doc_id,
419
+ "shared_with_auth_user_id": "user-uuid-ici",
420
+ "permission": "VIEW", # VIEW, EDIT, ou MANAGE
421
+ "expires_at": datetime.now() + timedelta(days=30)
422
+ })
423
+
424
+ print(f"Document partagé avec ID: {share['id']}")
425
+ print(f"Permission: {share['permission']}")
426
+ print(f"Expire le: {share['expires_at']}")
427
+
428
+ # 2. Lister tous les partages
429
+ shares = client.share_list(payload={"document_id": doc_id})
430
+
431
+ for s in shares:
432
+ print(f"Partagé avec: {s['shared_with_auth_user_id']}")
433
+ print(f"Permission: {s['permission']}")
434
+ print(f"Par: {s['shared_by_auth_user_id']}")
435
+
436
+ # 3. Révoquer un partage
437
+ if shares:
438
+ client.share_delete(payload={
439
+ "document_id": doc_id,
440
+ "share_id": shares[0]['id']
441
+ })
442
+ print("Partage révoqué")
443
+ ```
444
+
445
+ #### Endpoints clients (accès restreint)
446
+
447
+ Les endpoints clients sont pour les applications tierces avec permissions limitées :
448
+
449
+ ```python
450
+ from sahges_sdk.docs import SahgesDocsClient
451
+
452
+ client = SahgesDocsClient(
453
+ client_id="client_id_tiers",
454
+ client_secret="client_secret_tiers"
455
+ )
456
+
457
+ # Liste des documents accessibles (ORGANIZATION + PUBLIC)
458
+ documents = client.clients_list(payload={
459
+ "page": 1,
460
+ "search": "facture",
461
+ "category": "comptabilite"
462
+ })
463
+
464
+ # Créer un document (visibilité forcée à ORGANIZATION)
465
+ doc = client.clients_create(
466
+ title="Facture janvier 2025",
467
+ file_path="facture_janvier.pdf",
468
+ description="Facture du mois de janvier",
469
+ status="VALIDATED",
470
+ category="comptabilite"
471
+ )
472
+
473
+ # Récupérer un document
474
+ document = client.clients_find(payload={
475
+ "document_id": doc['id']
476
+ })
477
+
478
+ # Télécharger
479
+ client.clients_download(
480
+ document_id=doc['id'],
481
+ output_path="facture_downloaded.pdf"
482
+ )
483
+ ```
484
+
485
+ ### Workflow complet : Auth + Docs
486
+
487
+ Exemple d'utilisation combinée des deux modules :
488
+
489
+ ```python
490
+ from sahges_sdk.auth import SahgesAuthClient
491
+ from sahges_sdk.docs import SahgesDocsClient
492
+ from pathlib import Path
493
+
494
+ # 1. Authentification
495
+ auth_client = SahgesAuthClient(
496
+ client_id="votre_client_id",
497
+ client_secret="votre_client_secret"
498
+ )
499
+
500
+ login_response = auth_client.login(payload={
501
+ "credential": "user@example.com",
502
+ "password": "mot_de_passe"
503
+ })
504
+
505
+ access_token = login_response["access_token"]
506
+ user = login_response["user"]
507
+
508
+ print(f"Connecté en tant que {user['first_name']} {user['last_name']}")
509
+ print(f"Organisation: {user['organization']['name']}")
510
+
511
+ # 2. Gestion documentaire
512
+ docs_client = SahgesDocsClient(
513
+ client_id="votre_client_id",
514
+ client_secret="votre_client_secret"
515
+ )
516
+
517
+ # Créer un document
518
+ document = docs_client.create(
519
+ title="Mon document",
520
+ file_path=Path("document.pdf"),
521
+ visibility="ORGANIZATION",
522
+ status="DRAFT"
523
+ )
524
+
525
+ print(f"Document créé: {document['id']}")
526
+
527
+ # Lister mes documents
528
+ my_docs = docs_client.list(payload={"owner_only": True})
529
+ print(f"Vous avez {len(my_docs)} document(s)")
530
+
531
+ # Partager avec un collègue
532
+ if user.get('colleague_id'):
533
+ share = docs_client.share_create(payload={
534
+ "document_id": document['id'],
535
+ "shared_with_auth_user_id": user['colleague_id'],
536
+ "permission": "EDIT"
537
+ })
538
+ print(f"Document partagé avec permission {share['permission']}")
539
+
540
+ # 3. Déconnexion
541
+ auth_client.logout(access_token=access_token)
542
+ print("Session terminée")
543
+ ```
544
+
545
+ ### Utilisation avec variables d'environnement
546
+
547
+ ```python
548
+ import os
549
+ from dotenv import load_dotenv
550
+ from sahges_sdk.auth import SahgesAuthClient
551
+ from sahges_sdk.docs import SahgesDocsClient
552
+
553
+ load_dotenv()
554
+
555
+ # Initialisation simplifiée
556
+ auth_client = SahgesAuthClient(
557
+ client_id=os.getenv('SAHGES_CLIENT_ID'),
558
+ client_secret=os.getenv('SAHGES_CLIENT_SECRET')
559
+ )
560
+
561
+ docs_client = SahgesDocsClient(
562
+ client_id=os.getenv('SAHGES_CLIENT_ID'),
563
+ client_secret=os.getenv('SAHGES_CLIENT_SECRET')
564
+ )
565
+
566
+ # Utilisation...
567
+ response = auth_client.login(payload={
568
+ "credential": os.getenv('SAHGES_USER_EMAIL'),
569
+ "password": os.getenv('SAHGES_USER_PASSWORD')
570
+ })
571
+ ```
572
+
573
+ ## 🏗️ Architecture
574
+
575
+ ```
576
+ src/
577
+ ├── auth/ # Module d'authentification
578
+ │ ├── auth_client.py # Client SAHGES Auth
579
+ │ ├── routes.py # Routes API d'authentification
580
+ │ ├── login/ # Connexion et refresh token
581
+ │ ├── logout/ # Déconnexion
582
+ │ ├── introspect/ # Informations utilisateur
583
+ │ ├── reset_password/# Réinitialisation de mot de passe
584
+ │ └── schemas/ # Schémas de validation (user, organization)
585
+ ├── docs/ # Module de gestion documentaire
586
+ │ ├── docs_client.py # Client SAHGES Docs
587
+ │ ├── routes.py # Routes API des documents
588
+ │ ├── enums.py # Énumérations (visibilité, statut, permissions)
589
+ │ ├── documents/ # CRUD documents avec filtres
590
+ │ ├── shares/ # Gestion des partages
591
+ │ ├── clients/ # Endpoints clients (accès restreint)
592
+ │ └── schemas/ # Schémas de validation (document, share)
593
+ ├── base/ # Classes de base
594
+ │ ├── client.py # Client HTTP de base
595
+ │ ├── endpoint.py # Définition des endpoints
596
+ │ ├── decorators.py # Décorateurs de validation
597
+ │ ├── enums.py # Énumérations globales
598
+ │ ├── error.py # Exceptions personnalisées
599
+ │ └── logger.py # Configuration du logging
600
+ ├── config/ # Configuration centralisée
601
+ ├── plugins/ # Extensions
602
+ │ └── marshmallow/ # Champs de validation personnalisés
603
+ └── utils/ # Utilitaires
604
+ └── validators.py # Validateurs
605
+ ```
606
+
607
+ ## 🎯 Fonctionnalités principales
608
+
609
+ ### Module Auth
610
+
611
+ - ✅ **Connexion (login)** : Authentification avec email/identifiant et mot de passe
612
+ - ✅ **Rafraîchissement (refresh)** : Renouvellement des tokens sans reconnexion
613
+ - ✅ **Introspection** : Récupération des informations utilisateur et organisation
614
+ - ✅ **Déconnexion (logout)** : Invalidation sécurisée des tokens
615
+ - ✅ **Mot de passe oublié** : Demande de réinitialisation par email
616
+ - ✅ **Validation de token** : Vérification du token de réinitialisation
617
+ - ✅ **Réinitialisation** : Changement de mot de passe avec token
618
+
619
+ ### Module Docs
620
+
621
+ - 📄 **Upload de documents** : Création avec fichier (tous formats)
622
+ - 🔍 **Recherche avancée** : Filtres par titre, catégorie, statut, visibilité
623
+ - 📝 **CRUD complet** : Création, lecture, mise à jour, suppression
624
+ - 👁️ **Visibilité granulaire** : PRIVATE, ORGANIZATION, PUBLIC
625
+ - 🤝 **Partage** : Permissions VIEW, EDIT, MANAGE avec expiration
626
+ - 🤖 **Traitement IA** : OCR, transcription audio, résumés, métadonnées
627
+ - 🖼️ **Prévisualisation** : Génération automatique de miniatures
628
+ - 🔐 **Hash SHA-256** : Intégrité et détection de doublons
629
+ - 📊 **Métadonnées** : Extraction automatique (taille, format, MIME type)
630
+ - 🔗 **Liens publics** : Partage avec token pour documents PUBLIC
631
+ - 📁 **Catégorisation** : Organisation par catégories et tags
632
+ - 🎫 **Statuts** : Workflow DRAFT → PENDING → VALIDATED → ARCHIVED
633
+
634
+ ## 🔒 Gestion des erreurs
635
+
636
+ Le SDK fournit des exceptions spécifiques pour une meilleure gestion des erreurs :
637
+
638
+ ```python
639
+ from base.error import (
640
+ SahgesError, # Erreur de base
641
+ SahgesClientConfigError, # Erreur de configuration
642
+ SahgesRequestError, # Erreur de requête HTTP
643
+ SahgesAuthenticationError, # Erreur d'authentification
644
+ SahgesValidationError # Erreur de validation de données
645
+ )
646
+
647
+ # Exemple de gestion complète
648
+ try:
649
+ response = client.login(payload={
650
+ "credential": "user@example.com",
651
+ "password": "mot_de_passe"
652
+ })
653
+
654
+ except SahgesAuthenticationError as e:
655
+ print(f"Échec de l'authentification: {e}")
656
+ print(f"Status HTTP: {e.status_code}")
657
+ print(f"Données de réponse: {e.response_data}")
658
+
659
+ except SahgesValidationError as e:
660
+ print(f"Erreur de validation: {e}")
661
+ # Les données fournies ne sont pas valides
662
+
663
+ except SahgesRequestError as e:
664
+ print(f"Erreur réseau ou serveur: {e}")
665
+ print(f"Status: {e.status_code}")
666
+
667
+ except SahgesClientConfigError as e:
668
+ print(f"Erreur de configuration du client: {e}")
669
+ # client_id ou client_secret manquant/invalide
670
+
671
+ except SahgesError as e:
672
+ print(f"Erreur SAHGES générale: {e}")
673
+
674
+ # Pour les documents
675
+ try:
676
+ document = client.create(
677
+ title="Document",
678
+ file_path="inexistant.pdf"
679
+ )
680
+ except FileNotFoundError as e:
681
+ print(f"Fichier introuvable: {e}")
682
+ ```
683
+
684
+ ### Codes d'erreur HTTP communs
685
+
686
+ - **400 Bad Request** : Données invalides → `SahgesValidationError`
687
+ - **401 Unauthorized** : Authentification échouée → `SahgesAuthenticationError`
688
+ - **403 Forbidden** : Permissions insuffisantes → `SahgesAuthenticationError`
689
+ - **404 Not Found** : Ressource introuvable → `SahgesRequestError`
690
+ - **429 Too Many Requests** : Rate limit dépassé → `SahgesRequestError`
691
+ - **500 Server Error** : Erreur serveur → `SahgesRequestError`
692
+
693
+ ## 🧪 Tests
694
+
695
+ Le SDK comprend une suite complète de tests unitaires et d'intégration.
696
+
697
+ ### Exécuter tous les tests
698
+
699
+ ```bash
700
+ pytest tests/ -v
701
+ ```
702
+
703
+ ### Tests avec couverture
704
+
705
+ ```bash
706
+ pytest --cov=src tests/
707
+ pytest --cov=src --cov-report=html tests/
708
+ ```
709
+
710
+ ### Tests spécifiques
711
+
712
+ ```bash
713
+ # Tests du module Auth
714
+ pytest tests/test_auth_login.py -v
715
+ pytest tests/test_auth_complete.py -v
716
+
717
+ # Tests du module Docs
718
+ pytest tests/test_docs_complete.py -v
719
+
720
+ # Tests de configuration
721
+ pytest tests/test_config.py -v
722
+
723
+ # Tests des décorateurs
724
+ pytest tests/test_decorators.py -v
725
+
726
+ # Tests des erreurs
727
+ pytest tests/test_errors.py -v
728
+ ```
729
+
730
+ ### Tests manuels
731
+
732
+ Des scripts de tests manuels sont disponibles pour tester en conditions réelles :
733
+
734
+ ```bash
735
+ # Test manuel de connexion
736
+ python tests/test_manual_login.py
737
+
738
+ # Test manuel de documents
739
+ python tests/test_manual_docs.py
740
+ ```
741
+
742
+ ### Configuration pour les tests
743
+
744
+ Créez un fichier `.env.test` :
745
+
746
+ ```env
747
+ SAHGES_CLIENT_ID=test_client_id
748
+ SAHGES_CLIENT_SECRET=test_client_secret
749
+ SAHGES_TEST_EMAIL=test@example.com
750
+ SAHGES_TEST_PASSWORD=test_password
751
+ SAHGES_AUTHENTICATION_BASE_URL=https://api-test.sahges.com
752
+ SAHGES_DOCS_BASE_URL=https://docs-test.sahges.com
753
+ ```
754
+
755
+ ## 📝 Développement
756
+
757
+ ### Installation pour le développement
758
+
759
+ ```bash
760
+ git clone https://gitlab.com/florianogomez/sahges-sdk.git
761
+ cd sahges-sdk
762
+ pip install -e ".[dev]"
763
+ ```
764
+
765
+ ### Structure du projet
766
+
767
+ ```
768
+ sahges-sdk/
769
+ ├── src/ # Code source
770
+ │ ├── auth/ # Module Auth
771
+ │ ├── docs/ # Module Docs
772
+ │ ├── base/ # Classes de base
773
+ │ ├── config/ # Configuration
774
+ │ ├── plugins/ # Extensions
775
+ │ └── utils/ # Utilitaires
776
+ ├── tests/ # Tests unitaires et d'intégration
777
+ │ ├── conftest.py # Configuration pytest
778
+ │ ├── test_auth_*.py # Tests Auth
779
+ │ ├── test_docs_*.py # Tests Docs
780
+ │ └── test_*.py # Tests divers
781
+ ├── context/ # Documentation de contexte (backend)
782
+ ├── pyproject.toml # Configuration du projet
783
+ ├── pytest.ini # Configuration pytest
784
+ ├── .env.example # Exemple de configuration
785
+ └── readme.md # Ce fichier
786
+ ```
787
+
788
+ ### Scripts utiles
789
+
790
+ Le fichier `manage.sh` fournit des commandes pratiques :
791
+
792
+ ```bash
793
+ # Lancer les tests
794
+ ./manage.sh test
795
+
796
+ # Vérifier le formatage
797
+ ./manage.sh lint
798
+
799
+ # Générer la documentation
800
+ ./manage.sh docs
801
+ ```
802
+
803
+ ### Conventions de code
804
+
805
+ - **Python 3.10+** : Utilisez les fonctionnalités modernes (type hints, match/case)
806
+ - **Type hints** : Annotations de type obligatoires
807
+ - **Docstrings** : Documentation Google style pour toutes les fonctions publiques
808
+ - **Validation** : Marshmallow pour tous les schémas
809
+ - **Logging** : Utilisez le logger configuré (`base.logger`)
810
+ - **Erreurs** : Levez des exceptions spécifiques (`SahgesAuthenticationError`, etc.)
811
+
812
+ ### Ajouter une nouvelle fonctionnalité
813
+
814
+ #### Pour le module Auth
815
+
816
+ 1. Créez la fonction dans le dossier approprié (`login/`, `logout/`, etc.)
817
+ 2. Définissez les schémas de validation (request/response)
818
+ 3. Ajoutez la route dans `routes.py`
819
+ 4. Attachez la méthode au client dans `auth_client.py`
820
+ 5. Écrivez les tests dans `tests/`
821
+
822
+ #### Pour le module Docs
823
+
824
+ 1. Créez la fonction dans le dossier approprié (`documents/`, `shares/`, etc.)
825
+ 2. Définissez les schémas si nécessaire
826
+ 3. Ajoutez la route dans `routes.py`
827
+ 4. Attachez la méthode au client dans `docs_client.py`
828
+ 5. Écrivez les tests dans `tests/`
829
+
830
+ ### Exemple d'ajout de fonctionnalité
831
+
832
+ ```python
833
+ # 1. Créer la fonction (src/auth/new_feature/feature.py)
834
+ from base.decorators import sahges_endpoint
835
+ from auth.routes import SahgesAuthenticationRoutes
836
+
837
+ @sahges_endpoint(
838
+ request_schema=FeatureRequestSchema,
839
+ response_schema=FeatureResponseSchema
840
+ )
841
+ def sahges_auth_new_feature(self, payload: dict):
842
+ """Description de la nouvelle fonctionnalité."""
843
+ endpoint = SahgesAuthenticationRoutes.new_feature.value
844
+ response = self.request(
845
+ method=endpoint.method,
846
+ path=endpoint.path,
847
+ json=payload
848
+ )
849
+ return response
850
+
851
+ # 2. Ajouter la route (src/auth/routes.py)
852
+ class SahgesAuthenticationRoutes(Enum):
853
+ # ... routes existantes ...
854
+ new_feature = Endpoint(
855
+ path=f"/{BASE}/new-feature",
856
+ method=HTTPMethod.POST
857
+ )
858
+
859
+ # 3. Attacher au client (src/auth/auth_client.py)
860
+ class SahgesAuthClient(BaseSahgesApiClient):
861
+ def __init__(self, client_id, client_secret):
862
+ # ... init existant ...
863
+ from auth.new_feature.feature import sahges_auth_new_feature
864
+ self.new_feature = MethodType(sahges_auth_new_feature, self)
865
+ ```
866
+
867
+ ## 🤝 Contribution
868
+
869
+ Les contributions sont les bienvenues ! Veuillez suivre ces étapes :
870
+
871
+ 1. Fork le projet
872
+ 2. Créez une branche pour votre fonctionnalité (`git checkout -b feature/AmazingFeature`)
873
+ 3. Committez vos changements (`git commit -m 'Add some AmazingFeature'`)
874
+ 4. Pushez vers la branche (`git push origin feature/AmazingFeature`)
875
+ 5. Ouvrez une Pull Request
876
+
877
+ ## 📄 Licence
878
+
879
+ Ce projet est sous licence MIT. Voir le fichier [LICENSE](LICENSE) pour plus de détails.
880
+
881
+ ## 📧 Contact
882
+
883
+ SAHGES - floriano.gomez@bj.sanlamallianz.com
884
+
885
+ Lien du projet : [https://gitlab.com/florianogomez/sahges-sdk](https://gitlab.com/florianogomez/sahges-sdk)
886
+
887
+ ## 🔗 Liens utiles
888
+
889
+ - [Documentation Auth complète](src/auth/readme.md) - Guide détaillé du module Auth
890
+ - [Documentation Docs complète](src/docs/readme.md) - Guide détaillé du module Docs
891
+ - [Documentation API Backend](https://api.sahges.com/docs)
892
+ - [Support](https://support.sahges.com)
893
+ - [GitLab Repository](https://gitlab.com/florianogomez/sahges-sdk)
894
+
895
+ ## 📚 Documentation des modules
896
+
897
+ ### Module Auth
898
+
899
+ Consultez [src/auth/readme.md](src/auth/readme.md) pour :
900
+ - Architecture détaillée du module Auth
901
+ - Description complète de chaque fonctionnalité (login, refresh, introspect, logout, reset password)
902
+ - Schémas de validation (AuthUserSchema, AuthOrganizationSchema)
903
+ - Exemples avancés
904
+ - Gestion des tokens JWT et refresh tokens
905
+ - Sécurité et bonnes pratiques
906
+
907
+ ### Module Docs
908
+
909
+ Consultez [src/docs/readme.md](src/docs/readme.md) pour :
910
+ - Architecture détaillée du module Docs
911
+ - CRUD complet des documents avec upload
912
+ - Système de partage et permissions
913
+ - Filtres et recherche avancée
914
+ - Traitement IA (OCR, transcription, résumés)
915
+ - Énumérations (visibilité, statut, permissions, formats)
916
+ - Schéma DocumentSchema complet
917
+ - Endpoints clients vs endpoints normaux
918
+ - Exemples d'utilisation avancés
919
+
920
+ ## ⚡ Quick Start
921
+
922
+ ### Installation rapide
923
+
924
+ ```bash
925
+ # Installer le SDK
926
+ pip install sahges-sdk
927
+
928
+ # Créer un fichier de test
929
+ cat > test_sahges.py << 'EOF'
930
+ from sahges_sdk.auth import SahgesAuthClient
931
+
932
+ client = SahgesAuthClient(
933
+ client_id="votre_client_id",
934
+ client_secret="votre_client_secret"
935
+ )
936
+
937
+ response = client.login(payload={
938
+ "credential": "user@example.com",
939
+ "password": "password"
940
+ })
941
+
942
+ print(f"✅ Connecté: {response['user']['email']}")
943
+ print(f"🔑 Token: {response['access_token'][:20]}...")
944
+ EOF
945
+
946
+ # Tester
947
+ python test_sahges.py
948
+ ```
949
+
950
+ ### Modules disponibles
951
+
952
+ Le SDK expose deux modules principaux :
953
+
954
+ ```python
955
+ # Module d'authentification
956
+ from sahges_sdk.auth import SahgesAuthClient
957
+
958
+ # Module de gestion documentaire
959
+ from sahges_sdk.docs import SahgesDocsClient
960
+
961
+ # Schémas de validation (si besoin)
962
+ from sahges_sdk.auth.schemas import AuthUserSchema
963
+ from sahges_sdk.docs.schemas import DocumentSchema
964
+
965
+ # Énumérations (si besoin)
966
+ from sahges_sdk.docs.enums import (
967
+ DocumentVisibilityEnum,
968
+ DocumentStatusEnum,
969
+ DocumentSharePermissionEnum
970
+ )
971
+ ```
972
+
973
+ ## 💡 Exemples d'utilisation courants
974
+
975
+ ### Authentification et gestion de session
976
+
977
+ ```python
978
+ from sahges_sdk.auth import SahgesAuthClient
979
+
980
+ client = SahgesAuthClient(client_id="xxx", client_secret="yyy")
981
+
982
+ # Connexion
983
+ login = client.login(payload={"credential": "user@example.com", "password": "pass"})
984
+ token = login["access_token"]
985
+
986
+ # Vérifier l'utilisateur
987
+ user = client.introspect(access_token=token)
988
+ print(f"Connecté: {user['email']}")
989
+
990
+ # Rafraîchir la session
991
+ new_tokens = client.refresh(payload={"refresh_token": login["refresh_token"]})
992
+ ```
993
+
994
+ ### Upload et partage de document
995
+
996
+ ```python
997
+ from sahges_sdk.docs import SahgesDocsClient
998
+ from datetime import datetime, timedelta
999
+
1000
+ client = SahgesDocsClient(client_id="xxx", client_secret="yyy")
1001
+
1002
+ # Upload
1003
+ doc = client.create(
1004
+ title="Contrat client",
1005
+ file_path="contrat.pdf",
1006
+ visibility="ORGANIZATION",
1007
+ tags=["contrat", "2025"]
1008
+ )
1009
+
1010
+ # Partager avec expiration
1011
+ share = client.share_create(payload={
1012
+ "document_id": doc['id'],
1013
+ "shared_with_auth_user_id": "colleague-uuid",
1014
+ "permission": "VIEW",
1015
+ "expires_at": datetime.now() + timedelta(days=7)
1016
+ })
1017
+ ```
1018
+
1019
+ ### Recherche et téléchargement
1020
+
1021
+ ```python
1022
+ from sahges_sdk.docs import SahgesDocsClient
1023
+
1024
+ client = SahgesDocsClient(client_id="xxx", client_secret="yyy")
1025
+
1026
+ # Recherche
1027
+ docs = client.list(payload={
1028
+ "search": "contrat",
1029
+ "status": "VALIDATED",
1030
+ "category": "legal"
1031
+ })
1032
+
1033
+ # Télécharger le premier résultat
1034
+ if docs:
1035
+ client.download(
1036
+ document_id=docs[0]['id'],
1037
+ output_path="contrat_downloaded.pdf"
1038
+ )
1039
+ ```
1040
+
1041
+ ## 🛡️ Sécurité
1042
+
1043
+ - **Tokens JWT** : Authentification stateless sécurisée
1044
+ - **Refresh tokens** : Renouvellement sans redemander le mot de passe
1045
+ - **HTTPS obligatoire** : Toutes les communications sont chiffrées
1046
+ - **Hash SHA-256** : Intégrité des fichiers garantie
1047
+ - **Validation stricte** : Tous les inputs sont validés (Marshmallow)
1048
+ - **Credentials** : Ne jamais logger ou commiter les secrets
1049
+ - **Rate limiting** : Protection contre les abus
1050
+ - **Permissions granulaires** : Contrôle d'accès fin (PRIVATE/ORGANIZATION/PUBLIC)
1051
+
1052
+ ## 🚦 Statuts et visibilité
1053
+
1054
+ ### Statuts des documents (DocumentStatusEnum)
1055
+
1056
+ - **DRAFT** : Brouillon, en cours de rédaction
1057
+ - **PENDING** : En attente de validation
1058
+ - **VALIDATED** : Validé et approuvé
1059
+ - **ARCHIVED** : Archivé (inactif)
1060
+
1061
+ ### Visibilité (DocumentVisibilityEnum)
1062
+
1063
+ - **PRIVATE** : Visible uniquement par le propriétaire
1064
+ - **ORGANIZATION** : Visible par tous les membres de l'organisation
1065
+ - **PUBLIC** : Accessible publiquement via token
1066
+
1067
+ ### Permissions de partage (DocumentSharePermissionEnum)
1068
+
1069
+ - **VIEW** : Lecture seule
1070
+ - **EDIT** : Lecture et modification
1071
+ - **MANAGE** : Lecture, modification et gestion des partages
1072
+
1073
+ ## ❓ FAQ
1074
+
1075
+ ### Comment obtenir des credentials API ?
1076
+
1077
+ Contactez l'équipe SAHGES à floriano.gomez@bj.sanlamallianz.com pour obtenir vos `client_id` et `client_secret`.
1078
+
1079
+ ### Quelle est la durée de vie des tokens ?
1080
+
1081
+ - **Access token** : 15 minutes (configurable)
1082
+ - **Refresh token** : 7 jours (configurable)
1083
+
1084
+ ### Quels formats de fichiers sont supportés ?
1085
+
1086
+ Tous les formats sont acceptés. Traitement spécial pour :
1087
+ - PDF : OCR et extraction de texte
1088
+ - Images : OCR et analyse IA
1089
+ - Audio/Vidéo : Transcription automatique
1090
+ - Office : Conversion et prévisualisation
1091
+
1092
+ ### Comment gérer les fichiers volumineux ?
1093
+
1094
+ Le système gère automatiquement les uploads en streaming. Vérifiez les limites de taille avec votre administrateur.
1095
+
1096
+ ### Puis-je utiliser le SDK en production ?
1097
+
1098
+ Oui, le SDK est conçu pour la production avec gestion d'erreurs robuste, logging, et retry automatique.
1099
+
1100
+ ### Comment contribuer ?
1101
+
1102
+ Voir la section [Contribution](#🤝-contribution) ci-dessous.
1103
+