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.
- sahges_sdk-0.1.1/PKG-INFO +1103 -0
- sahges_sdk-0.1.1/README.md +1084 -0
- sahges_sdk-0.1.1/pyproject.toml +57 -0
- sahges_sdk-0.1.1/setup.cfg +4 -0
- sahges_sdk-0.1.1/src/sahges_sdk/__init__.py +3 -0
- sahges_sdk-0.1.1/src/sahges_sdk/auth/__init__.py +5 -0
- sahges_sdk-0.1.1/src/sahges_sdk/auth/auth_client.py +58 -0
- sahges_sdk-0.1.1/src/sahges_sdk/auth/introspect/introspect.py +41 -0
- sahges_sdk-0.1.1/src/sahges_sdk/auth/login/login_attempt.py +45 -0
- sahges_sdk-0.1.1/src/sahges_sdk/auth/login/login_attempt_schema.py +15 -0
- sahges_sdk-0.1.1/src/sahges_sdk/auth/login/login_response_schema.py +17 -0
- sahges_sdk-0.1.1/src/sahges_sdk/auth/login/refresh_attempt.py +43 -0
- sahges_sdk-0.1.1/src/sahges_sdk/auth/login/refresh_attempt_schema.py +24 -0
- sahges_sdk-0.1.1/src/sahges_sdk/auth/logout/logout.py +38 -0
- sahges_sdk-0.1.1/src/sahges_sdk/auth/reset_password/reset_password.py +138 -0
- sahges_sdk-0.1.1/src/sahges_sdk/auth/reset_password_schemas.py +60 -0
- sahges_sdk-0.1.1/src/sahges_sdk/auth/routes.py +31 -0
- sahges_sdk-0.1.1/src/sahges_sdk/auth/schemas/auth_organization_schema.py +21 -0
- sahges_sdk-0.1.1/src/sahges_sdk/auth/schemas/auth_user_schema.py +24 -0
- sahges_sdk-0.1.1/src/sahges_sdk/base/__init__.py +1 -0
- sahges_sdk-0.1.1/src/sahges_sdk/base/client.py +148 -0
- sahges_sdk-0.1.1/src/sahges_sdk/base/decorators.py +86 -0
- sahges_sdk-0.1.1/src/sahges_sdk/base/endpoint.py +20 -0
- sahges_sdk-0.1.1/src/sahges_sdk/base/enums.py +17 -0
- sahges_sdk-0.1.1/src/sahges_sdk/base/error.py +55 -0
- sahges_sdk-0.1.1/src/sahges_sdk/base/logger.py +27 -0
- sahges_sdk-0.1.1/src/sahges_sdk/config/__init__.py +44 -0
- sahges_sdk-0.1.1/src/sahges_sdk/docs/__init__.py +5 -0
- sahges_sdk-0.1.1/src/sahges_sdk/docs/clients/__init__.py +13 -0
- sahges_sdk-0.1.1/src/sahges_sdk/docs/clients/create.py +69 -0
- sahges_sdk-0.1.1/src/sahges_sdk/docs/clients/download.py +37 -0
- sahges_sdk-0.1.1/src/sahges_sdk/docs/clients/find.py +28 -0
- sahges_sdk-0.1.1/src/sahges_sdk/docs/clients/list.py +31 -0
- sahges_sdk-0.1.1/src/sahges_sdk/docs/docs_client.py +86 -0
- sahges_sdk-0.1.1/src/sahges_sdk/docs/documents/__init__.py +19 -0
- sahges_sdk-0.1.1/src/sahges_sdk/docs/documents/create.py +69 -0
- sahges_sdk-0.1.1/src/sahges_sdk/docs/documents/create_schema.py +18 -0
- sahges_sdk-0.1.1/src/sahges_sdk/docs/documents/delete.py +21 -0
- sahges_sdk-0.1.1/src/sahges_sdk/docs/documents/download.py +37 -0
- sahges_sdk-0.1.1/src/sahges_sdk/docs/documents/find.py +28 -0
- sahges_sdk-0.1.1/src/sahges_sdk/docs/documents/list.py +29 -0
- sahges_sdk-0.1.1/src/sahges_sdk/docs/documents/list_schema.py +19 -0
- sahges_sdk-0.1.1/src/sahges_sdk/docs/documents/update.py +33 -0
- sahges_sdk-0.1.1/src/sahges_sdk/docs/documents/update_schema.py +17 -0
- sahges_sdk-0.1.1/src/sahges_sdk/docs/documents/visibility.py +33 -0
- sahges_sdk-0.1.1/src/sahges_sdk/docs/documents/visibility_schema.py +13 -0
- sahges_sdk-0.1.1/src/sahges_sdk/docs/enums.py +42 -0
- sahges_sdk-0.1.1/src/sahges_sdk/docs/routes.py +50 -0
- sahges_sdk-0.1.1/src/sahges_sdk/docs/schemas/__init__.py +5 -0
- sahges_sdk-0.1.1/src/sahges_sdk/docs/schemas/document_schema.py +56 -0
- sahges_sdk-0.1.1/src/sahges_sdk/docs/shares/__init__.py +11 -0
- sahges_sdk-0.1.1/src/sahges_sdk/docs/shares/create.py +32 -0
- sahges_sdk-0.1.1/src/sahges_sdk/docs/shares/delete.py +29 -0
- sahges_sdk-0.1.1/src/sahges_sdk/docs/shares/list.py +28 -0
- sahges_sdk-0.1.1/src/sahges_sdk/docs/shares/share_schema.py +30 -0
- sahges_sdk-0.1.1/src/sahges_sdk/plugins/marshmallow/__init__.py +11 -0
- sahges_sdk-0.1.1/src/sahges_sdk/plugins/marshmallow/fields.py +468 -0
- sahges_sdk-0.1.1/src/sahges_sdk/test.py +42 -0
- sahges_sdk-0.1.1/src/sahges_sdk/utils/__init__.py +5 -0
- sahges_sdk-0.1.1/src/sahges_sdk/utils/validators.py +69 -0
- sahges_sdk-0.1.1/src/sahges_sdk.egg-info/PKG-INFO +1103 -0
- sahges_sdk-0.1.1/src/sahges_sdk.egg-info/SOURCES.txt +72 -0
- sahges_sdk-0.1.1/src/sahges_sdk.egg-info/dependency_links.txt +1 -0
- sahges_sdk-0.1.1/src/sahges_sdk.egg-info/requires.txt +11 -0
- sahges_sdk-0.1.1/src/sahges_sdk.egg-info/top_level.txt +1 -0
- sahges_sdk-0.1.1/tests/test_auth_complete.py +265 -0
- sahges_sdk-0.1.1/tests/test_auth_login.py +154 -0
- sahges_sdk-0.1.1/tests/test_client.py +66 -0
- sahges_sdk-0.1.1/tests/test_config.py +24 -0
- sahges_sdk-0.1.1/tests/test_decorators.py +74 -0
- sahges_sdk-0.1.1/tests/test_docs_complete.py +377 -0
- sahges_sdk-0.1.1/tests/test_errors.py +54 -0
- sahges_sdk-0.1.1/tests/test_manual_docs.py +635 -0
- 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
|
+
[](https://www.python.org/downloads/)
|
|
25
|
+
[](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
|
+
|