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 0.3.3
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-0.3.3.tar.gz | 27.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| osdental_mb_library-0.3.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 62.6 kB
Release files / osdental_mb_library-0.3.3.tar.gz
| Download URL | osdental_mb_library-0.3.3.tar.gz |
|---|---|
| Size | 27.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
356aa1f0ba268fb5982a891b7be9eceb588a12ecbd50c47a33b1a9604e3fca50
|
|
BLAKE2b-256 checksum How to use checksums |
bbb65acaa3ba25a9c964a6914d9d46bc5111179dd8d480aef0d0c4aa69cefe4d
|
| 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-0.3.3-py3-none-any.whl
| Download URL | osdental_mb_library-0.3.3-py3-none-any.whl |
|---|---|
| Size | 35.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d6cf487cfda5c4fceac701c9c5863143c7252782669f6371015b6277c9b0d19e
|
|
BLAKE2b-256 checksum How to use checksums |
034cd97c1653f5a40cd7f62ac318eea23e9b87550f51faadf0a1970bebd585ce
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.7
|