Ir al contenido

Guía del desarrollador del SDK de Python

El SDK (kit de desarrollo de software) de Python de NextPDF es un cliente ligero y tipado que se apoya en un endpoint de NextPDF Connect. La aplicación es responsable de validar la entrada, manejar las credenciales y definir la política de simultaneidad; el SDK se encarga de construir la solicitud, realizar el transporte y tipar la respuesta. Mantener explícito ese límite: leer el PDF de forma segura, elegir un cliente, llamar al método ast necesario y manejar el fallo concreto.

Esta guía es útil para construir servicios de extracción, trabajos por lotes con asyncio, herramientas para agentes de IA o flujos de trabajo de línea de comandos en torno al SDK. Se asume que ya se han leído la introducción y la guía de inicio rápido, y que se dispone de Python 3.10 o posterior y de un endpoint de NextPDF Connect.

CapaResponsableResponsabilidadNo pongas aquí
Fuente de entradaAplicaciónAutorizar a quien llama, validar la fuente del PDF y elegir la política de extracción.Literales de URL del endpoint o de credenciales.
Construcción del clienteAplicaciónLeer base_url y api_key desde el entorno o un gestor de secretos.Secretos incrustados en el código.
NextPDF / AsyncNextPDFSDKConstruir la solicitud, llamar a Connect, devolver modelos de Pydantic tipados.Lógica de dominio o política de almacenamiento.
ast espacio de nombres de métodosSDKAsociar una llamada de método con un endpoint de Connect y analizar la respuesta.Política de reintentos o de retroceso más allá de la configurada.
Endpoint de NextPDF ConnectDespliegueEjecutar la extracción, aplicar la autenticación, las cuotas y las licencias.Autorización de la aplicación.

El SDK nunca realiza reconocimiento óptico de caracteres (OCR). Un PDF escaneado o formado solo por imágenes necesita un paso de OCR antes de la extracción; debe tratarse como una responsabilidad de la aplicación, fuera de este límite.

EtapaComportamientoAcción del desarrollador
Construcción del clientebase_url y api_key se validan; un valor vacío genera ValueError.Leer ambos desde el entorno; no incrustarlos nunca en el código.
Creación del backendUn backend remoto abre una conexión agrupada hacia Connect.Reutilizar un cliente para todas las llamadas en lugar de construir uno por solicitud.
Llamada de métodoEl método ast serializa la solicitud, envía los bytes del PDF y analiza la respuesta para convertirla en un modelo de Pydantic.Pasa bytes ya validados.
Asignación de erroresUn estado HTTP que no es de éxito se asigna a una subclase de excepción concreta.Capturar primero la clase más específica.
CierreAsyncNextPDF.close() libera el grupo de conexiones; el gestor de contexto asíncrono lo invoca automáticamente.Usar async with o llamar a close() en un bloque finally.
RutaPropósito
app/pdf/clients.pyConstruir y almacenar en caché un NextPDF o AsyncNextPDF configurado.
app/pdf/extraction.pyCapa envoltorio de la aplicación para las llamadas al método ast.
app/pdf/validation.pyValidación de la fuente del PDF, límites de tamaño y comprobaciones de contenido.
tests/pdf/Pruebas de extracción, de modos de fallo y de procesamiento por lotes asíncrono.

Mantener la validación del PDF separada de la extracción. La capa de extracción debe recibir bytes ya autorizados y con el tamaño comprobado, y aun así apoyarse en el endpoint como defensa en profundidad.

import os
from nextpdf import NextPDF
def build_client() -> NextPDF:
"""Construct a synchronous client from environment configuration.
Raises:
KeyError: When a required environment variable is missing.
"""
base_url = os.environ["NEXTPDF_BASE_URL"]
api_key = os.environ["NEXTPDF_API_KEY"]
return NextPDF(base_url=base_url, api_key=api_key)

Usar el cliente síncrono NextPDF para scripts, trabajos por lotes y notebooks. Validar la entrada antes de llamar al SDK y manejar los fallos concretos que pueda generar la llamada.

from pathlib import Path
from nextpdf import (
NextPDF,
CitedTextBlock,
NextPDFAPIError,
NextPDFError,
QuotaExceededError,
)
MAX_PDF_BYTES = 100 * 1024 * 1024 # Reject documents above 100 MiB for the in-memory path.
def read_pdf(path: Path) -> bytes:
"""Read and validate a PDF from disk.
Raises:
ValueError: When the file is missing, empty, oversized, or not a PDF.
"""
if not path.is_file():
raise ValueError(f"Not a file: {path}")
data = path.read_bytes()
if not data:
raise ValueError("PDF is empty")
if len(data) > MAX_PDF_BYTES:
raise ValueError("PDF exceeds the configured size limit; use the CLI streaming path")
if not data.startswith(b"%PDF-"):
raise ValueError("File does not look like a PDF")
return data
def extract_text(client: NextPDF, path: Path) -> list[CitedTextBlock]:
"""Extract cited text blocks, handling the most specific failures first."""
pdf_bytes = read_pdf(path)
try:
return client.ast.extract_cited_text(pdf_bytes)
except QuotaExceededError as error:
raise RuntimeError(f"Quota exceeded; retry after {error.retry_after}s") from error
except NextPDFAPIError as error:
raise RuntimeError(f"API error {error.status_code}: {error}") from error
except NextPDFError as error:
raise RuntimeError(f"SDK error: {error}") from error

Forma esperada de un elemento de resultado:

block = blocks[0]
print(block.text) # the extracted text
print(block.citation.page_index) # 0-based page index
print(block.citation.confidence) # 0.0 - 1.0

Patrón asíncrono y de procesamiento por lotes

Sección titulada «Patrón asíncrono y de procesamiento por lotes»

Usar el cliente asíncrono AsyncNextPDF en entornos de ejecución de asyncio, como FastAPI. Construir un único cliente como gestor de contexto asíncrono y compartirlo entre las llamadas simultáneas; no abrir un cliente por documento. Limitar la simultaneidad con un semáforo para respetar la cuota del endpoint.

import asyncio
import os
from nextpdf import (
AsyncNextPDF,
ExtractCitedTablesResponse,
NextPDFError,
QuotaExceededError,
)
async def extract_tables_batch(
pdfs: list[bytes],
*,
max_concurrency: int = 4,
) -> list[ExtractCitedTablesResponse | None]:
"""Extract tables from many PDFs concurrently with one shared client.
Returns one response per input PDF, or None where extraction failed.
"""
base_url = os.environ["NEXTPDF_BASE_URL"]
api_key = os.environ["NEXTPDF_API_KEY"]
semaphore = asyncio.Semaphore(max_concurrency)
async with AsyncNextPDF(base_url=base_url, api_key=api_key) as client:
async def one(pdf_bytes: bytes) -> ExtractCitedTablesResponse | None:
async with semaphore:
try:
return await client.ast.extract_cited_tables(pdf_bytes)
except QuotaExceededError as error:
# Surface the backpressure signal; do not silently drop it.
raise RuntimeError(f"Quota exceeded; retry after {error.retry_after}s") from error
except NextPDFError:
return None
return await asyncio.gather(*(one(pdf) for pdf in pdfs))

No escribir nunca un except vacío. Actuar sobre el fallo, convertirlo en un resultado definido o volver a generarlo.

Punto de extensiónUso recomendadoRestricción
AsyncNextPDF(backend=...)Inyectar un backend personalizado o local en las pruebas.El backend debe cumplir el protocolo PdfBackend.
api_version (argumento)Fijar una versión de la API de Connect.De forma predeterminada es v1; cambiarla solo cuando el endpoint admita la versión de destino.
Configuración del entornoProporcionar NEXTPDF_BASE_URL y NEXTPDF_API_KEY a la CLI y al servidor MCP.Tratar la clave como un secreto con alcance limitado a la carga de trabajo.
Servidor MCP (python -m nextpdf.mcp)Exponer herramientas de extracción a agentes compatibles con MCP.Requiere el extra nextpdf[mcp] y un endpoint controlado.
  1. Instalar el SDK con pip install nextpdf, o pip install nextpdf[mcp] para el servidor de agentes.
  2. Leer NEXTPDF_BASE_URL y NEXTPDF_API_KEY desde el entorno para que ningún secreto entre en el control de código fuente.
  3. Validar cada fuente de PDF —existencia, tamaño y los bytes mágicos %PDF-— antes de llamar al SDK.
  4. Construir un único cliente por proceso y reutilizarlo; para asyncio, mantenerlo abierto con async with.
  5. Llamar al método ast más acotado para la tarea: extract_cited_text() para prosa, extract_cited_tables() para tablas, get_document_ast() solo cuando se necesite el árbol completo.
  6. Capturar la excepción más específica sobre la que se pueda actuar y luego recurrir a NextPDFError.
  7. Para documentos de más de 100 MiB, usar la ruta de transmisión por flujo de la CLI en lugar de materializar todos los bloques en memoria.
  8. Ejecutar la comprobación de tipos con mypy en modo estricto y agregar una prueba de modo de fallo para cada excepción que se maneje.
FalloExcepciónRespuesta recomendada
PDF sin etiquetar, heurística desactivadaAstNoStructTreeError (HTTP 422)Activar el modo heurístico en el endpoint o proporcionar un PDF etiquetado.
Tiempo de espera de compilación agotado en el servidorAstBuildTimeoutError (HTTP 504)Reducir el rango de páginas y volver a intentarlo.
Se requiere un nivel de licenciaNextPDFLicenseError (HTTP 402)Actualizar la licencia del servidor o recurrir a una función permitida.
Límite de frecuencia o cuotaQuotaExceededError (HTTP 429)Esperar retry_after segundos y luego volver a intentarlo con retroceso.
Otro error HTTPNextPDFAPIErrorInspeccionar status_code y error_code; registrar y mostrar un error definido.
Cualquier error del SDKNextPDFErrorÚltimo recurso; no dejar nunca que escape como una excepción no manejada.

El endpoint informa de los fallos con semántica de estado HTTP alineada con RFC 9110 y cuerpos de error legibles por máquina alineados con RFC 9457. Cada excepción conserva el status_code de origen. Asignarlos a respuestas de error propias en lugar de exponer detalles del transporte a los consumidores.

AspectoPredeterminadoCuándo anularlo
Versión de la APIv1.Cambiarla solo cuando el endpoint admita una versión más reciente.
Verificación de TLSActivada; no se expone ningún interruptor inseguro.No desactivarla nunca para el tráfico de producción.
CredencialesSe leen desde el entorno; nunca se incrustan en el código.Usar un gestor de secretos en producción.
Límite de tamaño en memoriaRechaza los PDF de más de 100 MiB en la ruta del cliente.Reducirlo para servicios multiinquilino; usar la CLI para archivos más grandes.
SimultaneidadLimitada por un semáforo en los lotes asíncronos.Ajustarla a la cuota del endpoint, no al número de núcleos del host.
RegistroSe registran el nombre del archivo, el tamaño, el estado y la duración.No registrar nunca los bytes del PDF ni la clave de API.
  • Las pruebas de construcción verifican que un base_url o api_key vacío genera ValueError.
  • Las pruebas de validación cubren entradas ausentes, vacías, de tamaño excesivo y que no son PDF.
  • Las pruebas de extracción verifican los tipos de modelo devueltos y la presencia de un CitationAnchor en cada bloque.
  • Las pruebas de modo de fallo cubren AstNoStructTreeError, AstBuildTimeoutError, NextPDFLicenseError, QuotaExceededError y NextPDFAPIError.
  • Las pruebas asíncronas verifican que el cliente se usa como un gestor de contexto async with y que la simultaneidad se mantiene dentro del límite del semáforo.
  • Las pruebas de ciclo de vida verifican que close() libera el transporte y es idempotente.
  • Inyectar un backend falso con AsyncNextPDF(backend=...) para que las pruebas se ejecuten sin depender de un endpoint en vivo.