osdental-mobile-library
Librería interna compartida para los microservicios móviles de OSDental. Provee conexión a base de datos, autenticación vía gRPC, cliente HTTP, decoradores de auditoría y manejo de excepciones estandarizado.
Versión: 0.3.1 · Python: ≥ 3.10
Instalación
pip install osdental-mb-library
Variables de entorno requeridas
| Variable | Descripción |
|---|---|
APPLICATIONINSIGHTS_CONNECTION_STRING |
Connection string de Azure Monitor |
SECURITY_GRPC_ENDPOINT |
Host del servicio de autenticación gRPC |
GRPC_SECURE |
true para canal TLS, false para inseguro |
ENVIRONMENT |
Nombre del entorno (dev, staging, prod) |
MICROSERVICE_NAME |
Nombre del microservicio que usa la librería |
MICROSERVICE_VERSION |
Versión del microservicio |
Módulos
Database.Connection
Singleton asíncrono para conexiones SQL Server via SQLAlchemy. Soporta connection string directa o Azure Managed Identity.
from osdentalMobileLibrary.Database.Connection import Connection
# Con connection string
db = Connection(db_url="mssql+aioodbc://user:pass@server/db?driver=...")
# Con Azure Managed Identity
db = Connection(db_url="mssql+aioodbc://server/db?...", use_managed_identity=True)
Métodos disponibles:
# Retorna el primer valor escalar
value = await db.execute_query_return_first_value(query, params)
# Retorna lista de dicts (o un dict si fetchone=True)
rows = await db.execute_query_return_data(query, params, fetchone=False)
# Ejecuta y valida STATUS_CODE, retorna STATUS_MESSAGE
msg = await db.execute_query_return_message(query, params, code="SUCCESS")
# Ejecuta sin retorno, o valida STATUS_CODE si se provee code
await db.execute_query(query, params, code=None)
# Ejecuta múltiples queries en una sola transacción
result = await db.execute_transaction_queries(
data=[{"query": "...", "params": {}, "code": "SUCCESS"}],
return_data=False
)
El pool está configurado con
pool_size=20,max_overflow=40,pool_recycle=3600.
Decorators
AuditLogMobile
Decorador para resolvers GraphQL (Strawberry). Valida el Bearer token vía gRPC, crea un span de OpenTelemetry en Azure Monitor y bloquea requests no autenticados.
from osdentalMobileLibrary.Decorators.AuditLogMobile import AuditLogMobile
@strawberry.type
class Query:
@strawberry.field
@AuditLogMobile()
async def get_patient(self, info: Info) -> Patient:
...
El decorador espera que info.context contenga un objeto request con headers Authorization (Bearer) y Agent-Mobile.
grpc_retry / rest_retry
Reintentos automáticos con backoff exponencial (3 intentos, espera 1–4 s).
from osdentalMobileLibrary.Decorators.Retry import grpc_retry, rest_retry
@grpc_retry # reintenta en grpc.RpcError
async def call_grpc(...): ...
@rest_retry # reintenta en httpx.RequestError
async def call_rest(...): ...
ExternalHttp.APIClient
Cliente HTTP asíncrono (extiende httpx.AsyncClient) con retry automático y logging a Service Bus.
from osdentalMobileLibrary.ExternalHttp.Client import APIClient
async with APIClient() as client:
# REST
data = await client.rest_request("GET", "https://api.example.com/resource")
# GraphQL
data = await client.graphql_request(
url="https://api.example.com/graphql",
consult="query { patients { id } }",
variables={},
headers={"Authorization": "Bearer ..."}
)
Cada llamada envía automáticamente el request y el response al Service Bus para auditoría.
Grpc.Client.AuthClient
Cliente gRPC asíncrono para validar tokens contra el servicio de autenticación.
from osdentalMobileLibrary.Grpc.Client.AuthClient import AuthClient
async with AuthClient() as auth:
response = await auth.validate_auth_token(
bearer_token="eyJ...",
agent_mobile="ios-v2.1"
)
if not response.Data:
# Token inválido o sin acceso
...
Exception
Jerarquía de excepciones tipadas. Todas extienden OSDException e incluyen message, error y status_code.
| Excepción | Uso |
|---|---|
OSDException |
Base — error genérico de la aplicación |
UnauthorizedException |
Token inválido o sin permisos |
RequestDataException |
Parámetros de request inválidos |
DatabaseException |
Error en ejecución de query |
HttpClientException |
Error en llamada HTTP externa |
AzureException |
Error en servicios Azure |
ValidationDataException |
Error de validación de datos |
MissingFieldException |
Campo requerido ausente |
InvalidFormatException |
Formato de dato incorrecto |
UnexpectedException |
Error inesperado genérico |
from osdentalMobileLibrary.Exception.ControlledException import DatabaseException
raise DatabaseException(message="Query falló", error=str(e))
Estructura del proyecto
src/osdentalMobileLibrary/
├── Database/ # Conexión async a SQL Server
├── Decorators/ # AuditLogMobile, grpc_retry, rest_retry
├── Exception/ # Excepciones tipadas
├── ExternalHttp/ # APIClient HTTP/GraphQL
├── Grpc/
│ ├── Base/ # GrpcClientBase
│ ├── Client/ # AuthClient
│ └── Generated/ # Protobuf generado
├── Models/ # Response model
├── ServicesBus/ # TaskQueue para Service Bus
└── Shared/ # Config, Logger, Enums, Utils, Azure
Build y distribución
python -m build
# Genera dist/osdental_mb_library-x.x.x-py3-none-any.whl
Metadata
Release files for osdental-mb-library 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| osdental_mb_library-1.0.0.tar.gz | 27.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| osdental_mb_library-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 63.0 kB
Release files / osdental_mb_library-1.0.0.tar.gz
| Download URL | osdental_mb_library-1.0.0.tar.gz |
|---|---|
| Size | 27.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ed1ca1dfcac8eae4608240f7ae71073f1517c384ea0622be5055434f3e217c16
|
|
BLAKE2b-256 checksum How to use checksums |
d808d5aaa639c40dc624e87d4c785e4c0645823b543cf2ac9bb3578c54af1879
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.7
|
Release files / osdental_mb_library-1.0.0-py3-none-any.whl
| Download URL | osdental_mb_library-1.0.0-py3-none-any.whl |
|---|---|
| Size | 35.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
4fc3c4361ef97cd3329ea59c790d12a5f6379a49a0088b444c6f464185d89a2e
|
|
BLAKE2b-256 checksum How to use checksums |
c1d11fc9f51b1be721c727c3ee4d34b45c9700621c4c8bf069e6cc4bb92771b3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.7
|