Python-CLI
Python-CLI
Abschnitt betitelt „Python-CLI“Mit dem Befehl nextpdf führen Sie die PDF-Extraktion im Terminal aus. Sie richten ihn auf einen NextPDF Connect-Endpunkt aus, übergeben ein PDF und erhalten eine strukturierte Ausgabe — zitierten Text, Tabellen, den vollständigen semantischen Abstract Syntax Tree (AST) oder eine Metadatenzusammenfassung — auf der Standardausgabe (stdout) oder in einer Datei.
Befehlsaufbau
Abschnitt betitelt „Befehlsaufbau“Der Befehl nextpdf ist eine Click-Befehlsgruppe. Verbindungs- und Sitzungsoptionen — --base-url, --api-key, --log-level, --output/-o und --strict — sind an der Gruppe definiert; Sie platzieren sie also vor dem Unterbefehl. Der Unterbefehl und seine eigenen Optionen (etwa --format oder --page) folgen danach:
nextpdf [GROUP OPTIONS] COMMAND [SUBCOMMAND] PDF_PATH [COMMAND OPTIONS]Eine Gruppenoption hinter dem Unterbefehl schlägt fehl. nextpdf info document.pdf --base-url ... meldet zum Beispiel Error: No such option: --base-url und beendet sich mit Status 2, weil --base-url beim Parsen durch Click bereits dem Unterbefehl info zugeordnet ist, der diese Option nicht definiert.
Der klarste Weg, die Reihenfolgefalle zu vermeiden, besteht darin, die Zugangsdaten über Umgebungsvariablen bereitzustellen (siehe Einmal pro Shell konfigurieren). Die folgenden Beispiele zeigen zuerst die Form mit expliziten Flags, damit die richtige Reihenfolge klar ist.
Kurzreferenz
Abschnitt betitelt „Kurzreferenz“Text als JSON extrahieren:
nextpdf --base-url http://localhost:8080 --api-key "$NEXTPDF_API_KEY" extract text document.pdfTabellen als kommagetrennte Werte (CSV) extrahieren:
nextpdf --base-url http://localhost:8080 --api-key "$NEXTPDF_API_KEY" extract tables invoice.pdf --format csvDokument-Metadaten und -Struktur untersuchen:
nextpdf --base-url http://localhost:8080 --api-key "$NEXTPDF_API_KEY" info document.pdfDen vollständigen semantischen AST abrufen:
nextpdf --base-url http://localhost:8080 --api-key "$NEXTPDF_API_KEY" ast document.pdfDie installierte SDK-Version ausgeben, ohne einen Server zu kontaktieren:
nextpdf versionDer Befehl version ist der einzige Befehl, der weder --base-url noch --api-key benötigt. Jeder andere Befehl kontaktiert den Server und benötigt beide.
Jedes Beispiel liest den API-Schlüssel aus der Umgebungsvariablen NEXTPDF_API_KEY, statt ihn in die Kommandozeile einzubetten. Behandeln Sie den Schlüssel als Geheimnis. Ein direkt in der Kommandozeile angegebener Schlüssel ist in Ihrer Shell-Historie und in der Prozessliste (ps) für andere Benutzer auf dem Host sichtbar.
Befehle und Optionen
Abschnitt betitelt „Befehle und Optionen“Gruppenoptionen
Abschnitt betitelt „Gruppenoptionen“Diese Optionen platzieren Sie vor dem Unterbefehl. Jede Verbindungsoption liest auch aus einer Umgebungsvariablen, sodass Sie das Flag weglassen können, wenn die Variable gesetzt ist.
| Option | Umgebungsvariable | Standard | Zweck |
|---|---|---|---|
--base-url | NEXTPDF_BASE_URL | (erforderlich) | URL des NextPDF Connect-Servers. |
--api-key | NEXTPDF_API_KEY | (erforderlich) | API-Schlüssel für die Bearer-Authentifizierung. |
--log-level | — | warning | Protokollausführlichkeit: debug, info, warning oder error. Protokolle werden an die Standardfehlerausgabe (stderr) geschrieben. |
--output, -o | — | stdout | Schreibt die Befehlsausgabe in eine Datei statt nach stdout. |
--strict | — | off | Für zukünftige Verwendung reserviert. Das Flag wird heute geparst, ändert aber das Verhalten nicht. |
--help, -h | — | — | Zeigt die Hilfe an und beendet den Befehl. |
Die Werte für --base-url und --api-key sind für jeden Befehl außer version erforderlich. Fehlt einer von beiden — weder Flag noch Umgebungsvariable —, gibt der Befehl einen Fehler aus und beendet sich mit Status 1.
nextpdf extract text
Abschnitt betitelt „nextpdf extract text“Extrahiert zitierte Textblöcke. Jeder Block trägt einen Zitatanker (Knotenbezeichner, Seitenindex, Begrenzungsrahmen und einen Konfidenzwert).
nextpdf [GROUP OPTIONS] extract text PDF_PATH [--format FORMAT] [--page N] [--headings-only]| Option | Werte | Standard | Zweck |
|---|---|---|---|
--format | json, markdown, plain | json | Ausgabeformat. |
--page | Ganzzahl | alle Seiten | Extrahiert nur die Seite mit diesem 0-basierten Seitenindex. |
--headings-only | Flag | off | Extrahiert nur Überschriftenknoten. |
PDF_PATH ist ein Dateipfad oder -, um PDF-Bytes von stdin zu lesen.
nextpdf extract tables
Abschnitt betitelt „nextpdf extract tables“Extrahiert jede Tabelle mit Zitatankern und zellgenauer Struktur.
nextpdf [GROUP OPTIONS] extract tables PDF_PATH [--format FORMAT] [--page-start N] [--page-end N]| Option | Werte | Standard | Zweck |
|---|---|---|---|
--format | json, csv | json | Ausgabeformat. |
--page-start | Ganzzahl | erste Seite | Startseitenindex (0-basiert). |
--page-end | Ganzzahl | letzte Seite | Endseitenindex (0-basiert). |
PDF_PATH ist ein Dateipfad oder -, um von stdin zu lesen.
nextpdf ast
Abschnitt betitelt „nextpdf ast“Gibt den vollständigen semantischen AST als JSON zurück: einen hierarchischen Baum aus Knoten (Überschriften, Absätze, Tabellen, Listen, Abbildungen) mit Begrenzungsrahmen und Textinhalten.
nextpdf [GROUP OPTIONS] ast PDF_PATH [--page-start N] [--page-end N] [--token-budget N]| Option | Werte | Standard | Zweck |
|---|---|---|---|
--page-start | Ganzzahl | erste Seite | Startseitenindex (0-basiert). |
--page-end | Ganzzahl | letzte Seite | Endseitenindex (0-basiert). |
--token-budget | Ganzzahl | unbegrenzt | Ungefähres Tokenlimit für den zurückgegebenen AST. |
PDF_PATH ist ein Dateipfad oder -, um von stdin zu lesen. Der Befehl ast erzeugt einen einzelnen Dokumentbaum; er vergleicht keine zwei PDFs. Informationen zum strukturellen Diffing finden Sie unter Recipe: Zwei PDF-Revisionen vergleichen.
nextpdf info
Abschnitt betitelt „nextpdf info“Gibt eine kompakte JSON-Zusammenfassung eines Dokuments aus: Schemaversion, Quellhash, Seitenzahl, geschätzte Tokenanzahl, den Typ des Wurzelknotens und die Anzahl der direkten Kindknoten der Wurzel.
nextpdf [GROUP OPTIONS] info PDF_PATHPDF_PATH ist ein Dateipfad oder -, um von stdin zu lesen.
nextpdf version
Abschnitt betitelt „nextpdf version“Gibt die installierte SDK-Version aus (zum Beispiel nextpdf 1.1.0) und beendet den Befehl. Dieser Befehl kontaktiert keinen Server und benötigt keine Zugangsdaten.
nextpdf versionEinmal pro Shell konfigurieren
Abschnitt betitelt „Einmal pro Shell konfigurieren“Setzen Sie die Verbindungsoptionen einmal als Umgebungsvariablen und lassen Sie die wiederholten Flags weg. Diese Form vermeidet zudem die Reihenfolgefalle der Optionen vollständig, weil die Zugangsdaten nie auf der Kommandozeile erscheinen.
export NEXTPDF_BASE_URL=http://localhost:8080export NEXTPDF_API_KEY=your-keynextpdf extract text document.pdfUnter Windows PowerShell:
$env:NEXTPDF_BASE_URL = "http://localhost:8080"$env:NEXTPDF_API_KEY = "your-key"nextpdf extract text document.pdfLaden Sie den Schlüssel vorzugsweise aus einem Secret-Store oder einer .env-Datei, die Sie aus der Versionsverwaltung heraushalten. Fügen Sie keinen Produktionsschlüssel in eine gemeinsam genutzte Terminalsitzung oder in ein Skript ein, das Sie einchecken.
Ausgabeformate
Abschnitt betitelt „Ausgabeformate“Sie wählen das Ausgabeformat pro Befehl mit --format. Die Befehle für Text und Tabellen unterstützen mehr als ein Format; ast und info geben immer JSON aus.
| Befehl | Formate | Standard |
|---|---|---|
extract text | json, markdown, plain | json |
extract tables | json, csv | json |
ast | json | json |
info | json | json |
Wählen Sie JSON, wenn ein nachgelagertes Programm Seitenindizes, Konfidenzwerte oder Knotenbezeichner benötigt. Wählen Sie CSV, wenn eine Tabellenkalkulation oder eine tabellarische Pipeline die Tabellen verarbeitet. Wählen Sie plain oder markdown, wenn eine Person oder ein reines Text-Tool das Ergebnis liest.
JSON-Ausgabe parsen
Abschnitt betitelt „JSON-Ausgabe parsen“Der Textbefehl gibt ein JSON-Array zitierter Blöcke aus. Jeder Block hat text, ein citation-Objekt (node_id, page_index, bbox, confidence) und ein optionales node_type. Schreiben Sie die Ausgabe mit --output in eine Datei (oder leiten Sie stdout um) und parsen Sie sie anschließend.
Dieses Shell-Beispiel verwendet jq, um nur Überschriften auf Seite 0 zu behalten:
nextpdf --output blocks.json extract text report.pdf --format jsonjq '[.[] | select(.citation.page_index == 0 and .node_type == "heading") | .text]' blocks.jsonDieselben Daten lassen sich sauber in Python parsen. Die CLI schreibt ein JSON-Array; Sie laden es also mit der Standardbibliothek und lesen die typisierten Felder:
"""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)Wenn Sie die validierten, typisierten Modelle statt roher Dictionaries benötigen, rufen Sie das SDK direkt auf, anstatt die CLI-Ausgabe zu parsen. Siehe die Python-Übersicht für den NextPDF-Client und seinen Rückgabetyp CitedTextBlock.
CSV-Ausgabe parsen
Abschnitt betitelt „CSV-Ausgabe parsen“Mit --format csv schreibt der Tabellenbefehl einen CSV-Block pro Tabelle. Eine Kommentarzeile, # Table N (pM), steht vor jeder Tabelle und nennt ihre 1-basierte Tabellennummer und ihren 0-basierten Seitenindex. Eine Leerzeile trennt aufeinanderfolgende Tabellen. Die CLI maskiert Zellwerte und escaped sie mit Pythons csv-Modul, sodass Werte mit Kommas, Anführungszeichen oder Zeilenumbrüchen sicher erhalten bleiben.
nextpdf --output tables.csv extract tables statement.pdf --format csvDa die Datei mehrere CSV-Blöcke enthält, teilen Sie sie an den Kommentarzeilen auf, bevor Sie jeden Block als eigenständige Tabelle parsen:
"""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")Exit-Codes und Fehlererkennung
Abschnitt betitelt „Exit-Codes und Fehlererkennung“Die CLI verwendet drei Exit-Codes. Prüfen Sie $? in Shell-Skripten (oder $LASTEXITCODE in PowerShell), um auf Erfolg oder Fehler zu verzweigen, und lesen Sie Diagnosemeldungen von stderr, das von den Daten auf stdout getrennt bleibt.
| Exit-Code | Bedeutung | Beispiele |
|---|---|---|
0 | Erfolg. | Ein Befehl wurde erfolgreich abgeschlossen; version wurde ausgegeben. |
1 | Laufzeitfehler. Die CLI gibt Error: <message> nach stderr aus. | Eingabedatei nicht gefunden oder keine reguläre Datei, leeres stdin, fehlendes oder ungültiges --base-url/--api-key, jeder serverseitige Fehler (Lizenz erforderlich, Kontingent überschritten, ungetaggtes PDF, Build-Timeout oder ein anderer API-Fehler). |
2 | Verwendungsfehler, von Click gemeldet. | Unbekannter Befehl oder unbekannte Option (einschließlich einer Gruppenoption hinter dem Unterbefehl), ein fehlendes erforderliches Argument wie PDF_PATH. |
Jeder serverseitige Fehler erscheint als Exit-Code 1 mit einer menschenlesbaren Meldung auf stderr. Das SDK löst eine typisierte Ausnahme aus — NextPDFLicenseError (HTTP 402), QuotaExceededError (HTTP 429), AstNoStructTreeError (HTTP 422, ungetaggtes PDF), AstBuildTimeoutError (HTTP 504) oder die Basisklasse NextPDFAPIError. Die CLI fängt sie alle über ihre gemeinsame Basisklasse NextPDFError ab, gibt die Meldung aus und beendet sich mit 1. Die CLI stellt keine eigenen Exit-Codes pro Fehlertyp bereit. Um in einem Skript etwa einen Kontingentfehler von einem Lizenzfehler zu unterscheiden, prüfen Sie den Meldungstext auf stderr oder rufen Sie das SDK direkt auf (siehe die Python-Übersicht für die Ausnahmeklassen).
Ein Skriptmuster, das Daten und Diagnosen trennt:
#!/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}"fiBeachten Sie, dass --output die Daten in die genannte Datei schreibt und nur die Bestätigungszeile Written to <path> nach stderr ausgibt, sodass stdout leer bleibt. Ohne --output gehen die Daten nach stdout, und Sie können sie umleiten.
Recipes
Abschnitt betitelt „Recipes“Jedes der folgenden Recipes verwendet ausschließlich verifizierte Befehle und Flags. Die Zugangsdaten kommen in jedem Fall aus der Umgebung.
Recipe: Rechnungstabellen nach CSV extrahieren
Abschnitt betitelt „Recipe: Rechnungstabellen nach CSV extrahieren“Verwandeln Sie einen Ordner voller Rechnungen für eine Tabellenkalkulations- oder Buchhaltungs-Pipeline in je eine CSV-Datei pro Dokument:
#!/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 csvdoneJede out/<name>.csv enthält einen CSV-Block pro erkannter Tabelle, mit einem vorangestellten # Table N (pM)-Header. Parsen Sie die Blöcke mit dem oben gezeigten CSV-Reader.
Recipe: Eine Dokument-Gliederung erstellen
Abschnitt betitelt „Recipe: Eine Dokument-Gliederung erstellen“Kombinieren Sie --headings-only mit dem Format markdown, um schnell eine Gliederung zu erzeugen, die Sie lesen oder in Notizen einfügen können:
nextpdf --output outline.md extract text whitepaper.pdf --headings-only --format markdownRecipe: Zwei PDF-Revisionen vergleichen
Abschnitt betitelt „Recipe: Zwei PDF-Revisionen vergleichen“Der Befehl ast der CLI gibt den Baum für ein einzelnes Dokument zurück; er hat keinen Diff-Unterbefehl. Strukturelles Diffing liegt im SDK als client.ast.get_ast_diff(...) und im Model Context Protocol (MCP)-Server als Tool nextpdf_diff vor. Führen Sie den Diff über das SDK aus:
"""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"))Um denselben Diff aus einem KI-Agenten statt aus einem Skript auszuführen, registrieren Sie den MCP-Server und rufen Sie das Tool nextpdf_diff auf. Siehe die Seite Python-MCP-Server.
Recipe: Ein PDF aus einem anderen Tool einspeisen
Abschnitt betitelt „Recipe: Ein PDF aus einem anderen Tool einspeisen“Lesen Sie PDF-Bytes mit - von stdin, um nextpdf an ein Tool anzuschließen, das ein PDF auf stdout ausgibt:
curl --silent https://example.com/report.pdf | nextpdf info -Das Argument - weist den Befehl an, das Dokument von stdin zu lesen. Gehen keine Bytes ein, meldet der Befehl einen Fehler und beendet sich mit 1.
Hinweise zur Performance
Abschnitt betitelt „Hinweise zur Performance“Die CLI baut jede Antwort im Speicher auf und schreibt sie einmal, sodass das Umleiten oder Weiterleiten der Ausgabe unkompliziert ist, die Ausgabe aber nicht inkrementell erzeugt wird. Ein großer AST oder Tabellensatz wird vollständig gepuffert, bevor das erste Byte stdout oder die --output-Datei erreicht. Planen Sie Speicher und Latenz für Antworten über das gesamte Dokument ein, nicht für einen Stream.
Jeder Aufruf von nextpdf erstellt einen frischen Client und eine frische HTTP-Verbindung, sodass eine Schleife über viele Dateien pro Datei eine Verbindung öffnet und schließt. Die Verbindungskosten sind neben der serverseitigen Extraktionszeit meist gering, verursachen im großen Maßstab aber realen Overhead.
- Einen Endpunkt wiederverwenden. Richten Sie jeden Aufruf auf dasselbe NextPDF Connect-Deployment, damit der Server aufgewärmte Caches und Connection-Pools wiederverwendet. Vermeiden Sie es, einen Batch über mehrere Endpunkte zu verteilen, sofern Sie nicht bewusst Lastverteilung betreiben.
- Begrenzen Sie die Arbeit pro Aufruf. Verwenden Sie
--page,--page-start/--page-endoder--token-budget, um nur die Seiten zu verarbeiten, die Sie benötigen. Kleinere Seitenbereiche senken sowohl die Serverzeit als auch die Antwortgröße;--token-budgetbegrenzt den AST, den Ihr Agent lesen muss. - Große Jobs in einem Prozess bündeln. Bevorzugen Sie für umfangreiche Batches das Python-SDK gegenüber wiederholten CLI-Aufrufen. Ein einzelner langlebiger
NextPDF- (oderAsyncNextPDF-)Client verwendet für mehrere Dokumente eine gepoolte HTTP-Verbindung wieder. Dadurch entfallen Prozessstart und Verbindungsaufbau, die eine CLI-Schleife jedes Mal tragen muss. Die Python-Übersicht zeigt den Lebenszyklus des Clients, undAsyncNextPDFunterstützt nebenläufige Extraktion über viele PDFs hinweg. - Halten Sie Protokolle aus dem Datenpfad heraus. Belassen Sie
--log-levelfür Batch-Läufe auf seinem Standardwert. Diagnoseprotokolle gehen an stderr und beschädigen die stdout-Daten nicht, doch das Anheben des Levels aufdebugerzeugt Rauschen und einen geringen Overhead.