← SDKs
SDK de Python

majorsilence-reporting

Genera informes RDL en PDF, Excel, CSV y más desde Python — vía subproceso, un binario AOT, o FFI ctypes en proceso. Sin dependencias en tiempo de ejecución más allá de la biblioteca estándar.


Instalación

Instala desde PyPI (se requiere Python 3.10+):

# PyPI
pip install majorsilence-reporting

# O de forma editable desde el código fuente
pip install -e .

Sin dependencias en tiempo de ejecución — usa solo la biblioteca estándar de Python (subprocess, ctypes, tempfile).


Modos de integración

Hay tres clases disponibles según cómo despliegues el motor de informes:

ClaseMecanismoRequisito
ReportLanza dotnet RdlCmd.dll como proceso hijo.Runtime de .NET instalado en el servidor.
ReportAotLanza un binario RdlCmd autocontenido compilado con AOT.Binario AOT desplegado junto a la aplicación. No se necesita runtime de .NET.
report_native.ReportCarga librdlnative.so en el proceso mediante ctypes.Biblioteca nativa + archivos .so asociados desplegados. Llama a load_library() una vez al iniciar.

Report — subproceso (dotnet)

from majorsilence_reporting import Report

rpt = Report(
    report_path  = '/path/to/report.rdl',
    rdl_cmd_path = '/path/to/RdlCmd.dll',
)
rpt.set_connection_string('Data Source=/path/to/data.db')
rpt.set_parameter('StartDate', '2026-01-01')

# Guardar en un archivo
rpt.export('pdf', '/tmp/output.pdf')

# O bien obtener los bytes en memoria (por ejemplo para una respuesta de Flask)
data = rpt.export_to_memory('pdf')
return Response(data, mimetype='application/pdf')

ReportAot — binario AOT

Misma API que Report, pero apunta a un binario autocontenido en lugar de a una DLL. No se necesita runtime de .NET en el servidor.

from majorsilence_reporting import ReportAot

rpt = ReportAot(
    report_path  = '/path/to/report.rdl',
    rdl_cmd_path = '/path/to/RdlCmd',   # binario autocontenido, sin extensión .dll
)
rpt.set_connection_string('Data Source=/path/to/data.db')
data = rpt.export_to_memory('xlsx')

# ReportAot también admite xlsx_table, tifb y mht
data = rpt.export_to_memory('xlsx_table')

report_native — FFI en proceso

El modo nativo carga librdlnative.so directamente en el proceso de Python mediante ctypes. No se genera ningún proceso hijo, lo que lo convierte en la opción de menor latencia. También admite renderizado en memoria real — los bytes del informe se devuelven directamente desde el búfer nativo sin escribir un archivo temporal.

from majorsilence_reporting.report_native import load_library, Report

# Llamar una vez al iniciar el proceso. Carga librdlnative.so y todas las bibliotecas asociadas.
lib = load_library('/path/to/librdlnative.so')

rpt = Report(lib, report_path='/path/to/report.rdl')
rpt.set_connection_string('Data Source=/path/to/data.db')

# Devuelve los bytes directamente desde el búfer nativo — no se escribe ningún archivo temporal
data = rpt.export_to_memory('pdf')

# Pasar a Django / FastAPI / Flask como respuesta binaria
return Response(data, media_type='application/pdf')
load_library() define RDLNATIVE_LIB_DIR y precarga todas las bibliotecas .so / .dylib asociadas con RTLD_GLOBAL para que el resolutor P/Invoke de .NET las encuentre correctamente. Llámala una vez por proceso antes de crear cualquier instancia de Report.

API principal

Las tres clases comparten la misma interfaz:

MétodoDescripción
set_connection_string(cs)Establece la cadena de conexión a la base de datos usada por el informe. Llamar antes de export.
set_parameter(name, value)Define un parámetro de informe con nombre. Ambos argumentos son cadenas. Se puede llamar tantas veces como sea necesario.
export(format, path)Renderiza el informe y escribe la salida en path en disco.
export_to_memory(format)Renderiza y devuelve la salida como bytes (formatos binarios) o str (formatos de texto). En report_native.Report siempre devuelve bytes.

Conjuntos de datos en memoria

report_native.Report permite suministrar datos completamente en memoria mediante add_data() — sin necesidad de conexión a una base de datos. Pasa un nombre de conjunto de datos y una lista de diccionarios donde cada valor es una cadena.

from majorsilence_reporting.report_native import load_library, Report

lib = load_library('/path/to/librdlnative.so')
rpt = Report(lib, report_path='/path/to/report.rdl')

rpt.add_data('SalesData', [
    {'Product': 'PDF Library Pro',  'Revenue': '1200.00', 'Units': '3'},
    {'Product': 'Report Designer',   'Revenue': '250.00',  'Units': '1'},
    {'Product': 'Support (12 mo.)',  'Revenue': '500.00',  'Units': '1'},
])

data = rpt.export_to_memory('pdf')
add_data() activa automáticamente SkipDatabaseSchemaValidation. El nombre del conjunto de datos debe coincidir con un conjunto de datos definido en el archivo .rdl. Todos los valores de campo deben ser cadenas — convierte números y fechas antes de pasarlos.

Formatos de exportación

Cadena de formatoSalidaDisponible en
pdfPDFTodos los modos
csvTexto CSVTodos los modos
xlsxLibro de ExcelTodos los modos
xmlDatos XMLTodos los modos
rtfRich Text FormatTodos los modos
tifImagen TIFF (color)Todos los modos
htmlHTMLTodos los modos
xlsx_tableExcel (estilo tabla)Solo ReportAot + nativo
tifbImagen TIFF (blanco y negro)Solo ReportAot + nativo
mhtArchivo web MHTMLSolo ReportAot + nativo
Las cadenas de formato no reconocidas pasan silenciosamente a pdf. Todos los métodos son síncronos — envuélvelos en asyncio.get_event_loop().run_in_executor(None, ...) si necesitas llamarlos desde código asíncrono sin bloquear.