contadb-sdk
SDK oficial de Python para construir, firmar y timbrar CFDI 4.0 contra el API público de ContaDB.
Consume timbres de tu bolsa prepagada usando un API token. Sin pagos por uso, sin contratos mensuales — solo timbra cuando lo necesites.
Instalación
pip install contadb-sdk
Requiere Python 3.10+.
Quickstart
from decimal import Decimal
from contadb_sdk import (
ContaDBClient,
CFDIBuilder,
Certificado,
Emisor,
Receptor,
Concepto,
)
# 1. Carga tu CSD (Certificado de Sello Digital del SAT)
cert = Certificado.cargar(
cer_path="emisor.cer",
key_path="emisor.key",
password="MI_PASSWORD",
)
# 2. Construye el CFDI
cfdi_xml = (
CFDIBuilder(
emisor=Emisor(
rfc="EKU9003173C9",
nombre="ESCUELA KEMPER URGATE",
regimen_fiscal="601",
),
receptor=Receptor(
rfc="URE180429TM6",
nombre="UNIVERSIDAD ROBOTICA ESPAÑOLA",
uso_cfdi="G03",
domicilio_fiscal_receptor="65000",
regimen_fiscal_receptor="601",
),
serie="A",
folio="1001",
forma_pago="03", # Transferencia electrónica
metodo_pago="PUE", # Pago en una sola exhibición
lugar_expedicion="64000",
)
.agregar_concepto(
Concepto(
clave_prod_serv="43232408",
clave_unidad="E48",
descripcion="Servicios de consultoría en sistemas",
cantidad=Decimal("1"),
valor_unitario=Decimal("1000.00"),
objeto_imp="02",
tasa_iva=Decimal("0.16"),
)
)
.construir_y_firmar(cert)
)
# 3. Timbra contra ContaDB
with ContaDBClient(api_token="cdb_TU_TOKEN_AQUI") as client:
resultado = client.timbrar(cfdi_xml)
print(f"UUID: {resultado.uuid}")
print(f"Saldo restante: {resultado.saldo_restante} timbres")
print(f"XML timbrado: {len(resultado.xml_timbrado)} chars")
Características
- ✅ Construcción CFDI 4.0 — Builder con API fluida, validación Pydantic, cálculo automático de impuestos.
- ✅ Firma RSA-SHA256 — Carga
.cer+.keydel SAT, firma cadena original generada con XSLT oficial. - ✅ Cliente HTTP tipado — Errores mapeados a excepciones específicas (
SaldoInsuficienteError,TokenRevocadoError, etc.). - ✅ Reintentos automáticos — Backoff exponencial con jitter en errores 429/5xx/red. Honra
Retry-After. Idempotency-Key resiste duplicados. - ✅ CFDI relacionados — Emite bloques
cfdi:CfdiRelacionados(sustitución, nota de crédito, devolución, etc.). - ✅ Complementos oficiales — Recepción de Pagos 2.0 y Carta Porte 3.1.
- ✅ Cancelación —
client.cancelar(uuid_cfdi, motivo, certificado, folio_sustitucion=...)con motivos SAT 01–04. - ✅ 100% tipado — Marcador
py.typedpara inferencia perfecta en IDEs ymypy --strict. - ✅ Cero dependencias mágicas — Solo
pydantic,httpx,cryptography,lxml.
Manejo de errores
from contadb_sdk import (
ContaDBClient,
SaldoInsuficienteError,
RateLimitError,
TokenRevocadoError,
)
try:
resultado = client.timbrar(xml)
except SaldoInsuficienteError:
# Comprar más timbres en https://contadb.mx/facturacion
...
except RateLimitError as e:
# El SDK ya reintentó automáticamente; aquí solo llegas si agotó los intentos.
# e.retry_after trae los segundos sugeridos por el servidor.
...
except TokenRevocadoError:
# Generar un nuevo token
...
Reintentos automáticos
El cliente reintenta solo en errores transitorios (HTTP 429, 500, 502, 503, 504 y fallos de red) con backoff exponencial + jitter. Cada reintento reusa el mismo Idempotency-Key, así que es seguro.
from contadb_sdk import ContaDBClient, RetryPolicy, RETRY_POLICY_NINGUNO
# Default: 3 intentos, backoff_factor=0.5, backoff_max=30s, honra Retry-After.
client = ContaDBClient(api_token="cdb_xxx")
# Personalizado:
client = ContaDBClient(
api_token="cdb_xxx",
retry_policy=RetryPolicy(max_intentos=5, backoff_factor=1.0, backoff_max=60.0),
)
# Sin reintentos (comportamiento de v1.0):
client = ContaDBClient(api_token="cdb_xxx", retry_policy=RETRY_POLICY_NINGUNO)
CFDI sustituto / nota de crédito / devolución
Para emitir un CFDI que referencia uno o varios CFDIs previos (sustitución tras cancelar con motivo 01, nota de crédito, devolución, etc.):
from contadb_sdk import CFDIBuilder, CfdiRelacionados
builder = CFDIBuilder(...).agregar_cfdi_relacionado(
tipo_relacion="04", # 04 = Sustitución de los CFDI previos
uuids=["550e8400-e29b-41d4-a716-446655440000"],
)
Catálogo c_TipoRelacion SAT: "01" nota de crédito, "02" nota de débito, "03" devolución, "04" sustitución, "05"–"07" traslados/anticipos.
Logging
El SDK emite eventos vía el logger estándar contadb_sdk (request, status, decisiones de reintento). Nunca loguea token, llave privada, contraseña ni XML.
import logging
logging.getLogger("contadb_sdk").setLevel(logging.INFO)
Configuración
Por defecto el cliente apunta a https://api.contadb.mx. Puedes cambiarlo:
client = ContaDBClient(
api_token="cdb_xxx",
base_url="https://staging.contadb.mx", # o env var CONTADB_BASE_URL
timeout=60.0,
)
Documentación
Cómo obtener un API token
- Crea cuenta en contadb.mx.
- Ve a Facturación → API Tokens y genera uno.
- Compra una bolsa de timbres (desde 100 timbres / $200 MXN).
- Usa el token con este SDK.
Licencia
MIT — ver LICENSE.
Metadata
Release files for contadb-sdk 1.1.4
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| contadb_sdk-1.1.4.tar.gz | 94.6 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| contadb_sdk-1.1.4-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 166.4 kB
Release files / contadb_sdk-1.1.4.tar.gz
| Download URL | contadb_sdk-1.1.4.tar.gz |
|---|---|
| Size | 94.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
bb2cd432a13584b7c9f76acac501b0d1d421570d84dbc5552c9a0183e14ff270
|
|
BLAKE2b-256 checksum How to use checksums |
f3f4068e66220bb0d826587a0384b21099e4487f35c4812572c3ee71c76b105a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.10.12
|
Release files / contadb_sdk-1.1.4-py3-none-any.whl
| Download URL | contadb_sdk-1.1.4-py3-none-any.whl |
|---|---|
| Size | 71.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b89858b69107f7c5c85fb0a1fac289f37298ee86b11cc361c93ecf79c12886a0
|
|
BLAKE2b-256 checksum How to use checksums |
26b0bb0db6f8aea55659b50fbbbcf4fb997c8d5588cb651aed26a09926df6288
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.10.12
|
Security for contadb-sdk 1.1.4
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.