CLI Python
CLI Python
Sezione intitolata “CLI Python”Il comando nextpdf esegue l’estrazione di PDF dal terminale. Basta indirizzarlo a un endpoint NextPDF Connect, passargli un PDF e ricevere un output strutturato — testo con citazioni, tabelle, l’intero Abstract Syntax Tree (AST) semantico o un riepilogo dei metadati — sullo standard output (stdout) o in un file.
Struttura del comando
Sezione intitolata “Struttura del comando”Il comando nextpdf è un gruppo di comandi Click. Le opzioni di connessione e di sessione — --base-url, --api-key, --log-level, --output/-o e --strict — sono definite a livello di gruppo, quindi vanno collocate prima del sottocomando. Il sottocomando e le relative opzioni (come --format o --page) vanno dopo:
nextpdf [GROUP OPTIONS] COMMAND [SUBCOMMAND] PDF_PATH [COMMAND OPTIONS]Collocare un’opzione di gruppo dopo il sottocomando genera un errore. Ad esempio, nextpdf info document.pdf --base-url ... segnala Error: No such option: --base-url ed esce con stato 2, perché quando Click analizza --base-url si trova già all’interno del sottocomando info, che non definisce tale opzione.
Il modo più chiaro per evitare la trappola dell’ordine è fornire le credenziali tramite variabili d’ambiente (vedere Configurare una volta per shell). Gli esempi seguenti mostrano prima la forma con flag espliciti, così l’ordine corretto resta evidente.
Riferimento rapido
Sezione intitolata “Riferimento rapido”Estrarre il testo come JSON:
nextpdf --base-url http://localhost:8080 --api-key "$NEXTPDF_API_KEY" extract text document.pdfEstrarre le tabelle come valori separati da virgola (CSV):
nextpdf --base-url http://localhost:8080 --api-key "$NEXTPDF_API_KEY" extract tables invoice.pdf --format csvEsaminare i metadati e la struttura del documento:
nextpdf --base-url http://localhost:8080 --api-key "$NEXTPDF_API_KEY" info document.pdfOttenere l’intero AST semantico:
nextpdf --base-url http://localhost:8080 --api-key "$NEXTPDF_API_KEY" ast document.pdfStampare la versione dell’SDK installata senza contattare alcun server:
nextpdf versionIl comando version è l’unico comando che non richiede né --base-url né --api-key. Ogni altro comando contatta il server e richiede entrambi.
Ogni esempio legge la chiave API dalla variabile d’ambiente NEXTPDF_API_KEY anziché incorporarla nella riga di comando. Trattare la chiave come un segreto. Una chiave in chiaro nella riga di comando è visibile nella cronologia della shell e nell’elenco dei processi (ps) agli altri utenti dell’host.
Comandi e opzioni
Sezione intitolata “Comandi e opzioni”Opzioni di gruppo
Sezione intitolata “Opzioni di gruppo”Queste opzioni vanno collocate prima del sottocomando. Ogni opzione di connessione può leggere anche da una variabile d’ambiente, quindi è possibile omettere il flag quando la variabile è impostata.
| Opzione | Variabile d’ambiente | Predefinito | Scopo |
|---|---|---|---|
--base-url | NEXTPDF_BASE_URL | (obbligatorio) | URL del server NextPDF Connect. |
--api-key | NEXTPDF_API_KEY | (obbligatorio) | Chiave API per l’autenticazione bearer. |
--log-level | — | warning | Livello di dettaglio del logging: debug, info, warning o error. I log vengono inviati allo standard error (stderr). |
--output, -o | — | stdout | Scrive l’output del comando in un file invece che su stdout. |
--strict | — | off | Riservato per uso futuro. Attualmente il flag viene analizzato ma non modifica il comportamento. |
--help, -h | — | — | Mostra la guida ed esce. |
I valori --base-url e --api-key sono obbligatori per ogni comando tranne version. Se uno dei due manca — senza flag e senza variabile d’ambiente — il comando stampa un errore ed esce con stato 1.
nextpdf extract text
Sezione intitolata “nextpdf extract text”Estrae blocchi di testo con citazioni. Ogni blocco contiene un’ancora di citazione (identificatore del nodo, indice di pagina, bounding box e punteggio di confidenza).
nextpdf [GROUP OPTIONS] extract text PDF_PATH [--format FORMAT] [--page N] [--headings-only]| Opzione | Valori | Predefinito | Scopo |
|---|---|---|---|
--format | json, markdown, plain | json | Formato di output. |
--page | intero | tutte le pagine | Estrae solo questo indice di pagina in base 0. |
--headings-only | flag | off | Estrae solo i nodi di intestazione. |
PDF_PATH è un percorso di file oppure - per leggere i byte del PDF da stdin.
nextpdf extract tables
Sezione intitolata “nextpdf extract tables”Estrae ogni tabella con ancore di citazione e struttura a livello di cella.
nextpdf [GROUP OPTIONS] extract tables PDF_PATH [--format FORMAT] [--page-start N] [--page-end N]| Opzione | Valori | Predefinito | Scopo |
|---|---|---|---|
--format | json, csv | json | Formato di output. |
--page-start | intero | prima pagina | Indice della pagina iniziale (in base 0). |
--page-end | intero | ultima pagina | Indice della pagina finale (in base 0). |
PDF_PATH è un percorso di file oppure - per leggere da stdin.
nextpdf ast
Sezione intitolata “nextpdf ast”Restituisce l’intero AST semantico come JSON: un albero gerarchico di nodi (intestazioni, paragrafi, tabelle, elenchi, figure) con bounding box e contenuto testuale.
nextpdf [GROUP OPTIONS] ast PDF_PATH [--page-start N] [--page-end N] [--token-budget N]| Opzione | Valori | Predefinito | Scopo |
|---|---|---|---|
--page-start | intero | prima pagina | Indice della pagina iniziale (in base 0). |
--page-end | intero | ultima pagina | Indice della pagina finale (in base 0). |
--token-budget | intero | illimitato | Limite approssimativo di token per l’AST restituito. |
PDF_PATH è un percorso di file oppure - per leggere da stdin. Il comando ast produce un singolo albero del documento; non confronta due PDF. Per il confronto strutturale, vedere Ricetta: confrontare due revisioni di PDF.
nextpdf info
Sezione intitolata “nextpdf info”Stampa un riepilogo JSON compatto di un documento: versione dello schema, hash dell’origine, numero di pagine, numero stimato di token, tipo del nodo radice e numero di figli della radice.
nextpdf [GROUP OPTIONS] info PDF_PATHPDF_PATH è un percorso di file oppure - per leggere da stdin.
nextpdf version
Sezione intitolata “nextpdf version”Stampa la versione dell’SDK installata (ad esempio, nextpdf 1.1.0) ed esce. Questo comando non contatta alcun server e non richiede credenziali.
nextpdf versionConfigurare una volta per shell
Sezione intitolata “Configurare una volta per shell”Impostare le opzioni di connessione una sola volta come variabili d’ambiente e omettere i flag ripetuti. Questa forma evita del tutto anche la trappola dell’ordine delle opzioni, perché le credenziali non compaiono mai nella riga di comando.
export NEXTPDF_BASE_URL=http://localhost:8080export NEXTPDF_API_KEY=your-keynextpdf extract text document.pdfSu Windows PowerShell:
$env:NEXTPDF_BASE_URL = "http://localhost:8080"$env:NEXTPDF_API_KEY = "your-key"nextpdf extract text document.pdfÈ preferibile caricare la chiave da un archivio di segreti o da un file .env tenuto fuori dal controllo di versione. Non incollare una chiave di produzione in una sessione di terminale condivisa o in uno script destinato al commit.
Formati di output
Sezione intitolata “Formati di output”Il formato di output si seleziona per ciascun comando con --format. I comandi text e table supportano più formati; ast e info emettono sempre JSON.
| Comando | Formati | Predefinito |
|---|---|---|
extract text | json, markdown, plain | json |
extract tables | json, csv | json |
ast | json | json |
info | json | json |
Scegliere JSON quando un programma a valle richiede indici di pagina, punteggi di confidenza o identificatori di nodo. Scegliere CSV quando le tabelle vengono consumate da un foglio di calcolo o da una pipeline tabellare. Scegliere il testo plain o markdown quando il risultato viene letto da una persona o da uno strumento solo testo.
Analisi dell’output JSON
Sezione intitolata “Analisi dell’output JSON”Il comando text emette un array JSON di blocchi con citazione. Ogni blocco contiene text, un oggetto citation (node_id, page_index, bbox, confidence) e un node_type opzionale. Inviare l’output a un file con --output (oppure reindirizzare stdout), quindi analizzarlo.
Questo esempio di shell utilizza jq per mantenere solo le intestazioni della pagina 0:
nextpdf --output blocks.json extract text report.pdf --format jsonjq '[.[] | select(.citation.page_index == 0 and .node_type == "heading") | .text]' blocks.jsonGli stessi dati si analizzano agevolmente in Python. La CLI scrive un array JSON, che si può caricare con la libreria standard per leggere i campi tipizzati:
"""Parse cited text blocks emitted by `nextpdf extract text --format json`."""
import jsonfrom pathlib import Path
def load_headings(blocks_path: Path) -> list[str]: """Return the text of every heading block on page 0.
Args: blocks_path: Path to the JSON file written by `nextpdf extract text`.
Returns: The text of each heading-type block whose citation is on page 0. """ raw = blocks_path.read_text(encoding="utf-8") blocks: list[dict[str, object]] = json.loads(raw) headings: list[str] = [] for block in blocks: citation = block["citation"] if block.get("node_type") == "heading" and citation["page_index"] == 0: headings.append(str(block["text"])) return headings
if __name__ == "__main__": for heading in load_headings(Path("blocks.json")): print(heading)Quando servono modelli convalidati e tipizzati anziché dizionari grezzi, chiamare direttamente l’SDK invece di analizzare l’output della CLI. Vedere la panoramica di Python per il client NextPDF e il relativo tipo restituito CitedTextBlock.
Analisi dell’output CSV
Sezione intitolata “Analisi dell’output CSV”Con --format csv, il comando table scrive un blocco CSV per ogni tabella. Una riga di commento, # Table N (pM), precede ogni tabella e indica il numero di tabella in base 1 e l’indice di pagina in base 0. Una riga vuota separa le tabelle consecutive. La CLI racchiude tra virgolette ed esegue l’escape dei valori delle celle con il modulo csv di Python, così i valori contenenti virgole, virgolette o ritorni a capo vengono preservati nel round-trip.
nextpdf --output tables.csv extract tables statement.pdf --format csvPoiché il file contiene più blocchi CSV, suddividerlo in corrispondenza delle righe di commento prima di analizzare ciascun blocco come tabella autonoma:
"""Split multi-table CSV output from `nextpdf extract tables --format csv`."""
import csvimport iofrom pathlib import Path
def read_tables(csv_path: Path) -> list[list[list[str]]]: """Parse the multi-block CSV file into a list of tables.
Each table is a list of rows; each row is a list of cell strings. The leading `# Table N (pM)` comment row is dropped from every table.
Args: csv_path: Path to the file written by `nextpdf extract tables`.
Returns: One parsed table per `# Table` block in the file. """ text = csv_path.read_text(encoding="utf-8") tables: list[list[list[str]]] = [] current: list[str] = [] for line in text.splitlines(keepends=True): if line.startswith("# Table ") and current: tables.append(_parse_block(current)) current = [] current.append(line) if current: tables.append(_parse_block(current)) return tables
def _parse_block(lines: list[str]) -> list[list[str]]: """Parse one CSV block, discarding its leading comment row.""" reader = csv.reader(io.StringIO("".join(lines))) rows = [row for row in reader if row] return rows[1:] if rows and rows[0] and rows[0][0].startswith("# Table ") else rows
if __name__ == "__main__": for index, table in enumerate(read_tables(Path("tables.csv")), start=1): print(f"table {index}: {len(table)} rows")Codici di uscita e rilevamento degli errori
Sezione intitolata “Codici di uscita e rilevamento degli errori”La CLI utilizza tre codici di uscita. Controllare $? negli script di shell (oppure $LASTEXITCODE in PowerShell) per diramare in base all’esito, positivo o negativo, e leggere i messaggi diagnostici da stderr, che resta separato dai dati su stdout.
| Codice di uscita | Significato | Esempi |
|---|---|---|
0 | Esito positivo. | Un comando è stato completato; version ha stampato l’output. |
1 | Errore di runtime. La CLI stampa Error: <message> su stderr. | File di input non trovato o non regolare, stdin vuoto, --base-url/--api-key mancante o non valido, qualsiasi errore lato server (licenza richiesta, quota superata, PDF non taggato, timeout di build o altro errore dell’API). |
2 | Errore d’uso, segnalato da Click. | Comando od opzione sconosciuti (incluso un’opzione di gruppo collocata dopo il sottocomando), un argomento obbligatorio mancante come PDF_PATH. |
Ogni errore lato server si manifesta con codice di uscita 1 e un messaggio leggibile su stderr. L’SDK solleva un’eccezione tipizzata — NextPDFLicenseError (HTTP 402), QuotaExceededError (HTTP 429), AstNoStructTreeError (HTTP 422, PDF non taggato), AstBuildTimeoutError (HTTP 504) o la classe base NextPDFAPIError. La CLI le intercetta tutte sotto la classe base condivisa NextPDFError, stampa il messaggio ed esce con 1. La CLI non espone codici di uscita distinti per tipo di errore. Per distinguere, ad esempio, un errore di quota da un errore di licenza in uno script, esaminare il testo del messaggio su stderr o chiamare direttamente l’SDK (vedere la panoramica di Python per le classi delle eccezioni).
Uno schema di scripting che separa i dati dalla diagnostica:
#!/usr/bin/env bashset -euo pipefail
# Credentials come from the environment, not the command line.: "${NEXTPDF_BASE_URL:?set NEXTPDF_BASE_URL}": "${NEXTPDF_API_KEY:?set NEXTPDF_API_KEY}"
if nextpdf --output contract.ast.json ast contract.pdf; then echo "AST written to contract.ast.json"else status=$? echo "nextpdf failed with exit code ${status}" >&2 exit "${status}"fiSi noti che --output scrive i dati nel file indicato e stampa solo la riga di conferma Written to <path> su stderr, quindi stdout resta vuoto. Senza --output, i dati vengono inviati a stdout e possono essere reindirizzati.
Ricette
Sezione intitolata “Ricette”Ogni ricetta seguente utilizza solo comandi e flag verificati. In tutti i casi, le credenziali provengono dall’ambiente.
Ricetta: estrarre le tabelle delle fatture in CSV
Sezione intitolata “Ricetta: estrarre le tabelle delle fatture in CSV”Trasformare una cartella di fatture in un file CSV per documento, da usare in un foglio di calcolo o in una pipeline contabile:
#!/usr/bin/env bashset -euo pipefail
: "${NEXTPDF_BASE_URL:?set NEXTPDF_BASE_URL}": "${NEXTPDF_API_KEY:?set NEXTPDF_API_KEY}"
mkdir -p outfor pdf in invoices/*.pdf; do name="$(basename "${pdf}" .pdf)" nextpdf --output "out/${name}.csv" extract tables "${pdf}" --format csvdoneOgni out/<name>.csv contiene un blocco CSV per ogni tabella rilevata, con un’intestazione # Table N (pM) prima di ciascuna tabella. Analizzare i blocchi con il lettore CSV mostrato sopra.
Ricetta: costruire una struttura del documento
Sezione intitolata “Ricetta: costruire una struttura del documento”Combinare --headings-only con il formato markdown per produrre rapidamente una struttura leggibile o da incollare negli appunti:
nextpdf --output outline.md extract text whitepaper.pdf --headings-only --format markdownRicetta: confrontare due revisioni di PDF
Sezione intitolata “Ricetta: confrontare due revisioni di PDF”Il comando ast della CLI restituisce l’albero di un singolo documento; non dispone di un sottocomando di confronto. Il confronto strutturale è disponibile nell’SDK come client.ast.get_ast_diff(...) e nel server Model Context Protocol (MCP) come strumento nextpdf_diff. Eseguire il confronto tramite l’SDK:
"""Compare two PDF revisions structurally with the NextPDF SDK.
The API key is read from the environment, never hard-coded."""
import osfrom pathlib import Path
from nextpdf import NextPDF
def diff_revisions(original: Path, modified: Path) -> None: """Print a structural diff summary between two PDF revisions.
Args: original: Path to the earlier PDF revision. modified: Path to the later PDF revision. """ base_url = os.environ["NEXTPDF_BASE_URL"] api_key = os.environ["NEXTPDF_API_KEY"]
client = NextPDF(base_url=base_url, api_key=api_key) result = client.ast.get_ast_diff( original.read_bytes(), modified.read_bytes(), )
summary = result.summary print(f"added: {summary.added_node_count}") print(f"removed: {summary.removed_node_count}") print(f"changed: {summary.changed_node_count}") for entry in result.diff: preview = entry.text_preview or "" print(f" {entry.type:<8} {entry.node_type:<12} p{entry.page_index} {preview}")
if __name__ == "__main__": diff_revisions(Path("contract-v1.pdf"), Path("contract-v2.pdf"))Per eseguire lo stesso confronto da un agente IA anziché da uno script, registrare il server MCP e chiamare lo strumento nextpdf_diff. Vedere la pagina del server MCP di Python.
Ricetta: trasmettere un PDF in ingresso da un altro strumento
Sezione intitolata “Ricetta: trasmettere un PDF in ingresso da un altro strumento”Leggere i byte del PDF da stdin con - per concatenare nextpdf dopo uno strumento che emette un PDF sul proprio stdout:
curl --silent https://example.com/report.pdf | nextpdf info -L’argomento - indica al comando di leggere il documento da stdin. Se non arriva alcun byte, il comando segnala un errore ed esce con 1.
Note sulle prestazioni
Sezione intitolata “Note sulle prestazioni”La CLI costruisce ogni risposta in memoria e la scrive in un’unica operazione: reindirizzare o convogliare l’output è quindi semplice, ma l’output non viene prodotto in modo incrementale. Un AST o un insieme di tabelle di grandi dimensioni viene interamente bufferizzato prima che il primo byte raggiunga stdout o il file --output. Pianificare memoria e latenza per risposte sull’intero documento, non per un flusso.
Ogni invocazione di nextpdf crea un nuovo client e una nuova connessione HTTP, quindi un ciclo su molti file apre e chiude una connessione per file. Il costo della connessione è di solito ridotto rispetto al tempo di estrazione lato server, ma su larga scala rappresenta un overhead reale.
- Riutilizzare un solo endpoint. Indirizzare ogni invocazione allo stesso deployment NextPDF Connect, in modo che il server possa riutilizzare cache già pronte e pool di connessioni. Evitare di distribuire un batch su più endpoint, a meno che il bilanciamento del carico non sia intenzionale.
- Limitare il lavoro per chiamata. Usare
--page,--page-start/--page-endo--token-budgetper elaborare solo le pagine necessarie. Intervalli di pagine più piccoli riducono sia il tempo del server sia la dimensione della risposta;--token-budgetlimita l’AST che l’agente deve leggere. - Eseguire i batch in un solo processo per i lavori di grandi dimensioni. Per i batch ad alto volume, è preferibile usare l’SDK Python invece di chiamare ripetutamente la CLI. Un singolo client
NextPDF(oAsyncNextPDF) a lunga durata riutilizza una connessione HTTP in pool per ogni documento, eliminando l’avvio del processo e la configurazione della connessione che un ciclo della CLI paga ogni volta. La panoramica di Python mostra il ciclo di vita del client eAsyncNextPDFsupporta l’estrazione concorrente su molti PDF. - Tenere i log fuori dal percorso dei dati. Lasciare
--log-levelal valore predefinito per le esecuzioni batch. I log diagnostici vanno su stderr e non corrompono i dati su stdout, ma alzare il livello adebugaggiunge rumore e un lieve overhead.