Python CLI
Python CLI
Phần tiêu đề “Python CLI”Sử dụng lệnh nextpdf để trích xuất nội dung từ các tệp Portable Document Format (PDF) ngay trong terminal. Trỏ lệnh đến một endpoint NextPDF Connect, truyền vào một tệp PDF, rồi nhận kết quả có cấu trúc — văn bản có trích dẫn, bảng, toàn bộ cây cú pháp trừu tượng (Abstract Syntax Tree, AST) ngữ nghĩa, hoặc bản tóm tắt metadata — trên đầu ra chuẩn (stdout) hoặc trong một tệp.
Cấu trúc lệnh
Phần tiêu đề “Cấu trúc lệnh”Lệnh nextpdf là một nhóm lệnh Click. Các tùy chọn kết nối và phiên — --base-url, --api-key, --log-level, --output/-o, và --strict — thuộc về nhóm, nên hãy đặt chúng trước lệnh con. Đặt lệnh con và các tùy chọn của lệnh con, chẳng hạn --format hoặc --page, ở phía sau:
nextpdf [GROUP OPTIONS] COMMAND [SUBCOMMAND] PDF_PATH [COMMAND OPTIONS]Nếu bạn đặt một tùy chọn nhóm sau lệnh con, lệnh sẽ thất bại. Ví dụ, nextpdf info document.pdf --base-url ... sẽ báo Error: No such option: --base-url và thoát với trạng thái 2, vì Click đã phân tích lệnh con info khi gặp --base-url, còn info không định nghĩa tùy chọn đó.
Để tránh lỗi về thứ tự, hãy cung cấp thông tin xác thực qua các biến môi trường (xem Cấu hình một lần cho mỗi shell). Các ví dụ bên dưới dùng cờ tường minh trước để thứ tự đúng thật rõ ràng.
Tham khảo nhanh
Phần tiêu đề “Tham khảo nhanh”Trích xuất văn bản dưới dạng JavaScript Object Notation (JSON):
nextpdf --base-url http://localhost:8080 --api-key "$NEXTPDF_API_KEY" extract text document.pdfTrích xuất bảng dưới dạng giá trị phân tách bằng dấu phẩy (CSV):
nextpdf --base-url http://localhost:8080 --api-key "$NEXTPDF_API_KEY" extract tables invoice.pdf --format csvKiểm tra metadata và cấu trúc của tài liệu:
nextpdf --base-url http://localhost:8080 --api-key "$NEXTPDF_API_KEY" info document.pdfLấy toàn bộ AST ngữ nghĩa:
nextpdf --base-url http://localhost:8080 --api-key "$NEXTPDF_API_KEY" ast document.pdfIn phiên bản bộ công cụ phát triển phần mềm (SDK) đã cài đặt mà không cần liên hệ với máy chủ:
nextpdf versionLệnh version là lệnh duy nhất không cần --base-url hoặc --api-key. Mọi lệnh khác đều liên hệ với máy chủ và yêu cầu cả hai.
Mỗi ví dụ đọc khóa giao diện lập trình ứng dụng (API) từ biến môi trường NEXTPDF_API_KEY thay vì nhúng trực tiếp vào dòng lệnh. Hãy coi khóa này là bí mật. Khóa ở dạng nguyên văn trên dòng lệnh sẽ xuất hiện trong lịch sử shell và trong danh sách tiến trình (ps) với những người dùng khác trên máy chủ.
Lệnh và tùy chọn
Phần tiêu đề “Lệnh và tùy chọn”Tùy chọn nhóm
Phần tiêu đề “Tùy chọn nhóm”Đặt các tùy chọn này trước lệnh con. Mỗi tùy chọn kết nối cũng đọc từ một biến môi trường, nên có thể bỏ qua cờ khi biến đã được thiết lập.
| Tùy chọn | Biến môi trường | Mặc định | Mục đích |
|---|---|---|---|
--base-url | NEXTPDF_BASE_URL | (bắt buộc) | Định vị tài nguyên thống nhất (URL) của máy chủ NextPDF Connect. |
--api-key | NEXTPDF_API_KEY | (bắt buộc) | Khóa API để xác thực bearer. |
--log-level | — | warning | Mức độ chi tiết của nhật ký: debug, info, warning, hoặc error. Nhật ký được ghi ra lỗi chuẩn (stderr). |
--output, -o | — | stdout | Ghi đầu ra của lệnh vào một tệp thay vì stdout. |
--strict | — | tắt | Dành cho việc dùng trong tương lai. Hiện tại cờ này được phân tích nhưng không thay đổi hành vi. |
--help, -h | — | — | Hiển thị trợ giúp và thoát. |
Các giá trị --base-url và --api-key là bắt buộc với mọi lệnh trừ version. Nếu thiếu một trong hai giá trị — không có cờ và không có biến môi trường — lệnh sẽ in lỗi và thoát với trạng thái 1.
nextpdf extract text
Phần tiêu đề “nextpdf extract text”Trích xuất các khối văn bản có trích dẫn. Mỗi khối bao gồm một mỏ neo trích dẫn cùng mã định danh nút, chỉ số trang, hộp bao và điểm tin cậy.
nextpdf [GROUP OPTIONS] extract text PDF_PATH [--format FORMAT] [--page N] [--headings-only]| Tùy chọn | Giá trị | Mặc định | Mục đích |
|---|---|---|---|
--format | json, markdown, plain | json | Định dạng đầu ra. |
--page | số nguyên | tất cả trang | Chỉ trích xuất chỉ số trang dựa trên 0 này. |
--headings-only | cờ | tắt | Chỉ trích xuất các nút tiêu đề. |
PDF_PATH là một đường dẫn tệp, hoặc - để đọc byte PDF từ đầu vào chuẩn (stdin).
nextpdf extract tables
Phần tiêu đề “nextpdf extract tables”Trích xuất mọi bảng cùng các mỏ neo trích dẫn và cấu trúc ở cấp ô.
nextpdf [GROUP OPTIONS] extract tables PDF_PATH [--format FORMAT] [--page-start N] [--page-end N]| Tùy chọn | Giá trị | Mặc định | Mục đích |
|---|---|---|---|
--format | json, csv | json | Định dạng đầu ra. |
--page-start | số nguyên | trang đầu | Chỉ số trang bắt đầu (dựa trên 0). |
--page-end | số nguyên | trang cuối | Chỉ số trang kết thúc (dựa trên 0). |
PDF_PATH là một đường dẫn tệp, hoặc - để đọc từ stdin.
nextpdf ast
Phần tiêu đề “nextpdf ast”Trả về toàn bộ AST ngữ nghĩa dưới dạng JSON: một cây nút phân cấp, bao gồm tiêu đề, đoạn văn, bảng, danh sách và hình minh họa, kèm theo hộp bao và nội dung văn bản.
nextpdf [GROUP OPTIONS] ast PDF_PATH [--page-start N] [--page-end N] [--token-budget N]| Tùy chọn | Giá trị | Mặc định | Mục đích |
|---|---|---|---|
--page-start | số nguyên | trang đầu | Chỉ số trang bắt đầu (dựa trên 0). |
--page-end | số nguyên | trang cuối | Chỉ số trang kết thúc (dựa trên 0). |
--token-budget | số nguyên | không giới hạn | Giới hạn token gần đúng cho AST trả về. |
PDF_PATH là một đường dẫn tệp, hoặc - để đọc từ stdin. Lệnh ast tạo ra một cây tài liệu; lệnh này không so sánh hai tệp PDF. Để so sánh khác biệt về cấu trúc, xem Công thức: so sánh hai bản sửa đổi PDF.
nextpdf info
Phần tiêu đề “nextpdf info”In một bản tóm tắt JSON gọn về tài liệu: phiên bản schema, source hash, số trang, số token ước tính, kiểu nút gốc và số nút con của gốc.
nextpdf [GROUP OPTIONS] info PDF_PATHPDF_PATH là một đường dẫn tệp, hoặc - để đọc từ stdin.
nextpdf version
Phần tiêu đề “nextpdf version”In phiên bản SDK đã cài đặt, chẳng hạn nextpdf 1.1.0, rồi thoát. Lệnh này không liên hệ với máy chủ và không cần thông tin xác thực.
nextpdf versionCấu hình một lần cho mỗi shell
Phần tiêu đề “Cấu hình một lần cho mỗi shell”Thiết lập các tùy chọn kết nối một lần dưới dạng biến môi trường, rồi bỏ qua các cờ lặp lại. Cách này cũng tránh hoàn toàn lỗi thứ tự tùy chọn, vì thông tin xác thực không bao giờ xuất hiện trên dòng lệnh.
export NEXTPDF_BASE_URL=http://localhost:8080export NEXTPDF_API_KEY=your-keynextpdf extract text document.pdfTrên Windows PowerShell:
$env:NEXTPDF_BASE_URL = "http://localhost:8080"$env:NEXTPDF_API_KEY = "your-key"nextpdf extract text document.pdfBạn nên nạp khóa từ một kho bí mật hoặc một tệp .env được giữ ngoài hệ thống quản lý phiên bản. Không dán khóa môi trường sản xuất vào phiên terminal dùng chung hoặc vào script mà bạn commit.
Định dạng đầu ra
Phần tiêu đề “Định dạng đầu ra”Chọn định dạng đầu ra cho từng lệnh bằng --format. Các lệnh text và table hỗ trợ nhiều định dạng; ast và info luôn xuất JSON.
| Lệnh | Định dạng | Mặc định |
|---|---|---|
extract text | json, markdown, plain | json |
extract tables | json, csv | json |
ast | json | json |
info | json | json |
Chọn JSON khi chương trình phía sau cần chỉ số trang, điểm tin cậy hoặc mã định danh nút. Chọn CSV khi bảng tính hoặc quy trình dạng bảng cần dùng các bảng. Chọn văn bản plain hoặc markdown khi người dùng hoặc công cụ chỉ xử lý văn bản đọc kết quả.
Phân tích đầu ra JSON
Phần tiêu đề “Phân tích đầu ra JSON”Lệnh text xuất ra một mảng JSON gồm các khối có trích dẫn. Mỗi khối có text, một đối tượng citation (node_id, page_index, bbox, confidence) và một node_type tùy chọn. Gửi đầu ra vào một tệp bằng --output, hoặc chuyển hướng stdout, rồi phân tích dữ liệu đó.
Ví dụ shell này dùng jq để chỉ giữ lại các tiêu đề trên trang 0:
nextpdf --output blocks.json extract text report.pdf --format jsonjq '[.[] | select(.citation.page_index == 0 and .node_type == "heading") | .text]' blocks.jsonDữ liệu tương tự cũng có thể được phân tích gọn gàng trong Python. Giao diện dòng lệnh (CLI) ghi ra một mảng JSON, nên hãy nạp dữ liệu bằng thư viện chuẩn và đọc các trường có kiểu:
"""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)Khi cần các mô hình đã được kiểm tra và có kiểu thay vì từ điển thô, hãy gọi trực tiếp SDK thay vì phân tích đầu ra CLI. Xem Tổng quan Python để biết về client NextPDF và kiểu trả về CitedTextBlock của nó.
Phân tích đầu ra CSV
Phần tiêu đề “Phân tích đầu ra CSV”Với --format csv, lệnh table ghi một khối CSV cho mỗi bảng. Một hàng chú thích, # Table N (pM), đứng trước mỗi bảng và nêu số thứ tự bảng dựa trên 1 cùng chỉ số trang dựa trên 0 của bảng đó. Một dòng trống ngăn cách các bảng liên tiếp. CLI trích dẫn và thoát ký tự cho các giá trị ô bằng module csv của Python, nên các giá trị chứa dấu phẩy, dấu ngoặc kép hoặc ký tự xuống dòng vẫn được bảo toàn an toàn qua mỗi lượt.
nextpdf --output tables.csv extract tables statement.pdf --format csvVì tệp chứa nhiều khối CSV, hãy tách theo các hàng chú thích trước khi phân tích từng khối như một bảng độc lập:
"""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")Mã thoát và phát hiện lỗi
Phần tiêu đề “Mã thoát và phát hiện lỗi”CLI dùng ba mã thoát. Kiểm tra $? trong các script shell, hoặc $LASTEXITCODE trong PowerShell, để rẽ nhánh theo thành công hoặc thất bại. Đọc thông báo chẩn đoán từ stderr, vốn tách biệt với dữ liệu trên stdout.
| Mã thoát | Ý nghĩa | Ví dụ |
|---|---|---|
0 | Thành công. | Một lệnh đã hoàn tất; version đã in ra. |
1 | Lỗi thời gian chạy. CLI in Error: <message> ra stderr. | Không tìm thấy tệp đầu vào hoặc tệp đầu vào không phải tệp thông thường, stdin rỗng, thiếu hoặc không hợp lệ --base-url/--api-key, bất kỳ lỗi phía máy chủ nào (yêu cầu giấy phép, vượt hạn mức, PDF chưa được gắn thẻ, hết thời gian dựng hoặc lỗi API khác). |
2 | Lỗi sử dụng, do Click báo cáo. | Lệnh hoặc tùy chọn không xác định (bao gồm một tùy chọn nhóm đặt sau lệnh con), thiếu một đối số bắt buộc chẳng hạn PDF_PATH. |
Mọi lỗi phía máy chủ đều trả về mã thoát 1 cùng một thông báo dễ đọc trên stderr. SDK ném ra một ngoại lệ có kiểu — NextPDFLicenseError (Hypertext Transfer Protocol (HTTP) 402), QuotaExceededError (HTTP 429), AstNoStructTreeError (HTTP 422, PDF chưa được gắn thẻ), AstBuildTimeoutError (HTTP 504), hoặc NextPDFAPIError cơ sở. CLI bắt tất cả dưới lớp cơ sở chung NextPDFError, in thông báo và thoát 1. CLI không bộc lộ mã thoát riêng cho từng loại lỗi. Để phân biệt, chẳng hạn, lỗi hạn mức với lỗi giấy phép trong script, hãy kiểm tra nội dung thông báo trên stderr hoặc gọi trực tiếp SDK (xem Tổng quan Python để biết các lớp ngoại lệ).
Dùng mẫu script này để tách dữ liệu khỏi thông tin chẩn đoán:
#!/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}"fiVới --output, CLI ghi dữ liệu vào tệp được đặt tên và chỉ in dòng xác nhận Written to <path> ra stderr, nên stdout vẫn rỗng. Khi không có --output, dữ liệu đi ra stdout và bạn có thể chuyển hướng dữ liệu đó.
Công thức
Phần tiêu đề “Công thức”Mọi công thức bên dưới chỉ dùng các lệnh và cờ đã được kiểm chứng. Trong từng trường hợp, thông tin xác thực đều đến từ môi trường.
Công thức: trích xuất bảng hóa đơn ra CSV
Phần tiêu đề “Công thức: trích xuất bảng hóa đơn ra CSV”Biến một thư mục hóa đơn thành một tệp CSV cho mỗi tài liệu để phục vụ bảng tính hoặc quy trình kế toán:
#!/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 csvdoneMỗi out/<name>.csv chứa một khối CSV cho mỗi bảng được phát hiện, với tiêu đề # Table N (pM) đứng trước mỗi khối. Phân tích các khối bằng bộ đọc CSV được trình bày ở trên.
Công thức: dựng một mục lục tài liệu
Phần tiêu đề “Công thức: dựng một mục lục tài liệu”Kết hợp --headings-only với định dạng markdown để tạo nhanh mục lục mà bạn có thể đọc hoặc dán vào ghi chú:
nextpdf --output outline.md extract text whitepaper.pdf --headings-only --format markdownCông thức: so sánh hai bản sửa đổi PDF
Phần tiêu đề “Công thức: so sánh hai bản sửa đổi PDF”Lệnh ast của CLI trả về cây cho một tài liệu; lệnh này không có lệnh con so sánh. Tính năng so sánh khác biệt về cấu trúc nằm trong SDK ở dạng client.ast.get_ast_diff(...) và trong máy chủ Model Context Protocol (MCP) ở dạng công cụ nextpdf_diff. Chạy phép so sánh thông qua 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"))Để chạy cùng phép so sánh đó từ một tác nhân trí tuệ nhân tạo (AI) thay vì từ script, hãy đăng ký máy chủ MCP và gọi công cụ nextpdf_diff. Xem trang Máy chủ Python MCP.
Công thức: truyền vào một tệp PDF từ một công cụ khác
Phần tiêu đề “Công thức: truyền vào một tệp PDF từ một công cụ khác”Đọc byte PDF từ stdin với - để nối nextpdf sau một công cụ phát ra tệp PDF trên stdout của chính công cụ đó:
curl --silent https://example.com/report.pdf | nextpdf info -Đối số - báo cho lệnh đọc tài liệu từ stdin. Nếu không nhận được byte nào, lệnh sẽ báo lỗi và thoát 1.
Ghi chú về hiệu năng
Phần tiêu đề “Ghi chú về hiệu năng”CLI dựng mỗi phản hồi trong bộ nhớ và ghi một lần. Việc chuyển hướng hoặc đưa đầu ra qua pipe rất đơn giản, nhưng đầu ra không được tạo theo từng phần. Một AST hoặc tập bảng lớn được đệm đầy đủ trước khi byte đầu tiên đến stdout hoặc tệp --output. Hãy dự trù bộ nhớ và độ trễ cho các phản hồi trên toàn bộ tài liệu, không phải cho một luồng.
Mỗi lần gọi nextpdf tạo một client và kết nối HTTP mới, nên vòng lặp qua nhiều tệp sẽ mở và đóng một kết nối cho mỗi tệp. Chi phí kết nối thường nhỏ so với thời gian trích xuất phía máy chủ, nhưng sẽ trở thành phụ phí đáng kể ở quy mô lớn.
- Tái sử dụng một endpoint. Trỏ mọi lần gọi đến cùng một triển khai NextPDF Connect để máy chủ có thể tái sử dụng các bộ nhớ đệm đã được làm nóng và các nhóm kết nối. Tránh phân tán một lô qua nhiều endpoint trừ khi bạn chủ động cân bằng tải.
- Giới hạn khối lượng công việc cho mỗi lần gọi. Dùng
--page,--page-start/--page-end, hoặc--token-budgetđể chỉ xử lý các trang cần thiết. Phạm vi trang nhỏ hơn giúp giảm cả thời gian máy chủ lẫn kích thước phản hồi;--token-budgetgiới hạn AST mà tác nhân của bạn phải đọc. - Gộp lô trong một tiến trình cho các tác vụ lớn. Với các lô khối lượng lớn, hãy ưu tiên Python SDK thay vì gọi CLI lặp đi lặp lại. Một client
NextPDFhoặcAsyncNextPDFtồn tại lâu dài duy nhất sẽ tái sử dụng kết nối HTTP đã gộp sẵn cho mọi tài liệu, nhờ đó loại bỏ phần khởi động cho mỗi tiến trình và chi phí thiết lập kết nối mà vòng lặp CLI phải trả mỗi lần. Tổng quan Python trình bày vòng đời của client, vàAsyncNextPDFhỗ trợ trích xuất đồng thời trên nhiều tệp PDF. - Giữ nhật ký ngoài đường dữ liệu. Để
--log-levelở mức mặc định cho các lần chạy theo lô. Nhật ký chẩn đoán đi ra stderr và không làm hỏng dữ liệu stdout, nhưng nâng mức lêndebugsẽ thêm nhiễu và một ít phụ phí.