Requisitos previos
- Python 3.8+ y la librería
requests(pip install requests). - Una clave de API: crea una cuenta gratuita y copia tu clave desde el panel de control. Guárdala en una variable de entorno en lugar de incluirla en el código:
export PDF_SUMMARIZE_KEY="sk_live_..."
Tu primer resumen de PDF en Python
- Instala requests
pip install requests. - Configura tu clave de APIEn la variable de entorno
PDF_SUMMARIZE_KEY. - Envía el PDFComo multipart/form-data con el nombre de campo
file. - Lee el JSONEl resumen se encuentra en
summary; compruebasuccessy el código de estado HTTP.
import os
import requests
API_URL = "https://pdf-summarize.com/api/summarize.php"
API_KEY = os.environ["PDF_SUMMARIZE_KEY"]
def summarize_pdf(path, length="medium", fmt="bullets", lang="auto"):
with open(path, "rb") as f:
resp = requests.post(
API_URL,
headers={"Authorization": f"Bearer {API_KEY}"},
files={"file": (os.path.basename(path), f, "application/pdf")},
data={"length": length, "format": fmt, "outputLang": lang, "includeKeywords": "1"},
timeout=180,
)
data = resp.json()
if resp.status_code != 200 or not data.get("success"):
raise RuntimeError(f"{resp.status_code}: {data.get('error', data)}")
return data
result = summarize_pdf("annual-report.pdf")
print(result["summary"])
print("Páginas:", result["page_count"], "| Palabras clave:", result.get("keywords"))
La respuesta
{
"success": true,
"summary": "- Los ingresos crecieron un 6% hasta...",
"keywords": "ingresos, margen, previsiones, ...",
"page_count": 48,
"original_length": 182340,
"summary_length": 1210,
"processing_time": 6.214,
"requests_remaining": 4987
}
requests_remaining representa tu cuota mensual restante (-1 indica ilimitada).
Hacer streaming del resumen
Para documentos largos o aplicaciones interactivas, transmite el resumen a medida que se genera:
import json
def stream_summary(path):
with open(path, "rb") as f:
with requests.post(
API_URL + "?stream=1",
headers={"Authorization": f"Bearer {API_KEY}"},
files={"file": (os.path.basename(path), f, "application/pdf")},
data={"length": "long", "format": "mixed"},
stream=True, timeout=300,
) as resp:
resp.raise_for_status()
for line in resp.iter_lines(decode_unicode=True):
if not line or not line.startswith("data: "):
continue
payload = line[6:]
if payload == "[DONE]":
break
event = json.loads(payload)
if "error" in event:
raise RuntimeError(event["error"])
if event.get("type") == "summary":
print(event["content"], end="", flush=True)
stream_summary("research-paper.pdf")
Procesar una carpeta de PDFs
import pathlib, time
out_dir = pathlib.Path("summaries")
out_dir.mkdir(exist_ok=True)
for pdf in sorted(pathlib.Path("pdfs").glob("*.pdf")):
target = out_dir / (pdf.stem + ".md")
if target.exists():
continue # permite reanudar el proceso fácilmente
for attempt in range(3):
try:
data = summarize_pdf(str(pdf), length="long", fmt="mixed")
target.write_text(data["summary"], encoding="utf-8")
print("ok", pdf.name, data["page_count"], "páginas")
break
except RuntimeError as e:
if str(e).startswith("429"):
time.sleep(30 * (attempt + 1)) # límite de peticiones: espera antes de reintentar
else:
print("error", pdf.name, e)
break
Errores que debes gestionar
| Estado | Significado | Qué hacer |
|---|---|---|
| 400 | Falta el archivo, formato incorrecto, límite de páginas superado | Comprueba el archivo y el límite de páginas de tu plan |
| 401 | Clave de API ausente o no válida | Verifica la cabecera Authorization |
| 403 | Cuenta suspendida | Contacta con soporte |
| 413 | Archivo demasiado grande | Comprime o divide el PDF |
| 422 | Sin texto legible (vacío, protegido o escaneo ilegible) | Elimina la contraseña; mejora el escaneo |
| 429 | Límite de peticiones o cuota mensual alcanzada | Espera y reintenta, o actualiza tu plan |
| 500 | Resumen temporalmente no disponible | Reintenta aplicando espera exponencial |
Consejos
- Configura tiempos de espera (timeouts) generosos (2-3 minutos) para PDFs largos.
- Almacena en caché los resultados mediante el hash del archivo para evitar pagar dos veces por el mismo documento.
- Mantén las claves en el servidor — nunca las incluyas en el código de una aplicación frontend o móvil.
- Referencia completa de parámetros: la documentación de la API.
Preguntas frecuentes
¿Hay un plan de API gratuito?
Sí. El plan gratuito incluye una cuota mensual de peticiones sin necesidad de tarjeta de crédito. Consulta las tarifas.
¿Puedo enviar la URL de un PDF en lugar de un archivo?
La API recibe el archivo directamente. Descarga el PDF en tu código (por ejemplo, con requests) y envía los bytes.
¿En qué idiomas puede estar el resumen?
Usa outputLang=auto para conservar el idioma del documento, o indica un código de idioma como en, fr, es, de.
¿Cómo puedo resumir PDFs escaneados a través de la API?
Envíalos como cualquier PDF; el sistema de extracción recurre automáticamente al OCR cuando no hay una capa de texto utilizable.