Interfejs wiersza poleceń (CLI) w Pythonie
Interfejs wiersza poleceń (CLI) w Pythonie
Dział zatytułowany „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.
Struktura polecenia
Dział zatytułowany „Struktura polecenia”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.
Krótki przewodnik
Dział zatytułowany „Krótki przewodnik”Wyodrębnij tekst w formacie JavaScript Object Notation (JSON):
nextpdf --base-url http://localhost:8080 --api-key "$NEXTPDF_API_KEY" extract text document.pdfWyodrębnij tabele jako wartości rozdzielone przecinkami (CSV):
nextpdf --base-url http://localhost:8080 --api-key "$NEXTPDF_API_KEY" extract tables invoice.pdf --format csvSprawdź metadane i strukturę dokumentu:
nextpdf --base-url http://localhost:8080 --api-key "$NEXTPDF_API_KEY" info document.pdfPobierz pełne semantyczne drzewo AST:
nextpdf --base-url http://localhost:8080 --api-key "$NEXTPDF_API_KEY" ast document.pdfWyświetl wersję zainstalowanego zestawu narzędzi programistycznych (SDK) bez łączenia się z serwerem:
nextpdf versionPolecenie 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.
Polecenia i opcje
Dział zatytułowany „Polecenia i opcje”Opcje grupy
Dział zatytułowany „Opcje grupy”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ę.
| Opcja | Zmienna środowiskowa | Wartość domyślna | Przeznaczenie |
|---|---|---|---|
--base-url | NEXTPDF_BASE_URL | (wymagane) | Adres URL (uniform resource locator) serwera NextPDF Connect. |
--api-key | NEXTPDF_API_KEY | (wymagane) | Klucz API do uwierzytelniania typu bearer. |
--log-level | — | warning | Szczegółowość rejestrowania: debug, info, warning lub error. Komunikaty dziennika trafiają na standardowe wyjście błędów (stderr). |
--output, -o | — | stdout | Zapisuje dane wyjściowe polecenia do pliku zamiast na stdout. |
--strict | — | wyłączone | Zarezerwowane do przyszłego użytku. Flaga jest dziś przetwarzana, ale nie zmienia zachowania. |
--help, -h | — | — | Wyś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.
nextpdf extract text
Dział zatytułowany „nextpdf extract text”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]| Opcja | Wartości | Wartość domyślna | Przeznaczenie |
|---|---|---|---|
--format | json, markdown, plain | json | Format danych wyjściowych. |
--page | liczba całkowita | wszystkie strony | Wyodrębnia tylko stronę o podanym indeksie liczonym od 0. |
--headings-only | flaga | wyłączone | Wyodrę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).
nextpdf extract tables
Dział zatytułowany „nextpdf extract tables”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]| Opcja | Wartości | Wartość domyślna | Przeznaczenie |
|---|---|---|---|
--format | json, csv | json | Format danych wyjściowych. |
--page-start | liczba całkowita | pierwsza strona | Indeks strony początkowej (liczony od 0). |
--page-end | liczba całkowita | ostatnia strona | Indeks strony końcowej (liczony od 0). |
PDF_PATH to ścieżka do pliku lub -, aby odczytać ze stdin.
nextpdf ast
Dział zatytułowany „nextpdf ast”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]| Opcja | Wartości | Wartość domyślna | Przeznaczenie |
|---|---|---|---|
--page-start | liczba całkowita | pierwsza strona | Indeks strony początkowej (liczony od 0). |
--page-end | liczba całkowita | ostatnia strona | Indeks strony końcowej (liczony od 0). |
--token-budget | liczba całkowita | bez 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.
nextpdf info
Dział zatytułowany „nextpdf info”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_PATHPDF_PATH to ścieżka do pliku lub -, aby odczytać ze stdin.
nextpdf version
Dział zatytułowany „nextpdf version”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 versionKonfiguracja raz na powłokę
Dział zatytułowany „Konfiguracja raz na powłokę”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ń.
export NEXTPDF_BASE_URL=http://localhost:8080export NEXTPDF_API_KEY=your-keynextpdf extract text document.pdfW Windows PowerShell:
$env:NEXTPDF_BASE_URL = "http://localhost:8080"$env:NEXTPDF_API_KEY = "your-key"nextpdf extract text document.pdfNajlepiej 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.
Formaty danych wyjściowych
Dział zatytułowany „Formaty danych wyjściowych”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.
| Polecenie | Formaty | Wartość domyślna |
|---|---|---|
extract text | json, markdown, plain | json |
extract tables | json, csv | json |
ast | json | json |
info | json | json |
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.
Przetwarzanie danych wyjściowych JSON
Dział zatytułowany „Przetwarzanie danych wyjściowych JSON”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:
nextpdf --output blocks.json extract text report.pdf --format jsonjq '[.[] | select(.citation.page_index == 0 and .node_type == "heading") | .text]' blocks.jsonTe 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 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)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.
Przetwarzanie danych wyjściowych CSV
Dział zatytułowany „Przetwarzanie danych wyjściowych CSV”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ść.
nextpdf --output tables.csv extract tables statement.pdf --format csvPonieważ 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 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")Kody wyjścia i wykrywanie błędów
Dział zatytułowany „Kody wyjścia i wykrywanie błędów”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ścia | Znaczenie | Przykłady |
|---|---|---|
0 | Powodzenie. | Polecenie zakończyło się; version zostało wyświetlone. |
1 | Błą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). |
2 | Błą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 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}"fiPo 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ć.
Przepisy
Dział zatytułowany „Przepisy”Każdy poniższy przepis korzysta wyłącznie ze zweryfikowanych poleceń i flag. W każdym przypadku poświadczenia pochodzą ze środowiska.
Przepis: wyodrębnienie tabel z faktur do CSV
Dział zatytułowany „Przepis: wyodrębnienie tabel z faktur do CSV”Dla folderu z fakturami utwórz po jednym pliku CSV na dokument na potrzeby arkusza kalkulacyjnego lub potoku księgowego:
#!/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 csvdoneKaż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.
Przepis: zbudowanie konspektu dokumentu
Dział zatytułowany „Przepis: zbudowanie konspektu dokumentu”Połącz --headings-only z formatem markdown, aby utworzyć szybki konspekt do przeczytania lub wklejenia do notatek:
nextpdf --output outline.md extract text whitepaper.pdf --headings-only --format markdownPrzepis: porównanie dwóch wersji pliku PDF
Dział zatytułowany „Przepis: porównanie dwóch wersji pliku PDF”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 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"))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:
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.
Uwagi dotyczące wydajności
Dział zatytułowany „Uwagi dotyczące wydajności”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-endlub--token-budget, aby przetwarzać tylko potrzebne strony. Mniejsze zakresy stron skracają zarówno czas serwera, jak i rozmiar odpowiedzi;--token-budgetogranicza 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
NextPDFlubAsyncNextPDFponownie 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, aAsyncNextPDFobsługuje równoległe wyodrębnianie z wielu plików PDF. - Trzymaj rejestrowanie z dala od ścieżki danych. Pozostaw
--log-levelprzy wartości domyślnej dla zadań wsadowych. Komunikaty diagnostyczne trafiają na stderr i nie uszkadzają danych na stdout, ale zmiana poziomu nadebugdodaje szum i niewielkie obciążenie.