saamfi-sdk 0.1.0__py3-none-any.whl
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.
Potentially problematic release.
This version of saamfi-sdk might be problematic. Click here for more details.
- saamfi_sdk/__init__.py +49 -0
- saamfi_sdk/client.py +311 -0
- saamfi_sdk/exceptions.py +70 -0
- saamfi_sdk/models.py +141 -0
- saamfi_sdk/py.typed +2 -0
- saamfi_sdk/services/__init__.py +18 -0
- saamfi_sdk/services/auth.py +90 -0
- saamfi_sdk/services/base.py +45 -0
- saamfi_sdk/services/institutions.py +113 -0
- saamfi_sdk/services/systems.py +62 -0
- saamfi_sdk/services/token.py +155 -0
- saamfi_sdk/services/users.py +147 -0
- saamfi_sdk-0.1.0.dist-info/METADATA +257 -0
- saamfi_sdk-0.1.0.dist-info/RECORD +17 -0
- saamfi_sdk-0.1.0.dist-info/WHEEL +5 -0
- saamfi_sdk-0.1.0.dist-info/licenses/LICENSE +21 -0
- saamfi_sdk-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: saamfi-sdk
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: SDK de Python para conectarse a los servicios SAAMFI - Autenticacion y Autorizacion
|
|
5
|
+
Author-email: Universidad ICESI <dev@icesi.edu.co>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/icesi-dev/saamfi-sdk-python
|
|
8
|
+
Project-URL: Documentation, https://saamfi-sdk-python.readthedocs.io
|
|
9
|
+
Project-URL: Repository, https://github.com/icesi-dev/saamfi-sdk-python.git
|
|
10
|
+
Project-URL: Issues, https://github.com/icesi-dev/saamfi-sdk-python/issues
|
|
11
|
+
Keywords: saamfi,authentication,authorization,jwt,security,sdk
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
22
|
+
Classifier: Topic :: Security
|
|
23
|
+
Requires-Python: >=3.8
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
License-File: LICENSE
|
|
26
|
+
Requires-Dist: requests>=2.31.0
|
|
27
|
+
Requires-Dist: PyJWT>=2.8.0
|
|
28
|
+
Requires-Dist: cryptography>=41.0.0
|
|
29
|
+
Requires-Dist: pydantic>=2.5.0
|
|
30
|
+
Requires-Dist: python-dotenv>=1.0.0
|
|
31
|
+
Provides-Extra: dev
|
|
32
|
+
Requires-Dist: pytest>=7.4.0; extra == "dev"
|
|
33
|
+
Requires-Dist: pytest-cov>=4.1.0; extra == "dev"
|
|
34
|
+
Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
|
|
35
|
+
Requires-Dist: black>=23.0.0; extra == "dev"
|
|
36
|
+
Requires-Dist: flake8>=6.0.0; extra == "dev"
|
|
37
|
+
Requires-Dist: mypy>=1.5.0; extra == "dev"
|
|
38
|
+
Requires-Dist: isort>=5.12.0; extra == "dev"
|
|
39
|
+
Provides-Extra: fastapi
|
|
40
|
+
Requires-Dist: fastapi>=0.104.0; extra == "fastapi"
|
|
41
|
+
Dynamic: license-file
|
|
42
|
+
|
|
43
|
+
## Saamfi SDK para Python
|
|
44
|
+
|
|
45
|
+
Cliente oficial en Python para integrar sistemas con los servicios de autenticacion y autorizacion de Saamfi. Este SDK expone las mismas operaciones disponibles en la libreria Java (`SaamfiDelegate`) y simplifica la validacion de tokens JWT, la autenticacion de usuarios y la consulta de informacion institucional.
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Instalacion
|
|
50
|
+
|
|
51
|
+
- **Desde PyPI**
|
|
52
|
+
```bash
|
|
53
|
+
pip install saamfi-sdk
|
|
54
|
+
```
|
|
55
|
+
- **Desde el codigo fuente**
|
|
56
|
+
```bash
|
|
57
|
+
git clone https://github.com/saamfi/saamfi-sdk-python.git
|
|
58
|
+
cd saamfi-sdk-python
|
|
59
|
+
pip install -e .
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Configura las siguientes variables de entorno antes de usar el cliente (por ejemplo en un archivo `.env`):
|
|
63
|
+
|
|
64
|
+
- `SAAMFI_BASE_URL`: URL base del servicio Saamfi (`https://api.saamfi.com`).
|
|
65
|
+
- `SAAMFI_SYS_ID`: Identificador del sistema o tenant asignado por Saamfi.
|
|
66
|
+
- `SAAMFI_TENANT_ID` *(opcional)*: Identificador de institución (para endpoints como `/institutions/{instid}/params`).
|
|
67
|
+
- `SAAMFI_CLIENT_ID` y `SAAMFI_CLIENT_SECRET` *(opcionales)*: Credenciales del sistema si tu integración las requiere.
|
|
68
|
+
- `SAAMFI_TEST_USERNAME` y `SAAMFI_TEST_PASSWORD` *(solo para pruebas locales)*: Usuario demo del sandbox.
|
|
69
|
+
|
|
70
|
+
> El cliente mantiene compatibilidad con las variables antiguas `SAAMFI_URL`, `SAAMFI_SYSTEM_ID` y `SAAMFI_INST_ID`.
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Quickstart
|
|
75
|
+
|
|
76
|
+
```python
|
|
77
|
+
from saamfi_sdk import SaamfiClient
|
|
78
|
+
|
|
79
|
+
client = SaamfiClient() # Usa SAAMFI_BASE_URL y SAAMFI_SYS_ID desde el entorno
|
|
80
|
+
|
|
81
|
+
response = client.login("usuario@example.com", "clave-segura")
|
|
82
|
+
if response:
|
|
83
|
+
print(f"Token: {response.access_token}")
|
|
84
|
+
token_info = client.validate_token(response.access_token)
|
|
85
|
+
print(f"Roles: {token_info.roles}")
|
|
86
|
+
else:
|
|
87
|
+
print("Credenciales invalidas")
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## Sandbox local con docker compose
|
|
93
|
+
|
|
94
|
+
1. Levanta el entorno local de Saamfi con `docker compose` (puerto `9091` según la configuración compartida).
|
|
95
|
+
2. Crea un archivo `.env` junto al proyecto del SDK con las variables:
|
|
96
|
+
```
|
|
97
|
+
SAAMFI_BASE_URL=http://localhost:9091/iaslab/saamfiapi
|
|
98
|
+
SAAMFI_SYS_ID=8
|
|
99
|
+
SAAMFI_CLIENT_ID=8
|
|
100
|
+
SAAMFI_CLIENT_SECRET=qYr6-CxZP9t4vN2eFM1sR4gL
|
|
101
|
+
SAAMFI_TENANT_ID=1
|
|
102
|
+
SAAMFI_TEST_USERNAME=testuser
|
|
103
|
+
SAAMFI_TEST_PASSWORD=password123
|
|
104
|
+
```
|
|
105
|
+
3. Ejecuta el script de ejemplo:
|
|
106
|
+
```bash
|
|
107
|
+
python examples/sandbox_demo.py
|
|
108
|
+
```
|
|
109
|
+
Verás el flujo completo: descarga de clave pública, descubrimiento de sistemas/instituciones, autenticación del usuario demo, validación del JWT y consultas protegidas.
|
|
110
|
+
|
|
111
|
+
> Consulta los logs del backend en `saamfi-rest/logs/saamfi.log` o mediante `GET /logs/` (requiere rol `Query-server-logs`) para corroborar las operaciones.
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## Ejemplos por funcionalidad
|
|
116
|
+
|
|
117
|
+
Cada metodo del cliente refleja una operacion del servicio Saamfi. Los siguientes fragmentos muestran el flujo completo con un token valido (`token`):
|
|
118
|
+
|
|
119
|
+
- **Obtener llave publica**
|
|
120
|
+
```python
|
|
121
|
+
public_key = client.get_public_key()
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
- **Autenticar usuario**
|
|
125
|
+
```python
|
|
126
|
+
login = client.login("usuario@example.com", "clave")
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
- **Validar token y extraer datos**
|
|
130
|
+
```python
|
|
131
|
+
token_info = client.validate_token(token)
|
|
132
|
+
print(token_info.username, token_info.roles)
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
- **Roles desde un JWT**
|
|
136
|
+
```python
|
|
137
|
+
roles = client.get_roles_from_jwt(token)
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
- **Informacion detallada de usuario**
|
|
141
|
+
```python
|
|
142
|
+
user = client.get_user_info(token, user_id=12345)
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
- **Buscar usuario por username**
|
|
146
|
+
```python
|
|
147
|
+
user = client.get_user_by_username(token, "john.doe")
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
- **Buscar usuarios por documentos**
|
|
151
|
+
```python
|
|
152
|
+
users = client.get_users_by_document(token, ["100200300", "999888777"])
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
- **Obtener usuarios por lista de IDs**
|
|
156
|
+
```python
|
|
157
|
+
users_json = client.get_users_from_list(token, [1, 2, 3])
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
- **Busqueda generica por parametro y valor**
|
|
161
|
+
```python
|
|
162
|
+
result_json = client.get_users_by_param_and_value(token, "email", "example.com")
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
- **Consultar institucion por NIT**
|
|
166
|
+
```python
|
|
167
|
+
institution_json = client.get_institution_by_nit(token, "900123456-7")
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
- **Consultar instituciones por IDs**
|
|
171
|
+
```python
|
|
172
|
+
institutions_json = client.get_institutions_by_ids(token, [10, 20, 30])
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
- **Listado público de sistemas e instituciones**
|
|
176
|
+
```python
|
|
177
|
+
systems = client.list_public_systems()
|
|
178
|
+
institutions = client.list_public_institutions()
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
- **Parámetros de institución**
|
|
182
|
+
```python
|
|
183
|
+
params = client.get_institution_params(token) # Usa SAAMFI_TENANT_ID por defecto
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
- **Roles configurados para un sistema**
|
|
187
|
+
```python
|
|
188
|
+
roles = client.get_system_roles(token) # Usa SAAMFI_SYS_ID por defecto
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
## Referencia de API
|
|
194
|
+
|
|
195
|
+
### Clases principales
|
|
196
|
+
|
|
197
|
+
| Clase | Descripcion |
|
|
198
|
+
| ----- | ----------- |
|
|
199
|
+
| `SaamfiClient` | Cliente principal; gestiona autenticacion, validacion y consultas. |
|
|
200
|
+
| `LoginBody` | Modelo para solicitudes de login. |
|
|
201
|
+
| `LoginResponse` | Respuesta de autenticacion exitosa. |
|
|
202
|
+
| `UserInfo` | Informacion detallada de usuario. |
|
|
203
|
+
| `UserDetailToken` | Datos extraidos de un JWT validado. |
|
|
204
|
+
|
|
205
|
+
### Metodos clave de `SaamfiClient`
|
|
206
|
+
|
|
207
|
+
| Metodo | Entrada | Salida | Nota |
|
|
208
|
+
| ------ | ------- | ------ | ---- |
|
|
209
|
+
| `get_public_key()` | - | `RSAPublicKey` | Obtiene y cachea la llave publica. |
|
|
210
|
+
| `login(username, password)` | `str`, `str` | `LoginResponse | None` | Autentica usuario. |
|
|
211
|
+
| `get_roles_from_jwt(auth_token)` | `str` | `List[str]` | Extrae claim `role`. |
|
|
212
|
+
| `validate_token(auth_token)` | `str` | `UserDetailToken` | Valida firma y claims. |
|
|
213
|
+
| `get_user_info(auth_token, user_id)` | `str`, `int` | `UserInfo | None` | Consulta usuario por ID. |
|
|
214
|
+
| `get_user_by_username(auth_token, username)` | `str`, `str` | `dict | None` | Consulta POST por username. |
|
|
215
|
+
| `get_users_by_document(auth_token, user_documents)` | `str`, `List[str]` | `List[dict]` | Busca por multiples documentos. |
|
|
216
|
+
| `get_users_from_list(auth_token, user_ids)` | `str`, `List[int]` | `str | None` | JSON con usuarios por ID. |
|
|
217
|
+
| `get_users_by_param_and_value(auth_token, param, value)` | `str`, `str`, `str` | `str | None` | Filtro generico usando query string. |
|
|
218
|
+
| `get_institution_by_nit(auth_token, nit)` | `str`, `str` | `str | None` | Consulta institucion por NIT. |
|
|
219
|
+
| `get_institutions_by_ids(auth_token, institution_ids)` | `str`, `List[int]` | `str | None` | Consulta masiva por IDs. |
|
|
220
|
+
| `list_public_institutions()` | - | `List[dict] | None` | Descubrimiento de instituciones disponibles. |
|
|
221
|
+
| `get_institution_params(auth_token, institution_id=None)` | `str`, `Optional[int]` | `dict | None` | Obtiene parámetros de configuración institucional. |
|
|
222
|
+
| `list_public_systems()` | - | `List[dict] | None` | Descubrimiento de sistemas publicados. |
|
|
223
|
+
| `get_system_roles(auth_token, system_id=None)` | `str`, `Optional[int]` | `List[dict] | None` | Roles disponibles para un sistema. |
|
|
224
|
+
|
|
225
|
+
> Consulta los docstrings en `saamfi_sdk/client.py` para conocer detalles, equivalencias con la version Java y ejemplos adicionales.
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## Manejo de errores
|
|
230
|
+
|
|
231
|
+
Todas las excepciones del SDK heredan de `SaamfiException`:
|
|
232
|
+
|
|
233
|
+
| Excepcion | Cuándo ocurre |
|
|
234
|
+
| --------- | ------------- |
|
|
235
|
+
| `SaamfiAuthenticationError` | Credenciales invalidas o token sin permisos. |
|
|
236
|
+
| `SaamfiTokenValidationError` | Token expirado, mal formado o con claims faltantes. |
|
|
237
|
+
| `SaamfiConnectionError` | Problemas de red o respuestas no exitosas del backend. |
|
|
238
|
+
| `SaamfiInvalidSystemError` | El token pertenece a otro `system_id`. |
|
|
239
|
+
| `SaamfiUnauthorizedError` | El usuario autenticado no tiene permisos para la operacion. |
|
|
240
|
+
| `SaamfiNotFoundError` | El recurso solicitado no existe. |
|
|
241
|
+
|
|
242
|
+
```python
|
|
243
|
+
from saamfi_sdk import SaamfiClient
|
|
244
|
+
from saamfi_sdk.exceptions import SaamfiConnectionError, SaamfiAuthenticationError
|
|
245
|
+
|
|
246
|
+
client = SaamfiClient()
|
|
247
|
+
|
|
248
|
+
try:
|
|
249
|
+
login = client.login("usuario@example.com", "clave")
|
|
250
|
+
except SaamfiConnectionError as exc:
|
|
251
|
+
print(f"No es posible comunicar con Saamfi: {exc}")
|
|
252
|
+
except SaamfiAuthenticationError:
|
|
253
|
+
print("Credenciales invalidas")
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
---
|
|
257
|
+
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
saamfi_sdk/__init__.py,sha256=rC1tAAgJYOJAO1j3kGENyzqrtnXZH4GwyFyT_k4hmQA,1284
|
|
2
|
+
saamfi_sdk/client.py,sha256=Nwhv0giWBCyhs0GEeQUgbk6CuYe5yTn2sIt2562yPy8,11766
|
|
3
|
+
saamfi_sdk/exceptions.py,sha256=iVKCHbNlNEjw9foY0TV5PQMY0vrGDJY3KTLDw7oaCEo,2253
|
|
4
|
+
saamfi_sdk/models.py,sha256=shsY_Z-0Kp6Lle5TZr-PWZ4daZpbPVRwYkx2DyhJZiI,4602
|
|
5
|
+
saamfi_sdk/py.typed,sha256=daEdpEyAJIa8b2VkCqSKcw8PaExcB6Qro80XNes_sHA,2
|
|
6
|
+
saamfi_sdk/services/__init__.py,sha256=7xm0b5RLP6GNFXNj2bX7Yd16otGmffF9y_30B9jDZ6g,431
|
|
7
|
+
saamfi_sdk/services/auth.py,sha256=OLjRZOXiCh9L0yBaDioQ54s1yeFouG3_sRtyzvxeuUY,3171
|
|
8
|
+
saamfi_sdk/services/base.py,sha256=I4xqcOYup3unI5b9JnWbXHDE11vJfOhS8shw6zMFMA0,1555
|
|
9
|
+
saamfi_sdk/services/institutions.py,sha256=RmnhzrUkiO5Xc2hQ8Zkljaj472LuA-Bn8gvxlQBR9oY,3980
|
|
10
|
+
saamfi_sdk/services/systems.py,sha256=FD53D4b9smk_qzStyQsMJZfqUCaaSoyCUGLqPcxUd30,2053
|
|
11
|
+
saamfi_sdk/services/token.py,sha256=xE1pIdYb6voxI1pSeCap7ZBfj9T1kdKOFTSNM8pcvgE,6139
|
|
12
|
+
saamfi_sdk/services/users.py,sha256=bYWPcGOExtz0b4IZ3Ljuha2mX58j67ZmXkfznsY1QC4,5490
|
|
13
|
+
saamfi_sdk-0.1.0.dist-info/licenses/LICENSE,sha256=6iltbovbpbh9UIcMAQ4YaIe_XuhmiQHACLKGL5dXm70,1074
|
|
14
|
+
saamfi_sdk-0.1.0.dist-info/METADATA,sha256=-E-RGqe8R1nf81p2QrZfGkPMN1-ibIxRVWEGNWti4nE,9653
|
|
15
|
+
saamfi_sdk-0.1.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
16
|
+
saamfi_sdk-0.1.0.dist-info/top_level.txt,sha256=jF4kal_I5anaAgY1b4vS35XgME_BgJIPJK30WYndg9Q,11
|
|
17
|
+
saamfi_sdk-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Universidad ICESI
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
saamfi_sdk
|