Bridge SOAP Services for SIAT Bolivia
Project description
Sincpro SIAT SOAP SDK
SDK para consumir servicios SOAP del SIAT (Sistema Integral de Facturación) de Bolivia. Implementado con Sincpro Framework 3.0 siguiendo arquitectura hexagonal y el patrón Unified Bus.
📋 Sobre el Proyecto
Este SDK proporciona una interfaz Python completa para interactuar con los servicios de facturación electrónica del SIAT de Bolivia, cubriendo:
- ✅ Facturación electrónica y computarizada
- ✅ Múltiples sectores (compra-venta, hotel, hospital, educativo, alquiler, etc.)
- ✅ Gestión de contingencias y eventos significativos
- ✅ Notas de crédito y débito
- ✅ Sincronización de catálogos
- ✅ Validación y firma digital de documentos XML
- ✅ Facturación masiva
Características principales
- Arquitectura modular: Basado en Sincpro Framework con arquitectura hexagonal
- Type-safe: Validación completa con Pydantic DTOs
- Gestión automática: CUFD (renovación diaria) y CUIS por punto de venta
- Context manager: Propagación automática de metadatos (token, ambiente, etc.)
- Multi-ambiente: Soporte para entornos de producción y piloto
- Tests completos: Suite de tests siguiendo las 9 etapas de certificación SIAT
📄 Licencia
Este proyecto está licenciado bajo LICENCIA EMPRESARIAL DE USO DE SOFTWARE de Sincpro S.R.L.
Resumen de términos
- ✅ Licencia no exclusiva e intransferible
- ✅ Uso limitado según contrato de licencia
- ❌ Prohibido: copiar, modificar o distribuir sin autorización
- ⚠️ El uso no autorizado activa mecanismos de seguridad
- ⚖️ Protegido por leyes de propiedad intelectual
Importante: El uso del Software requiere una licencia válida emitida por Sincpro S.R.L. El uso no autorizado puede resultar en sanciones legales y activación de medidas de protección.
Para más detalles, consulta el archivo LICENSE.md.
Pre-Requirements
- Python 3.12+
- Poetry para gestión de dependencias
- Virtualenv configurado (el proyecto usa virtualenv in-project)
Configuración de Poetry
El proyecto incluye un poetry.toml para crear el virtualenv dentro del proyecto:
[virtualenvs]
create = true
in-project = true
Esto crea el entorno virtual en .venv/ dentro del directorio del proyecto, facilitando la gestión y el aislamiento de dependencias.
Instalación
# Verificar que Poetry está instalado
poetry --version
# Instalar dependencias
poetry install
Configuración de Variables de Entorno
Códigos de Sistema (System Codes)
| Código | Sectores Soportados |
|---|---|
| 7C3121D9A5A00BCE7B6A8DF | Prevalorado, Alquiler, Prevalorado sin crédito fiscal |
| 7755D817B7935A52BC1A8DF | Hotel, Hospital, Educativo |
| 721CDB813A795709E2128DF | Computarizada, Electrónica, Nota de crédito/débito |
| 353274141204F512BD7F | Tasa cero, Educativo |
Variables Requeridas
# Token de autenticación SIAT
export SIAT_TOKEN="<tu_token_aqui>"
# Ambiente: 1=producción, 2=piloto/testing
export SIAT_ENVIRONMENT=2
# Modalidad: 1=electrónica, 2=computarizada
export SIAT_MODALITY=1
# Password para certificados de firma digital
export KEY_PASSWORD="<password_certificado>"
# Nivel de logging (opcional)
export SP_SIAT_LOG_LEVEL="INFO"
# Timeout para sincronización (opcional, en segundos)
export SYNC_OBJ_TIMEOUT=300
Uso del SDK
Este SDK está construido sobre Sincpro Framework 3.0.1 utilizando el patrón Unified Bus. El punto de entrada principal es siat_soap_sdk, que ejecuta Features y ApplicationServices del SDK.
Uso básico
Por defecto, el SDK utiliza el SIAT_TOKEN y SIAT_ENVIRONMENT configurados en las variables de entorno:
from sincpro_siat_soap import siat_soap_sdk
from sincpro_siat_soap.services.auth_permissions import (
CommandGenerateCUIS,
ResponseGenerateCUIS,
)
from sincpro_siat_soap.global_definitions import SIATEnvironment, SIATModality
# Ejecutar una operación (Feature)
response = siat_soap_sdk(
CommandGenerateCUIS(
nit=412158028,
system_code="353274141204F512BD7F",
point_of_sale=1,
branch_office=0,
billing_type=SIATModality.ELECTRONICA,
environment=SIATEnvironment.TEST,
),
ResponseGenerateCUIS,
)
print(f"CUIS generado: {response.cuis}")
Uso con contexto personalizado
Si necesitas usar un token o ambiente diferente al configurado por defecto, puedes usar el context manager:
from sincpro_siat_soap import siat_soap_sdk
from sincpro_siat_soap.global_definitions import SIATEnvironment
from sincpro_siat_soap.services.billing import (
CommandCheckHealth,
ResponseCheckHealth,
)
# Ejecutar con contexto personalizado usando context manager
with siat_soap_sdk.context({
"TOKEN": "tu_token_personalizado_aqui",
"SIAT_ENV": SIATEnvironment.PRODUCTION, # o SIATEnvironment.TEST
}) as sdk_with_context:
response = sdk_with_context(
CommandCheckHealth(),
ResponseCheckHealth,
)
print(f"Estado del servicio: {response.raw_response}")
El context manager del framework Sincpro permite:
- Thread-safe: Aislamiento de contexto por hilo
- Nested contexts: Soporta contextos anidados con capacidad de override
- Automatic propagation: El contexto se propaga automáticamente a Features y ApplicationServices internos
Servicios disponibles
El SDK organiza las operaciones en módulos por tipo de servicio:
from sincpro_siat_soap import siat_soap_sdk
# Autenticación y permisos
from sincpro_siat_soap.services.auth_permissions import (
CommandGenerateCUIS,
CommandGenerateCUFD,
)
# Sincronización de datos (catálogos)
from sincpro_siat_soap.services.synchronization_data import (
CommandGenerateSyncDataDict,
CommandCreateOrLoadSyncObj,
)
# Operaciones (puntos de venta, eventos significativos)
from sincpro_siat_soap.services.operations import (
CommandCreatePointOfSale,
CommandRegisterSignificantEvent,
)
# Archivos digitales (envío, verificación, anulación)
from sincpro_siat_soap.services.digital_files import (
CmdSendDocumentToSiat,
CmdVerifyDocument,
CmdCancelDocument,
)
# Facturación
from sincpro_siat_soap.services.billing import (
CommandCheckHealth,
CommandMasiveInvoceReception,
)
Ejemplo completo: Flujo de facturación
from sincpro_siat_soap import siat_soap_sdk
from sincpro_siat_soap.global_definitions import (
SIATEnvironment,
SIATModality,
SIATApprovedDocumentId,
SIATEmissionType,
SIATInvoiceType,
)
from sincpro_siat_soap.services.auth_permissions import (
CommandGenerateCUIS,
ResponseGenerateCUIS,
)
from sincpro_siat_soap.services.synchronization_data import (
CommandCreateOrLoadSyncObj,
ResponseCreateOrLoadSyncObj,
)
from sincpro_siat_soap.services.digital_files import (
CmdSendDocumentToSiat,
ResSendDocumentToSiat,
)
# 1. Generar CUIS (una vez por punto de venta)
cuis_response = siat_soap_sdk(
CommandGenerateCUIS(
nit=412158028,
system_code="353274141204F512BD7F",
point_of_sale=1,
branch_office=0,
billing_type=SIATModality.ELECTRONICA,
environment=SIATEnvironment.TEST,
),
ResponseGenerateCUIS,
)
# 2. Crear/cargar objeto de sincronización (gestiona CUFD y catálogos)
sync_response = siat_soap_sdk(
CommandCreateOrLoadSyncObj(
nit=412158028,
cuis=cuis_response.cuis,
branch_office=0,
point_of_sale=1,
system_code="353274141204F512BD7F",
path_serialized="./sync_data",
environment=SIATEnvironment.TEST,
modality=SIATModality.ELECTRONICA,
),
ResponseCreateOrLoadSyncObj,
)
sync_obj = sync_response.sync_obj
# 3. Enviar factura (con XML firmado previamente)
invoice_response = siat_soap_sdk(
CmdSendDocumentToSiat(
nit=sync_obj.nit,
cuis=sync_obj.cuis,
cufd=sync_obj.cufd,
sector_document=SIATApprovedDocumentId.COMPRA_VENTA,
emission_code=SIATEmissionType.ONLINE,
sent_date="2025-02-25T10:30:00.000",
hash_invoice_file="hash_del_archivo",
branch_office=sync_obj.branch_office,
system_code=sync_obj.system_code,
point_of_sale=sync_obj.point_of_sale,
xml="xml_comprimido_y_firmado",
type_invoice=SIATInvoiceType.CREDITO_FISCAL,
environment=SIATEnvironment.TEST,
modality=SIATModality.ELECTRONICA,
),
ResSendDocumentToSiat,
)
print(f"Factura enviada: {invoice_response.raw_response}")
Manejo de errores
El SDK lanza excepciones SIATException cuando hay errores en las operaciones:
from sincpro_siat_soap import siat_soap_sdk
from sincpro_siat_soap.shared.core_exceptions import SIATException
try:
response = siat_soap_sdk(command, ResponseType)
except SIATException as e:
print(f"Error SIAT: {e}")
# Manejar el error según tu lógica de negocio
Tests
poetry run pytest
SIAT Integration Tests (test/siat_test)
El directorio test/siat_test contiene tests de integración que validan el flujo completo de facturación electrónica con el sistema SIAT (Sistema de Facturación de Bolivia). Estos tests simulan el proceso real de certificación y operación con SIAT.
Estructura de tests por etapas
Los tests están organizados siguiendo las etapas de certificación SIAT:
Etapa 1: Obtención de CUIS (test_etapa_1.py)
Valida la generación del Código Único de Inicio de Sistemas (CUIS) para cada punto de venta.
from sincpro_siat_soap import siat_soap_sdk
from sincpro_siat_soap.services.auth_permissions import (
CommandGenerateCUIS,
ResponseGenerateCUIS,
)
# Generar CUIS para punto de venta
response = siat_soap_sdk(
CommandGenerateCUIS(
nit=customer_nit,
system_code=customer_system_code,
point_of_sale=1,
branch_office=0,
billing_type=SIATModality.ELECTRONICA,
environment=SIATEnvironment.TEST,
),
ResponseGenerateCUIS,
)
Conceptos clave:
- Cada punto de venta requiere su propio CUIS
- El CUIS se genera una sola vez por punto de venta
- Es necesario para todas las operaciones posteriores
Etapa 2: Sincronización de catálogos (test_etapa_2.py)
Sincroniza los catálogos de códigos del SIAT (tipos de documento, monedas, unidades de medida, etc.).
from sincpro_siat_soap.services.synchronization_data import (
CommandGenerateSyncDataDict,
ResponseGenerateSyncDataDict,
)
# Sincronizar catálogos
response = siat_soap_sdk(
CommandGenerateSyncDataDict(
nit=nit,
cuis=cuis,
system_code=system_code,
environment=environment,
point_of_sale=point_of_sale,
branch_office=branch_office,
),
ResponseGenerateSyncDataDict,
)
Etapa 3: Generación de CUFD (test_etapa_3.py)
El Código Único de Factura Diaria (CUFD) debe renovarse diariamente.
# Renovar CUFD (se hace automáticamente con el SynchronizationObject)
sync_obj.request_new_cufd()
Etapa 4, 7, 8: Facturación en línea (test_etapa_4_7_8_v2.py)
Tests de emisión, verificación, anulación y reversión de facturas en línea.
from sincpro_siat_soap.services.digital_files import (
CmdSendDocumentToSiat,
CmdVerifyDocument,
CmdCancelDocument,
CmdRevertCancelledDocument,
)
# 1. Enviar factura
res_send = siat_soap_sdk(
CmdSendDocumentToSiat(
nit=nit,
cuis=cuis,
cufd=cufd,
sector_document=SIATApprovedDocumentId.COMPRA_VENTA,
emission_code=SIATEmissionType.ONLINE,
xml=invoice_xml.compressed_xml,
# ... otros parámetros
),
ResSendDocumentToSiat,
)
# 2. Verificar estado de la factura
res_verify = siat_soap_sdk(
CmdVerifyDocument(
cuf_or_reception_code=cuf,
# ... otros parámetros
),
ResVerifyDocument,
)
# 3. Anular factura
res_cancel = siat_soap_sdk(
CmdCancelDocument(
cuf=cuf,
cancellation_reason=cancellation_type,
# ... otros parámetros
),
ResCancelDocument,
)
# 4. Revertir anulación
res_revert = siat_soap_sdk(
CmdRevertCancelledDocument(
cuf=cuf,
# ... otros parámetros
),
ResRevertCancelledDocument,
)
Sectores soportados:
- Compra y venta (COMPRA_VENTA)
- Notas de crédito/débito
- Sector educativo
- Sector hotelero
- Sector hospitalario
- Alquiler de bienes
- Prevalorada
- Tasa cero
Etapa 5, 6: Facturación fuera de línea (Contingencia) (test_etapa_5_6_v2.py)
Tests de emisión de facturas en modo offline con eventos significativos.
from sincpro_siat_soap.services.operations import (
CommandRegisterSignificantEvent,
)
# 1. Registrar evento significativo (corte de internet, luz, etc.)
significant_event_response = siat_soap_sdk(
CommandRegisterSignificantEvent(
event_type=significant_event[0],
description=significant_event[1],
start_datetime_event=start_datetime.isoformat(),
end_datetime_event=end_datetime.isoformat(),
# ... otros parámetros
),
ResponseRegisterSignificantEvent,
)
# 2. Enviar paquete de facturas offline
package = siat_soap_sdk(
CmdSendDocumentPackage(
xml_list=signed_invoice,
cafc=cafc, # Código de Autorización de Facturas de Contingencia
with_significant_event_type=significant_event[0],
emission_code=SIATEmissionType.OFFLINE,
# ... otros parámetros
),
ResSendDocumentPackage,
)
Eventos significativos soportados:
- Corte de internet (
SE_CORTE_INTERNET) - Corte de electricidad (
SE_CORTE_ELECTRICIDAD) - Falla de hardware (
SE_FALLA_HARDWARE) - Virus informático (
SE_VIRUS_INFORMATICO) - Problemas con Administración Tributaria (
SE_ADMINISTRACION_TRIBUTARIA) - Zonas sin internet (
SE_ZONAS_SIN_INTERNET) - Despliegue a zonas sin internet (
SE_DEPLIEGUE_A_ZONAS_SIN_INTERNET)
Etapa 9: Facturación masiva (test_etapa_9.py)
Tests de envío de múltiples facturas en un solo paquete.
from sincpro_siat_soap.services.billing import (
CommandMasiveInvoceReception,
CommandVerifyMassiveInvoice,
)
# Enviar paquete masivo
massive_response = siat_soap_sdk(
CommandMasiveInvoceReception(
xml=compressed_files.zip_file,
count_invoice=len(invoice_list),
# ... otros parámetros
),
ResponseMasiveInvoiceReception,
)
# Verificar procesamiento
validation = siat_soap_sdk(
CommandVerifyMassiveInvoice(
reception_code=massive_response.reception_code,
# ... otros parámetros
),
ResponseVerifyMassiveInvoice,
)
Objeto de sincronización (SynchronizationObject)
El SynchronizationObject es una utilidad central que encapsula y gestiona automáticamente:
- CUIS (Código Único de Inicio de Sistemas)
- CUFD (Código Único de Factura Diaria) con renovación automática
- Catálogos sincronizados del SIAT
- Configuración de punto de venta y sucursal
from sincpro_siat_soap.services.synchronization_data import (
CommandCreateOrLoadSyncObj,
ResponseCreateOrLoadSyncObj,
)
# Crear o cargar objeto de sincronización
response = siat_soap_sdk(
CommandCreateOrLoadSyncObj(
nit=nit,
cuis=cuis,
branch_office=0,
point_of_sale=1,
system_code=system_code,
path_serialized=".", # Ruta para persistir el objeto
environment=SIATEnvironment.TEST,
modality=SIATModality.ELECTRONICA,
),
ResponseCreateOrLoadSyncObj,
)
sync_obj = response.sync_obj
# Renovar CUFD cuando sea necesario
sync_obj.request_new_cufd()
Configuración de tests
Los tests utilizan fixtures definidas en conftest.py:
# Variables necesarias
customer_nit = 412158028
customer_system_code = "353274141204F512BD7F"
customer_default_branch_office = 0
point_of_sale = 1
# Certificados para firma digital
certs_path = "certs_guide/siat_pilot"
cert = open(f"{certs_path}/certificate.crt", "r").read()
key = open(f"{certs_path}/private.key", "r").read()
Ejecutar tests SIAT
# Todos los tests SIAT
make test_one t=test/siat_test
# Test específico por etapa
poetry run pytest test/siat_test/test_etapa_1.py -v
# Con output detallado
poetry run pytest test/siat_test/test_etapa_4_7_8_v2.py -vvs
Importante antes de ejecutar
- Configurar variables de entorno:
export SIAT_TOKEN="<tu_token_siat>"
export SIAT_ENVIRONMENT=2 # 1=producción, 2=piloto
export SIAT_MODALITY=1 # 1=electronica, 2=computarizada
export KEY_PASSWORD="<password_certificado>"
-
Tener certificados válidos en
certs_guide/siat_pilot/ -
Ejecutar primero
test_only_run_at_the_beggining.pypara crear puntos de venta si es necesario -
Los tests de contingencia (etapa 5-6) requieren configuración especial y deben ejecutarse en orden
Notas sobre las etapas
- Etapa 1: Ejecutar una sola vez por punto de venta
- Etapa 2: Ejecutar periódicamente para actualizar catálogos
- Etapa 3: El CUFD se renueva automáticamente cada 24 horas
- Etapas 4-8: Tests de flujo completo en línea (pueden ejecutarse múltiples veces)
- Etapas 5-6: Requieren registro previo de eventos significativos
- Etapa 9: Tests de alto volumen (facturación masiva)
Uso Interactivo con IPython
Para usar el SDK de forma interactiva:
poetry run ipython
Esto te permite probar comandos y explorar el SDK en un entorno REPL.
Instalación en Otros Proyectos
Generar el Wheel
Para distribuir e instalar esta librería en otros proyectos:
# Construir el paquete wheel
poetry build
# Esto crea un directorio `dist/` con el archivo .whl
Instalar el Wheel
# Con pip
pip install dist/sincpro_siat_soap-7.2.1-py3-none-any.whl
# Con poetry en otro proyecto
poetry add /path/to/sincpro_siat_soap-7.2.1-py3-none-any.whl
📚 Documentación Adicional
Para más información sobre el SDK:
- Ver tests de ejemplo en
test/siat_test/ - Consultar documentación generada en
generated_docs/ - Revisar contexto AI en
generated_docs/ai_context/
🤝 Soporte
Para soporte técnico o consultas sobre licencias, contactar a Sincpro S.R.L.
© 2025 Sincpro S.R.L. - Todos los derechos reservados
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file sincpro_siat_soap-8.0.0.tar.gz.
File metadata
- Download URL: sincpro_siat_soap-8.0.0.tar.gz
- Upload date:
- Size: 84.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.3.4 CPython/3.12.3 Linux/6.17.0-1010-azure
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1330024e0753117de6c66e43b50b2af64b2c52c25ab198e8014761d1e3ec5e37
|
|
| MD5 |
a22dd51a3116308ca0ed847ad6f425b2
|
|
| BLAKE2b-256 |
e7739413ab307f4889bfec80769fa6a9e77751e82cd979a0ed2392dd1cca52d7
|
File details
Details for the file sincpro_siat_soap-8.0.0-py3-none-any.whl.
File metadata
- Download URL: sincpro_siat_soap-8.0.0-py3-none-any.whl
- Upload date:
- Size: 183.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.3.4 CPython/3.12.3 Linux/6.17.0-1010-azure
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
edc6f565d528e263be1751262aa43928019c7564658522f02eb618b17b430b82
|
|
| MD5 |
5608bb258f62820469fb3cfcee34a89f
|
|
| BLAKE2b-256 |
0766ecc5c6d48a887568b1c9ecc0d5394b6c5c238ed2aa558bdc7fe33df8f0c2
|