Przejdź do głównej zawartości

Interfejs wiersza poleceń (CLI) w Pythonie

Używaj polecenia nextpdf, aby wyodrębniać treść z plików Portable Document Format (PDF) bezpośrednio w terminalu. Wskaż punkt końcowy NextPDF Connect, przekaż plik PDF i odbierz uporządkowane dane wyjściowe — cytowany tekst, tabele, pełne semantyczne abstrakcyjne drzewo składniowe (AST) albo podsumowanie metadanych — na standardowym wyjściu (stdout) lub w pliku.

Polecenie nextpdf jest grupą poleceń biblioteki Click. Opcje połączenia i sesji — --base-url, --api-key, --log-level, --output/-o oraz --strict — należą do grupy, dlatego umieść je przed podpoleceniem. Podpolecenie i jego opcje, takie jak --format lub --page, umieść po nim:

nextpdf [GROUP OPTIONS] COMMAND [SUBCOMMAND] PDF_PATH [COMMAND OPTIONS]

Jeśli umieścisz opcję grupy po podpoleceniu, polecenie zakończy się niepowodzeniem. Na przykład nextpdf info document.pdf --base-url ... zgłasza Error: No such option: --base-url i kończy działanie z kodem stanu 2, ponieważ Click przetwarza już podpolecenie info w momencie napotkania --base-url, a info nie definiuje tej opcji.

Aby uniknąć problemów z kolejnością, przekaż poświadczenia za pomocą zmiennych środowiskowych (zobacz Konfiguracja raz na powłokę). Poniższe przykłady najpierw pokazują formę z jawnymi flagami, aby prawidłowa kolejność była czytelna.

Wyodrębnij tekst w formacie JavaScript Object Notation (JSON):

Okno terminala
nextpdf --base-url http://localhost:8080 --api-key "$NEXTPDF_API_KEY" extract text document.pdf

Wyodrębnij tabele jako wartości rozdzielone przecinkami (CSV):

Okno terminala
nextpdf --base-url http://localhost:8080 --api-key "$NEXTPDF_API_KEY" extract tables invoice.pdf --format csv

Sprawdź metadane i strukturę dokumentu:

Okno terminala
nextpdf --base-url http://localhost:8080 --api-key "$NEXTPDF_API_KEY" info document.pdf

Pobierz pełne semantyczne drzewo AST:

Okno terminala
nextpdf --base-url http://localhost:8080 --api-key "$NEXTPDF_API_KEY" ast document.pdf

Wyświetl wersję zainstalowanego zestawu narzędzi programistycznych (SDK) bez łączenia się z serwerem:

Okno terminala
nextpdf version

Polecenie version jest jedynym poleceniem, które nie wymaga ani --base-url, ani --api-key. Każde inne polecenie łączy się z serwerem i wymaga obu wartości.

Każdy przykład odczytuje klucz interfejsu programowania aplikacji (API) ze zmiennej środowiskowej NEXTPDF_API_KEY, zamiast umieszczać go w wierszu poleceń. Traktuj klucz jak dane poufne. Klucz podany dosłownie w wierszu poleceń jest widoczny w historii powłoki oraz na liście procesów (ps) dla innych użytkowników hosta.

Umieść je przed podpoleceniem. Każda opcja połączenia może też odczytać wartość ze zmiennej środowiskowej, więc gdy zmienna jest ustawiona, możesz pominąć flagę.

OpcjaZmienna środowiskowaWartość domyślnaPrzeznaczenie
--base-urlNEXTPDF_BASE_URL(wymagane)Adres URL (uniform resource locator) serwera NextPDF Connect.
--api-keyNEXTPDF_API_KEY(wymagane)Klucz API do uwierzytelniania typu bearer.
--log-levelwarningSzczegółowość rejestrowania: debug, info, warning lub error. Komunikaty dziennika trafiają na standardowe wyjście błędów (stderr).
--output, -ostdoutZapisuje dane wyjściowe polecenia do pliku zamiast na stdout.
--strictwyłączoneZarezerwowane do przyszłego użytku. Flaga jest dziś przetwarzana, ale nie zmienia zachowania.
--help, -hWyświetla pomoc i kończy działanie.

Wartości --base-url i --api-key są wymagane dla każdego polecenia z wyjątkiem version. Jeśli brakuje którejś z nich — nie ma ani flagi, ani zmiennej środowiskowej — polecenie wyświetla błąd i kończy działanie z kodem stanu 1.

Wyodrębnia cytowane bloki tekstu. Każdy blok zawiera kotwicę cytowania z identyfikatorem węzła, indeksem strony, prostokątem ograniczającym oraz oceną ufności.

nextpdf [GROUP OPTIONS] extract text PDF_PATH [--format FORMAT] [--page N] [--headings-only]
OpcjaWartościWartość domyślnaPrzeznaczenie
--formatjson, markdown, plainjsonFormat danych wyjściowych.
--pageliczba całkowitawszystkie stronyWyodrębnia tylko stronę o podanym indeksie liczonym od 0.
--headings-onlyflagawyłączoneWyodrębnia tylko węzły nagłówków.

PDF_PATH to ścieżka do pliku lub -, aby odczytać bajty PDF ze standardowego wejścia (stdin).

Wyodrębnia każdą tabelę wraz z kotwicami cytowania i strukturą na poziomie komórek.

nextpdf [GROUP OPTIONS] extract tables PDF_PATH [--format FORMAT] [--page-start N] [--page-end N]
OpcjaWartościWartość domyślnaPrzeznaczenie
--formatjson, csvjsonFormat danych wyjściowych.
--page-startliczba całkowitapierwsza stronaIndeks strony początkowej (liczony od 0).
--page-endliczba całkowitaostatnia stronaIndeks strony końcowej (liczony od 0).

PDF_PATH to ścieżka do pliku lub -, aby odczytać ze stdin.

Zwraca pełne semantyczne AST w formacie JSON: hierarchiczne drzewo węzłów, w tym nagłówki, akapity, tabele, listy i ilustracje, wraz z prostokątami ograniczającymi oraz treścią tekstową.

nextpdf [GROUP OPTIONS] ast PDF_PATH [--page-start N] [--page-end N] [--token-budget N]
OpcjaWartościWartość domyślnaPrzeznaczenie
--page-startliczba całkowitapierwsza stronaIndeks strony początkowej (liczony od 0).
--page-endliczba całkowitaostatnia stronaIndeks strony końcowej (liczony od 0).
--token-budgetliczba całkowitabez ograniczeńPrzybliżony limit tokenów dla zwracanego drzewa AST.

PDF_PATH to ścieżka do pliku lub -, aby odczytać ze stdin. Polecenie ast tworzy jedno drzewo dokumentu; nie porównuje dwóch plików PDF. Informacje o porównywaniu strukturalnym znajdziesz w sekcji Przepis: porównanie dwóch wersji pliku PDF.

Wyświetla zwięzłe podsumowanie jednego dokumentu w formacie JSON: wersję schematu, skrót źródła, liczbę stron, szacowaną liczbę tokenów, typ węzła głównego oraz liczbę elementów podrzędnych węzła głównego.

nextpdf [GROUP OPTIONS] info PDF_PATH

PDF_PATH to ścieżka do pliku lub -, aby odczytać ze stdin.

Wyświetla wersję zainstalowanego SDK, na przykład nextpdf 1.1.0, i kończy działanie. To polecenie nie łączy się z żadnym serwerem i nie wymaga poświadczeń.

nextpdf version

Ustaw opcje połączenia raz jako zmienne środowiskowe i pomiń powtarzające się flagi. Ta forma całkowicie eliminuje też problem kolejności opcji, ponieważ poświadczenia nigdy nie pojawiają się w wierszu poleceń.

Okno terminala
export NEXTPDF_BASE_URL=http://localhost:8080
export NEXTPDF_API_KEY=your-key
nextpdf extract text document.pdf

W Windows PowerShell:

Okno terminala
$env:NEXTPDF_BASE_URL = "http://localhost:8080"
$env:NEXTPDF_API_KEY = "your-key"
nextpdf extract text document.pdf

Najlepiej wczytuj klucz z magazynu sekretów lub z pliku .env trzymanego poza systemem kontroli wersji. Nie wklejaj klucza produkcyjnego do współdzielonej sesji terminala ani do skryptu, który zatwierdzasz w repozytorium.

Wybierz format danych wyjściowych dla danego polecenia za pomocą --format. Polecenia do obsługi tekstu i tabel obsługują więcej niż jeden format; ast oraz info zawsze generują dane w formacie JSON.

PolecenieFormatyWartość domyślna
extract textjson, markdown, plainjson
extract tablesjson, csvjson
astjsonjson
infojsonjson

Wybierz JSON, gdy program docelowy potrzebuje indeksów stron, ocen ufności lub identyfikatorów węzłów. Wybierz CSV, gdy tabele przetwarza arkusz kalkulacyjny lub potok tabelaryczny. Wybierz plain lub markdown, gdy wynik będzie czytać człowiek albo narzędzie obsługujące wyłącznie tekst.

Polecenie do obsługi tekstu generuje tablicę JSON cytowanych bloków. Każdy blok ma text, obiekt citation (node_id, page_index, bbox, confidence) oraz opcjonalny node_type. Wyślij dane wyjściowe do pliku za pomocą --output lub przekieruj stdout, a następnie przetwórz je.

Ten przykład powłoki używa jq, aby zachować tylko nagłówki na stronie 0:

Okno terminala
nextpdf --output blocks.json extract text report.pdf --format json
jq '[.[] | select(.citation.page_index == 0 and .node_type == "heading") | .text]' blocks.json

Te same dane można bez problemu przetwarzać w Pythonie. Interfejs wiersza poleceń (CLI) zapisuje tablicę JSON, więc wczytaj ją za pomocą biblioteki standardowej i odczytaj typowane pola:

"""Parse cited text blocks emitted by `nextpdf extract text --format json`."""
import json
from 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)

Gdy potrzebujesz zweryfikowanych, typowanych modeli zamiast surowych słowników, wywołaj SDK bezpośrednio, zamiast przetwarzać dane wyjściowe CLI. Zobacz Przegląd biblioteki dla Pythona, aby poznać klienta NextPDF i zwracany przez niego typ CitedTextBlock.

Po użyciu opcji --format csv polecenie do obsługi tabel zapisuje jeden blok CSV dla każdej tabeli. Wiersz komentarza # Table N (pM) poprzedza każdą tabelę i podaje jej numer liczony od 1 oraz indeks strony liczony od 0. Pusta linia oddziela kolejne tabele. CLI za pomocą modułu csv Pythona ujmuje wartości komórek w cudzysłowy i stosuje znaki ucieczki, więc wartości zawierające przecinki, cudzysłowy lub znaki nowej linii bezpiecznie zachowują integralność.

Okno terminala
nextpdf --output tables.csv extract tables statement.pdf --format csv

Ponieważ plik zawiera wiele bloków CSV, podziel go według wierszy komentarza, zanim przetworzysz każdy blok jako samodzielną tabelę:

"""Split multi-table CSV output from `nextpdf extract tables --format csv`."""
import csv
import io
from 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")

CLI używa trzech kodów wyjścia. Sprawdź $? w skryptach powłoki lub $LASTEXITCODE w PowerShell, aby sterować logiką zależnie od powodzenia lub niepowodzenia. Odczytuj komunikaty diagnostyczne ze stderr; pozostają oddzielone od danych na stdout.

Kod wyjściaZnaczeniePrzykłady
0Powodzenie.Polecenie zakończyło się; version zostało wyświetlone.
1Błąd w czasie wykonywania. CLI wyświetla Error: <message> na stderr.Plik wejściowy nie został znaleziony lub nie jest zwykłym plikiem, puste stdin, brakujące lub nieprawidłowe --base-url/--api-key, każdy błąd po stronie serwera (wymagana licencja, przekroczony limit, nieotagowany plik PDF, przekroczony czas budowania lub inna awaria interfejsu API).
2Błąd użycia, zgłoszony przez Click.Nieznane polecenie lub opcja (w tym opcja grupy umieszczona po podpoleceniu), brak wymaganego argumentu, takiego jak PDF_PATH.

Każda awaria po stronie serwera zwraca kod wyjścia 1 z czytelnym komunikatem na stderr. SDK zgłasza typowany wyjątek — NextPDFLicenseError (Hypertext Transfer Protocol (HTTP) 402), QuotaExceededError (HTTP 429), AstNoStructTreeError (HTTP 422, nieotagowany plik PDF), AstBuildTimeoutError (HTTP 504) lub bazowy NextPDFAPIError. CLI przechwytuje je wszystkie przez ich wspólną klasę bazową NextPDFError, wyświetla komunikat i kończy działanie z kodem 1. CLI nie udostępnia odrębnych kodów wyjścia dla poszczególnych typów awarii. Aby na przykład odróżnić w skrypcie błąd limitu od błędu licencji, sprawdź treść komunikatu na stderr lub wywołaj SDK bezpośrednio (zobacz Przegląd biblioteki dla Pythona, aby poznać klasy wyjątków).

Użyj tego wzorca w skrypcie, aby oddzielić dane od informacji diagnostycznych:

#!/usr/bin/env bash
set -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}"
fi

Po użyciu opcji --output CLI zapisuje dane do wskazanego pliku i wyświetla tylko wiersz potwierdzenia Written to <path> na stderr, więc stdout pozostaje pusty. Bez opcji --output dane trafiają na stdout i możesz je przekierować.

Każdy poniższy przepis korzysta wyłącznie ze zweryfikowanych poleceń i flag. W każdym przypadku poświadczenia pochodzą ze środowiska.

Dla folderu z fakturami utwórz po jednym pliku CSV na dokument na potrzeby arkusza kalkulacyjnego lub potoku księgowego:

#!/usr/bin/env bash
set -euo pipefail
: "${NEXTPDF_BASE_URL:?set NEXTPDF_BASE_URL}"
: "${NEXTPDF_API_KEY:?set NEXTPDF_API_KEY}"
mkdir -p out
for pdf in invoices/*.pdf; do
name="$(basename "${pdf}" .pdf)"
nextpdf --output "out/${name}.csv" extract tables "${pdf}" --format csv
done

Każdy plik out/<name>.csv zawiera jeden blok CSV dla każdej wykrytej tabeli, z nagłówkiem # Table N (pM) przed każdym blokiem. Przetwórz bloki za pomocą czytnika CSV pokazanego powyżej.

Połącz --headings-only z formatem markdown, aby utworzyć szybki konspekt do przeczytania lub wklejenia do notatek:

Okno terminala
nextpdf --output outline.md extract text whitepaper.pdf --headings-only --format markdown

Polecenie CLI ast zwraca drzewo jednego dokumentu; nie ma podpolecenia porównywania. Porównywanie strukturalne jest dostępne w SDK jako client.ast.get_ast_diff(...) oraz w serwerze Model Context Protocol (MCP) jako narzędzie nextpdf_diff. Uruchom porównanie za pośrednictwem SDK:

"""Compare two PDF revisions structurally with the NextPDF SDK.
The API key is read from the environment, never hard-coded.
"""
import os
from 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"))

Aby uruchomić to samo porównanie z poziomu agenta sztucznej inteligencji (AI), zamiast ze skryptu, zarejestruj serwer MCP i wywołaj narzędzie nextpdf_diff. Zobacz stronę Serwer MCP dla Pythona.

Przepis: przesłanie pliku PDF strumieniem z innego narzędzia

Dział zatytułowany „Przepis: przesłanie pliku PDF strumieniem z innego narzędzia”

Odczytaj bajty PDF ze stdin za pomocą -, aby połączyć nextpdf z narzędziem, które emituje plik PDF do własnego stdout:

Okno terminala
curl --silent https://example.com/report.pdf | nextpdf info -

Argument - nakazuje poleceniu odczytanie dokumentu ze stdin. Jeśli nie zostaną przekazane żadne bajty, polecenie zgłasza błąd i kończy działanie z kodem 1.

CLI buduje każdą odpowiedź w pamięci i zapisuje ją jednorazowo. Przekierowywanie lub potokowe przesyłanie danych wyjściowych jest proste, ale dane nie są wytwarzane przyrostowo. Duże drzewo AST albo zestaw tabel są w pełni buforowane, zanim pierwszy bajt trafi na stdout lub do pliku --output. Planując pamięć i opóźnienia, zakładaj odpowiedzi obejmujące cały dokument, a nie strumień.

Każde wywołanie nextpdf tworzy nowego klienta i połączenie HTTP, więc pętla po wielu plikach otwiera i zamyka połączenie dla każdego pliku. Koszt połączenia jest zwykle niewielki w porównaniu z czasem wyodrębniania po stronie serwera, ale przy dużej skali staje się realnym obciążeniem.

  • Korzystaj z jednego punktu końcowego. Kieruj każde wywołanie na to samo wdrożenie NextPDF Connect, aby serwer mógł ponownie wykorzystać rozgrzane pamięci podręczne i pule połączeń. Unikaj rozdzielania wsadu między punkty końcowe, chyba że celowo równoważysz obciążenie.
  • Ogranicz zakres pracy w jednym wywołaniu. Użyj --page, --page-start/--page-end lub --token-budget, aby przetwarzać tylko potrzebne strony. Mniejsze zakresy stron skracają zarówno czas serwera, jak i rozmiar odpowiedzi; --token-budget ogranicza drzewo AST, które agent musi odczytać.
  • Przetwarzaj wsadowo w jednym procesie przy dużych zadaniach. W przypadku wsadów o dużej liczbie elementów wybieraj SDK dla Pythona zamiast powtarzanych wywołań CLI. Pojedynczy, długo działający klient NextPDF lub AsyncNextPDF ponownie wykorzystuje jedno połączenie HTTP z puli dla każdego dokumentu, co eliminuje uruchamianie procesu i nawiązywanie połączenia, których koszt pętla CLI ponosi za każdym razem. Strona Przegląd biblioteki dla Pythona pokazuje cykl życia klienta, a AsyncNextPDF obsługuje równoległe wyodrębnianie z wielu plików PDF.
  • Trzymaj rejestrowanie z dala od ścieżki danych. Pozostaw --log-level przy wartości domyślnej dla zadań wsadowych. Komunikaty diagnostyczne trafiają na stderr i nie uszkadzają danych na stdout, ale zmiana poziomu na debug dodaje szum i niewielkie obciążenie.