SDK de Python
El paquete oficial fiscalrail es la forma recomendada de llamar a FiscalRail desde Python. Incluye parámetros tipados, dataclasses inmutables para las respuestas, conexiones reutilizables, reintentos seguros y helpers fiscales por país, sin añadir un framework de validación en tiempo de ejecución.
Instala y autentica
python -m pip install fiscalrail
export FISCALRAIL_API_KEY=ak_test_...
Crea un cliente y reutilízalo durante toda la vida del proceso de tu aplicación:
import os
from fiscalrail import FiscalRail
client = FiscalRail(os.environ["FISCALRAIL_API_KEY"])
La clave de API es un argumento obligatorio del constructor. Tu aplicación decide si procede de una variable de entorno, de un gestor de secretos o de otra fuente de configuración; el SDK no inspecciona las variables del proceso. Test y Live usan la misma URL base y la clave selecciona el entorno de la cuenta.
FiscalRail mantiene internamente una requests.Session. Úsalo como gestor de contexto en scripts breves o llama a client.close() al cerrar la aplicación. Puedes inyectar tu propia requests.Session si necesitas proxies, configuración TLS, adapters u observabilidad; en ese caso la sesión sigue siendo propiedad de tu aplicación.
Emite una factura
Usa Decimal para importes y los helpers de España para impuestos definidos en el catálogo:
import os
from decimal import Decimal
from fiscalrail import FiscalRail
from fiscalrail.tax_regimes.es import irpf, vat
client = FiscalRail(os.environ["FISCALRAIL_API_KEY"])
invoice = client.invoices.issue(
customer="cus_...",
lines=[
{
"description": "Servicios de consultoría",
"unit_price": Decimal("2500.00"),
"taxes": [vat.general, irpf.professionals],
}
],
)
print(invoice.code)
print(invoice.totals.payable)
La emisión y la rectificación generan automáticamente una clave de idempotencia. Los trabajos duraderos deberían proporcionar y guardar su propio idempotency_key, de modo que un reintento después de reiniciar el proceso identifique la misma operación.
Peticiones y respuestas tipadas
Los métodos aceptan argumentos con nombre y tipados. Los TypedDict exportados son útiles cuando construyes el payload antes de hacer la llamada:
from decimal import Decimal
from fiscalrail.params import InvoiceIssueParams
from fiscalrail.tax_regimes.es import vat
params = InvoiceIssueParams(
customer="cus_...",
lines=[
{
"description": "Servicios de consultoría",
"unit_price": Decimal("2500.00"),
"taxes": [vat.general],
}
],
)
invoice = client.invoices.issue(**params)
Las respuestas son dataclasses congelados generados desde el contrato OpenAPI de FiscalRail. Las fechas se convierten en date, las marcas de tiempo en datetime y los decimales en Decimal. Los campos de respuesta desconocidos permanecen disponibles en response.extra_fields, por lo que añadir un campo no rompe versiones anteriores del SDK.
Reintentos y errores
El cliente reintenta errores de conexión, timeouts y respuestas 408, 429 y 5xx transitorias solo cuando la operación se puede repetir de forma segura. Respeta Retry-After y, en los demás casos, aplica un backoff exponencial limitado. De forma predeterminada hace dos reintentos; usa max_retries=0 para desactivarlos.
Los errores de FiscalRail se lanzan como subclases de FiscalRailError. Los errores de API exponen status_code, code, request_id y los detalles de validación cuando existan. Los errores de conexión y timeout conservan la clave de idempotencia para que un worker duradero pueda decidir cómo continuar.
Recursos disponibles
client.accountsclient.api_keysclient.customersclient.event_destinationsclient.eventsclient.invoice_seriesclient.invoicesclient.invoice_pdfsclient.tax_idsclient.tax_regimes
Las facturas usan los verbos de dominio issue y amend; los documentos emitidos nunca se actualizan. Cada operación de la referencia de la API tiene un método correspondiente en el SDK.
Verifica webhooks
Pasa el cuerpo original de la petición, la cabecera FiscalRail-Signature y el secreto de firma del destino a construct_event:
from fiscalrail.webhooks import construct_event
event = construct_event(raw_body, signature_header, signing_secret)
El helper verifica el HMAC en tiempo constante, rechaza marcas de tiempo con más de cinco minutos y solo entonces interpreta el evento JSON. Una verificación fallida lanza WebhookSignatureError.