Guida per sviluppatori dell'SDK Python
In breve
Sezione intitolata “In breve”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.
Confine architetturale
Sezione intitolata “Confine architetturale”| Livello | Responsabile | Responsabilità | Da evitare qui |
|---|---|---|---|
| Origine dell’input | Applicazione | Autorizzare il chiamante, convalidare l’origine del PDF, scegliere la politica di estrazione. | URL dell’endpoint o credenziali hardcoded. |
| Costruzione del client | Applicazione | Leggere base_url e api_key dall’ambiente o da un gestore di segreti. | Segreti scritti direttamente nel codice. |
NextPDF / AsyncNextPDF | SDK | Costruire la richiesta, chiamare Connect, restituire modelli Pydantic tipizzati. | Logica di dominio o politica di archiviazione. |
Spazio dei nomi dei metodi ast | SDK | Mappare una chiamata di metodo a un endpoint Connect e analizzare la risposta. | Politica di ripetizione o di backoff oltre a quanto configurato. |
| Endpoint NextPDF Connect | Deployment | Eseguire 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.
Ciclo di vita di runtime
Sezione intitolata “Ciclo di vita di runtime”| Fase | Comportamento | Azione dello sviluppatore |
|---|---|---|
| Costruzione del client | base_url e api_key vengono convalidati; un valore vuoto solleva ValueError. | Leggerli entrambi dall’ambiente; non inserirli mai direttamente nel codice. |
| Creazione del backend | Un 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 metodo | Il metodo ast serializza la richiesta, invia i byte del PDF e analizza la risposta in un modello Pydantic. | Passare bytes già convalidati. |
| Mappatura degli errori | Uno stato HTTP di errore viene mappato su una sottoclasse di eccezione specifica. | Intercettare prima la classe più specifica. |
| Arresto | AsyncNextPDF.close() rilascia il pool di connessioni; il context manager asincrono lo chiama automaticamente. | Usare async with oppure chiamare close() in un blocco finally. |
Struttura dell’applicazione consigliata
Sezione intitolata “Struttura dell’applicazione consigliata”| Percorso | Scopo |
|---|---|
app/pdf/clients.py | Costruire e mettere in cache un NextPDF o AsyncNextPDF configurato. |
app/pdf/extraction.py | Wrapper applicativo attorno alle chiamate dei metodi ast. |
app/pdf/validation.py | Convalida 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)Pattern del client sincrono
Sezione intitolata “Pattern del client sincrono”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 errorFormato atteso di un elemento del risultato:
block = blocks[0]print(block.text) # the extracted textprint(block.citation.page_index) # 0-based page indexprint(block.citation.confidence) # 0.0 - 1.0Pattern asincrono e di batching
Sezione intitolata “Pattern asincrono e di batching”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 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))Non scrivere mai un except vuoto. Gestire l’errore, convertirlo in un risultato definito oppure rilanciarlo.
Punti di estensione
Sezione intitolata “Punti di estensione”| Punto di estensione | Usarlo per | Vincolo |
|---|---|---|
AsyncNextPDF(backend=...) | Iniettare un backend personalizzato o locale nei test. | Il backend deve soddisfare il protocollo PdfBackend. |
Argomento api_version | Vincolare una versione dell’API Connect. | Il valore predefinito è v1; modificarlo solo quando l’endpoint supporta la versione di destinazione. |
| Configurazione dell’ambiente | Fornire 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. |
Flusso di lavoro di sviluppo
Sezione intitolata “Flusso di lavoro di sviluppo”- Installare l’SDK con
pip install nextpdfoppurepip install nextpdf[mcp]per il server per agenti. - Leggere
NEXTPDF_BASE_URLeNEXTPDF_API_KEYdall’ambiente, così da evitare che i segreti entrino nel controllo del codice sorgente. - Convalidare ogni origine PDF — esistenza, dimensione e i magic byte
%PDF-— prima di chiamare l’SDK. - Costruire un client per processo e riutilizzarlo; per asyncio, mantenerlo aperto con
async with. - Chiamare il metodo
astpiù mirato all’attività:extract_cited_text()per la prosa,extract_cited_tables()per le tabelle,get_document_ast()solo quando serve l’intero albero. - Intercettare l’eccezione più specifica su cui è possibile agire, quindi ripiegare su
NextPDFError. - Per i documenti oltre 100 MiB, usare il percorso di streaming della CLI invece di materializzare ogni blocco in memoria.
- Eseguire il controllo dei tipi con mypy in modalità strict e aggiungere un test del percorso di errore per ogni eccezione gestita.
Gestione degli errori
Sezione intitolata “Gestione degli errori”| Errore | Eccezione | Risposta consigliata |
|---|---|---|
| PDF senza tag, euristiche disattivate | AstNoStructTreeError (HTTP 422) | Abilitare la modalità euristica sull’endpoint o fornire un PDF taggato. |
| Timeout della build lato server | AstBuildTimeoutError (HTTP 504) | Ridurre l’intervallo di pagine e riprovare. |
| Livello di licenza richiesto | NextPDFLicenseError (HTTP 402) | Aggiornare la licenza del server o ripiegare su una funzionalità consentita. |
| Limite di frequenza o quota | QuotaExceededError (HTTP 429) | Attendere retry_after secondi, quindi riprovare con backoff. |
| Altro errore HTTP | NextPDFAPIError | Esaminare status_code ed error_code; registrare l’evento nel log e restituire un errore definito. |
| Qualsiasi errore dell’SDK | NextPDFError | Fallback 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.
Impostazioni predefinite sicure
Sezione intitolata “Impostazioni predefinite sicure”| Aspetto | Impostazione predefinita | Quando sovrascrivere |
|---|---|---|
| Versione dell’API | v1. | Modificare solo quando l’endpoint supporta una versione più recente. |
| Verifica TLS | Abilitata; non viene esposta alcuna opzione non sicura. | Non disabilitarla mai per il traffico di produzione. |
| Credenziali | Lette dall’ambiente; mai scritte direttamente nel codice. | Usare un gestore di segreti in produzione. |
| Limite di dimensione in memoria | Rifiutare i PDF oltre 100 MiB nel percorso client. | Ridurlo per i servizi multi-tenant; usare la CLI per file più grandi. |
| Concorrenza | Limitata da un semaforo nei batch asincroni. | Regolarla in base alla quota dell’endpoint, non al numero di core dell’host. |
| Logging | Registrare nome file, dimensione, stato e durata. | Non registrare mai nel log i byte del PDF o la chiave API. |
Elenco di controllo dei test
Sezione intitolata “Elenco di controllo dei test”- I test di creazione verificano che un
base_urloapi_keyvuoto solleviValueError. - 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
CitationAnchorsu ogni blocco. - I test delle modalità di errore coprono
AstNoStructTreeError,AstBuildTimeoutError,NextPDFLicenseError,QuotaExceededErroreNextPDFAPIError. - I test asincroni verificano che il client sia usato come context manager
async withe 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.
Vedere anche
Sezione intitolata “Vedere anche”- Riferimento API Python — ogni metodo, modello ed eccezione del client.
- CLI Python — estrazione in streaming per documenti di grandi dimensioni.
- Server MCP Python — esporre gli strumenti di estrazione agli agenti AI.
- Panoramica dell’SDK Python — scelte di backend e limitazioni.