Guía del desarrollador del SDK de Python
De un vistazo
Sección titulada «De un vistazo»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.
Límite de la arquitectura
Sección titulada «Límite de la arquitectura»| Capa | Responsable | Responsabilidad | No pongas aquí |
|---|---|---|---|
| Fuente de entrada | Aplicación | Autorizar 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 cliente | Aplicación | Leer base_url y api_key desde el entorno o un gestor de secretos. | Secretos incrustados en el código. |
NextPDF / AsyncNextPDF | SDK | Construir 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étodos | SDK | Asociar 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 Connect | Despliegue | Ejecutar 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.
Ciclo de vida en tiempo de ejecución
Sección titulada «Ciclo de vida en tiempo de ejecución»| Etapa | Comportamiento | Acción del desarrollador |
|---|---|---|
| Construcción del cliente | base_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 backend | Un 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étodo | El 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 errores | Un estado HTTP que no es de éxito se asigna a una subclase de excepción concreta. | Capturar primero la clase más específica. |
| Cierre | AsyncNextPDF.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. |
Estructura recomendada de la aplicación
Sección titulada «Estructura recomendada de la aplicación»| Ruta | Propósito |
|---|---|
app/pdf/clients.py | Construir y almacenar en caché un NextPDF o AsyncNextPDF configurado. |
app/pdf/extraction.py | Capa envoltorio de la aplicación para las llamadas al método ast. |
app/pdf/validation.py | Validació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)Patrón de cliente síncrono
Sección titulada «Patrón de cliente síncrono»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 errorForma esperada de un elemento de resultado:
block = blocks[0]print(block.text) # the extracted textprint(block.citation.page_index) # 0-based page indexprint(block.citation.confidence) # 0.0 - 1.0Patró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 asyncioimport 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.
Puntos de extensión
Sección titulada «Puntos de extensión»| Punto de extensión | Uso recomendado | Restricció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 entorno | Proporcionar 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. |
Flujo de trabajo de desarrollo
Sección titulada «Flujo de trabajo de desarrollo»- Instalar el SDK con
pip install nextpdf, opip install nextpdf[mcp]para el servidor de agentes. - Leer
NEXTPDF_BASE_URLyNEXTPDF_API_KEYdesde el entorno para que ningún secreto entre en el control de código fuente. - Validar cada fuente de PDF —existencia, tamaño y los bytes mágicos
%PDF-— antes de llamar al SDK. - Construir un único cliente por proceso y reutilizarlo; para asyncio, mantenerlo abierto con
async with. - Llamar al método
astmá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. - Capturar la excepción más específica sobre la que se pueda actuar y luego recurrir a
NextPDFError. - 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.
- 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.
Manejo de fallos
Sección titulada «Manejo de fallos»| Fallo | Excepción | Respuesta recomendada |
|---|---|---|
| PDF sin etiquetar, heurística desactivada | AstNoStructTreeError (HTTP 422) | Activar el modo heurístico en el endpoint o proporcionar un PDF etiquetado. |
| Tiempo de espera de compilación agotado en el servidor | AstBuildTimeoutError (HTTP 504) | Reducir el rango de páginas y volver a intentarlo. |
| Se requiere un nivel de licencia | NextPDFLicenseError (HTTP 402) | Actualizar la licencia del servidor o recurrir a una función permitida. |
| Límite de frecuencia o cuota | QuotaExceededError (HTTP 429) | Esperar retry_after segundos y luego volver a intentarlo con retroceso. |
| Otro error HTTP | NextPDFAPIError | Inspeccionar status_code y error_code; registrar y mostrar un error definido. |
| Cualquier error del SDK | NextPDFError | Ú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.
Valores predeterminados seguros
Sección titulada «Valores predeterminados seguros»| Aspecto | Predeterminado | Cuándo anularlo |
|---|---|---|
| Versión de la API | v1. | Cambiarla solo cuando el endpoint admita una versión más reciente. |
| Verificación de TLS | Activada; no se expone ningún interruptor inseguro. | No desactivarla nunca para el tráfico de producción. |
| Credenciales | Se 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 memoria | Rechaza 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. |
| Simultaneidad | Limitada por un semáforo en los lotes asíncronos. | Ajustarla a la cuota del endpoint, no al número de núcleos del host. |
| Registro | Se 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. |
Lista de comprobación de pruebas
Sección titulada «Lista de comprobación de pruebas»- Las pruebas de construcción verifican que un
base_urloapi_keyvacío generaValueError. - 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
CitationAnchoren cada bloque. - Las pruebas de modo de fallo cubren
AstNoStructTreeError,AstBuildTimeoutError,NextPDFLicenseError,QuotaExceededErroryNextPDFAPIError. - Las pruebas asíncronas verifican que el cliente se usa como un gestor de contexto
async withy 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.
Consulta también
Sección titulada «Consulta también»- Referencia de la API de Python: cada método de cliente, modelo y excepción.
- CLI de Python: extracción por flujo para documentos grandes.
- Servidor MCP de Python: exponer herramientas de extracción a agentes de IA.
- Introducción al SDK de Python: opciones de backend y limitaciones.