Salta ai contenuti

Guida per sviluppatori dell'SDK Python

Il Software Development Kit (SDK) Python di NextPDF è un client tipizzato e leggero che si appoggia a un endpoint NextPDF Connect. L’applicazione è responsabile della convalida dell’input, della gestione delle credenziali e dei criteri di concorrenza; l’SDK è responsabile della costruzione della richiesta, del trasporto e della tipizzazione della risposta. Mantenere esplicito questo confine: leggere il PDF in modo sicuro, scegliere il client, chiamare il metodo ast necessario e gestire l’errore specifico.

Usare questa guida per creare servizi di estrazione, processi batch asyncio, strumenti per agenti AI o un flusso di lavoro da riga di comando attorno all’SDK. La guida presuppone che siano state lette la panoramica e la guida rapida e che siano disponibili Python 3.10 o versione successiva e un endpoint NextPDF Connect.

LivelloResponsabileResponsabilitàDa evitare qui
Origine dell’inputApplicazioneAutorizzare il chiamante, convalidare l’origine del PDF, scegliere la politica di estrazione.URL dell’endpoint o credenziali hardcoded.
Costruzione del clientApplicazioneLeggere base_url e api_key dall’ambiente o da un gestore di segreti.Segreti scritti direttamente nel codice.
NextPDF / AsyncNextPDFSDKCostruire la richiesta, chiamare Connect, restituire modelli Pydantic tipizzati.Logica di dominio o politica di archiviazione.
Spazio dei nomi dei metodi astSDKMappare una chiamata di metodo a un endpoint Connect e analizzare la risposta.Politica di ripetizione o di backoff oltre a quanto configurato.
Endpoint NextPDF ConnectDeploymentEseguire l’estrazione, applicare autenticazione, quote e licenze.Autorizzazione applicativa.

L’SDK non esegue mai il riconoscimento ottico dei caratteri (OCR). Un PDF acquisito da scansione o composto solo da immagini richiede una fase di OCR prima dell’estrazione; questa va trattata come una responsabilità dell’applicazione, esterna a questo confine.

FaseComportamentoAzione dello sviluppatore
Costruzione del clientbase_url e api_key vengono convalidati; un valore vuoto solleva ValueError.Leggerli entrambi dall’ambiente; non inserirli mai direttamente nel codice.
Creazione del backendUn backend remoto inizializza un pool di connessioni verso Connect.Riutilizzare un unico client tra le chiamate, invece di crearne uno per ogni richiesta.
Chiamata di metodoIl metodo ast serializza la richiesta, invia i byte del PDF e analizza la risposta in un modello Pydantic.Passare bytes già convalidati.
Mappatura degli erroriUno stato HTTP di errore viene mappato su una sottoclasse di eccezione specifica.Intercettare prima la classe più specifica.
ArrestoAsyncNextPDF.close() rilascia il pool di connessioni; il context manager asincrono lo chiama automaticamente.Usare async with oppure chiamare close() in un blocco finally.
PercorsoScopo
app/pdf/clients.pyCostruire e mettere in cache un NextPDF o AsyncNextPDF configurato.
app/pdf/extraction.pyWrapper applicativo attorno alle chiamate dei metodi ast.
app/pdf/validation.pyConvalida dell’origine del PDF, limiti di dimensione e controlli del contenuto.
tests/pdf/Test di estrazione, di modalità di errore e di batching asincrono.

Mantenere la convalida del PDF separata dall’estrazione. Il livello di estrazione dovrebbe ricevere byte già autorizzati e con dimensione verificata, continuando comunque a fare affidamento sull’endpoint come difesa in profondità.

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)

Usare il client sincrono NextPDF per script, processi batch e notebook. Convalidare l’input prima di chiamare l’SDK e gestire gli errori specifici che la chiamata può sollevare.

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

Formato atteso di un elemento del risultato:

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

Usare il client asincrono AsyncNextPDF in runtime asyncio, per esempio FastAPI. Costruire un unico client come context manager asincrono e condividerlo tra le chiamate concorrenti; non aprirne uno per ogni documento. Limitare la concorrenza con un semaforo per rispettare la quota dell’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))

Non scrivere mai un except vuoto. Gestire l’errore, convertirlo in un risultato definito oppure rilanciarlo.

Punto di estensioneUsarlo perVincolo
AsyncNextPDF(backend=...)Iniettare un backend personalizzato o locale nei test.Il backend deve soddisfare il protocollo PdfBackend.
Argomento api_versionVincolare una versione dell’API Connect.Il valore predefinito è v1; modificarlo solo quando l’endpoint supporta la versione di destinazione.
Configurazione dell’ambienteFornire NEXTPDF_BASE_URL e NEXTPDF_API_KEY alla CLI e al server MCP.Trattare la chiave come un segreto con ambito limitato al carico di lavoro.
Server MCP (python -m nextpdf.mcp)Esporre gli strumenti di estrazione ad agenti compatibili con MCP.Richiede l’extra nextpdf[mcp] e un endpoint controllato.
  1. Installare l’SDK con pip install nextpdf oppure pip install nextpdf[mcp] per il server per agenti.
  2. Leggere NEXTPDF_BASE_URL e NEXTPDF_API_KEY dall’ambiente, così da evitare che i segreti entrino nel controllo del codice sorgente.
  3. Convalidare ogni origine PDF — esistenza, dimensione e i magic byte %PDF- — prima di chiamare l’SDK.
  4. Costruire un client per processo e riutilizzarlo; per asyncio, mantenerlo aperto con async with.
  5. Chiamare il metodo ast più mirato all’attività: extract_cited_text() per la prosa, extract_cited_tables() per le tabelle, get_document_ast() solo quando serve l’intero albero.
  6. Intercettare l’eccezione più specifica su cui è possibile agire, quindi ripiegare su NextPDFError.
  7. Per i documenti oltre 100 MiB, usare il percorso di streaming della CLI invece di materializzare ogni blocco in memoria.
  8. Eseguire il controllo dei tipi con mypy in modalità strict e aggiungere un test del percorso di errore per ogni eccezione gestita.
ErroreEccezioneRisposta consigliata
PDF senza tag, euristiche disattivateAstNoStructTreeError (HTTP 422)Abilitare la modalità euristica sull’endpoint o fornire un PDF taggato.
Timeout della build lato serverAstBuildTimeoutError (HTTP 504)Ridurre l’intervallo di pagine e riprovare.
Livello di licenza richiestoNextPDFLicenseError (HTTP 402)Aggiornare la licenza del server o ripiegare su una funzionalità consentita.
Limite di frequenza o quotaQuotaExceededError (HTTP 429)Attendere retry_after secondi, quindi riprovare con backoff.
Altro errore HTTPNextPDFAPIErrorEsaminare status_code ed error_code; registrare l’evento nel log e restituire un errore definito.
Qualsiasi errore dell’SDKNextPDFErrorFallback finale; non lasciarlo mai sfuggire come eccezione non gestita.

L’endpoint segnala gli errori usando una semantica di stato HTTP allineata a RFC 9110 e corpi di errore leggibili dalle macchine allineati a RFC 9457. Ogni eccezione conserva lo status_code di origine. Mappare tali valori sulle risposte di errore dell’applicazione, invece di esporre ai chiamanti dettagli di trasporto.

AspettoImpostazione predefinitaQuando sovrascrivere
Versione dell’APIv1.Modificare solo quando l’endpoint supporta una versione più recente.
Verifica TLSAbilitata; non viene esposta alcuna opzione non sicura.Non disabilitarla mai per il traffico di produzione.
CredenzialiLette dall’ambiente; mai scritte direttamente nel codice.Usare un gestore di segreti in produzione.
Limite di dimensione in memoriaRifiutare i PDF oltre 100 MiB nel percorso client.Ridurlo per i servizi multi-tenant; usare la CLI per file più grandi.
ConcorrenzaLimitata da un semaforo nei batch asincroni.Regolarla in base alla quota dell’endpoint, non al numero di core dell’host.
LoggingRegistrare nome file, dimensione, stato e durata.Non registrare mai nel log i byte del PDF o la chiave API.
  • I test di creazione verificano che un base_url o api_key vuoto sollevi ValueError.
  • I test di convalida coprono input mancanti, vuoti, di dimensioni eccessive e non PDF.
  • I test di estrazione verificano i tipi di modello restituiti e la presenza di un CitationAnchor su ogni blocco.
  • I test delle modalità di errore coprono AstNoStructTreeError, AstBuildTimeoutError, NextPDFLicenseError, QuotaExceededError e NextPDFAPIError.
  • I test asincroni verificano che il client sia usato come context manager async with e che la concorrenza rimanga entro il limite del semaforo.
  • I test del ciclo di vita verificano che close() rilasci il trasporto e sia idempotente.
  • Iniettare un backend fittizio con AsyncNextPDF(backend=...) in modo che i test vengano eseguiti senza un endpoint attivo.