Bỏ qua để đến nội dung

Hướng dẫn SDK Python dành cho nhà phát triển

Bộ công cụ phát triển phần mềm (SDK) Python của NextPDF là một client mỏng, được định kiểu rõ ràng cho một endpoint NextPDF Connect. Ứng dụng của bạn chịu trách nhiệm xác thực đầu vào Định dạng tài liệu di động (PDF), xử lý thông tin xác thực và chính sách đồng thời. SDK đảm nhiệm việc dựng yêu cầu, truyền tải và định kiểu phản hồi. Hãy giữ ranh giới đó thật rõ: đọc PDF một cách an toàn, chọn một client, gọi phương thức ast cần dùng, rồi xử lý lỗi cụ thể.

Hãy dùng hướng dẫn này khi bạn xây dựng dịch vụ trích xuất, tác vụ gộp lô asyncio, công cụ tác nhân trí tuệ nhân tạo (AI) hoặc quy trình dòng lệnh xoay quanh SDK. Hướng dẫn giả định rằng bạn đã đọc phần tổng quanbắt đầu nhanh, có Python 3.10 trở lên và có một endpoint NextPDF Connect.

TầngThuộc vềTrách nhiệmKhông đặt ở đây
Nguồn đầu vàoỨng dụngCấp quyền cho bên gọi, xác thực nguồn PDF và chọn chính sách trích xuất.Bộ định vị tài nguyên thống nhất (URL) của endpoint hoặc chuỗi thông tin xác thực ghi thẳng vào mã.
Dựng clientỨng dụngĐọc base_urlapi_key từ môi trường hoặc một trình quản lý bí mật.Bí mật ghi cứng trong mã.
NextPDF / AsyncNextPDFSDKDựng yêu cầu, gọi Connect và trả về các mô hình Pydantic có kiểu.Logic nghiệp vụ hoặc chính sách lưu trữ.
ast — không gian tên phương thứcSDKÁnh xạ lời gọi phương thức tới một endpoint Connect và phân tích phản hồi.Chính sách thử lại hoặc chờ giãn ngoài phạm vi bạn cấu hình.
Endpoint NextPDF ConnectTriển khaiChạy trích xuất và thực thi xác thực, hạn mức và cấp phép.Cấp quyền ở ứng dụng.

SDK không bao giờ thực hiện nhận dạng ký tự quang học (OCR). Nếu một PDF là bản quét hoặc chỉ chứa hình ảnh, hãy chạy OCR trước khi trích xuất. Hãy xem bước đó là trách nhiệm của ứng dụng, nằm ngoài ranh giới này.

Giai đoạnHành viHành động của nhà phát triển
Dựng clientbase_urlapi_key được xác thực; bất kỳ giá trị trống nào cũng làm phát sinh ValueError.Đọc cả hai từ môi trường; không bao giờ ghi thẳng vào mã.
Tạo backendMột backend từ xa mở một kết nối gộp tới Connect.Tái sử dụng một client cho nhiều lời gọi thay vì dựng client cho từng yêu cầu.
Gọi phương thứcPhương thức ast tuần tự hóa yêu cầu, gửi các byte PDF và phân tích phản hồi thành một mô hình Pydantic.Truyền vào các bytes đã được xác thực.
Ánh xạ lỗiSDK ánh xạ trạng thái Giao thức truyền siêu văn bản (HTTP) không thành công sang một lớp con ngoại lệ cụ thể.Bắt lớp cụ thể nhất trước.
TắtAsyncNextPDF.close() giải phóng pool kết nối; trình quản lý ngữ cảnh bất đồng bộ sẽ gọi phương thức này thay cho bạn.Dùng async with hoặc gọi close() trong một khối finally.
Đường dẫnMục đích
app/pdf/clients.pyDựng và lưu đệm một NextPDF hoặc AsyncNextPDF đã cấu hình.
app/pdf/extraction.pyLớp bọc của ứng dụng cho các lời gọi phương thức ast.
app/pdf/validation.pyXác thực nguồn PDF, giới hạn kích thước và kiểm tra nội dung.
tests/pdf/Kiểm thử trích xuất, chế độ lỗi và gộp lô bất đồng bộ.

Hãy giữ việc xác thực PDF tách biệt với việc trích xuất. Chỉ truyền các byte đã được cấp quyền và đã kiểm tra kích thước vào tầng trích xuất, đồng thời vẫn dựa vào endpoint để phòng thủ theo chiều sâu.

import os
from nextpdf import NextPDF
def build_client() -> NextPDF:
"""Construct a synchronous client from environment configuration.
Raises:
KeyError: When a required environment variable is missing.
"""
base_url = os.environ["NEXTPDF_BASE_URL"]
api_key = os.environ["NEXTPDF_API_KEY"]
return NextPDF(base_url=base_url, api_key=api_key)

Dùng client NextPDF đồng bộ cho script, tác vụ gộp lô và notebook. Xác thực đầu vào trước khi gọi SDK và xử lý các lỗi cụ thể mà lời gọi có thể phát sinh.

from pathlib import Path
from nextpdf import (
NextPDF,
CitedTextBlock,
NextPDFAPIError,
NextPDFError,
QuotaExceededError,
)
MAX_PDF_BYTES = 100 * 1024 * 1024 # Reject documents above 100 MiB for the in-memory path.
def read_pdf(path: Path) -> bytes:
"""Read and validate a PDF from disk.
Raises:
ValueError: When the file is missing, empty, oversized, or not a PDF.
"""
if not path.is_file():
raise ValueError(f"Not a file: {path}")
data = path.read_bytes()
if not data:
raise ValueError("PDF is empty")
if len(data) > MAX_PDF_BYTES:
raise ValueError("PDF exceeds the configured size limit; use the CLI streaming path")
if not data.startswith(b"%PDF-"):
raise ValueError("File does not look like a PDF")
return data
def extract_text(client: NextPDF, path: Path) -> list[CitedTextBlock]:
"""Extract cited text blocks, handling the most specific failures first."""
pdf_bytes = read_pdf(path)
try:
return client.ast.extract_cited_text(pdf_bytes)
except QuotaExceededError as error:
raise RuntimeError(f"Quota exceeded; retry after {error.retry_after}s") from error
except NextPDFAPIError as error:
raise RuntimeError(f"API error {error.status_code}: {error}") from error
except NextPDFError as error:
raise RuntimeError(f"SDK error: {error}") from error

Một mục kết quả có dạng như sau:

block = blocks[0]
print(block.text) # the extracted text
print(block.citation.page_index) # 0-based page index
print(block.citation.confidence) # 0.0 - 1.0

Dùng client AsyncNextPDF bất đồng bộ trong các môi trường chạy asyncio như FastAPI. Dựng một client dưới dạng trình quản lý ngữ cảnh bất đồng bộ và chia sẻ client đó giữa các lời gọi đồng thời; không mở một client cho mỗi tài liệu. Giới hạn mức đồng thời bằng một semaphore để tuân thủ hạn mức của endpoint.

import asyncio
import os
from nextpdf import (
AsyncNextPDF,
ExtractCitedTablesResponse,
NextPDFError,
QuotaExceededError,
)
async def extract_tables_batch(
pdfs: list[bytes],
*,
max_concurrency: int = 4,
) -> list[ExtractCitedTablesResponse | None]:
"""Extract tables from many PDFs concurrently with one shared client.
Returns one response per input PDF, or None where extraction failed.
"""
base_url = os.environ["NEXTPDF_BASE_URL"]
api_key = os.environ["NEXTPDF_API_KEY"]
semaphore = asyncio.Semaphore(max_concurrency)
async with AsyncNextPDF(base_url=base_url, api_key=api_key) as client:
async def one(pdf_bytes: bytes) -> ExtractCitedTablesResponse | None:
async with semaphore:
try:
return await client.ast.extract_cited_tables(pdf_bytes)
except QuotaExceededError as error:
# Surface the backpressure signal; do not silently drop it.
raise RuntimeError(f"Quota exceeded; retry after {error.retry_after}s") from error
except NextPDFError:
return None
return await asyncio.gather(*(one(pdf) for pdf in pdfs))

Không bao giờ viết một khối except rỗng. Hãy xử lý lỗi, chuyển lỗi thành một kết quả đã định nghĩa, hoặc phát sinh lại lỗi đó.

Điểm mở rộngDùng choRàng buộc
AsyncNextPDF(backend=...)Tiêm một backend tùy chỉnh hoặc cục bộ trong khi kiểm thử.Backend phải thỏa mãn giao thức PdfBackend.
api_version — đối sốGhim một phiên bản giao diện lập trình ứng dụng (API) của Connect.Mặc định là v1; chỉ thay đổi khi endpoint hỗ trợ phiên bản đích.
Cấu hình môi trườngCung cấp NEXTPDF_BASE_URLNEXTPDF_API_KEY cho giao diện dòng lệnh (CLI) và máy chủ Model Context Protocol (MCP).Hãy xem khóa này là một bí mật chỉ giới hạn cho workload.
Máy chủ MCP (python -m nextpdf.mcp)Cung cấp các công cụ trích xuất cho những tác nhân có khả năng MCP.Yêu cầu gói thêm nextpdf[mcp] và một endpoint được kiểm soát.
  1. Cài đặt SDK bằng pip install nextpdf, hoặc dùng pip install nextpdf[mcp] cho máy chủ tác nhân.
  2. Đọc NEXTPDF_BASE_URLNEXTPDF_API_KEY từ môi trường để không bí mật nào lọt vào hệ thống quản lý mã nguồn.
  3. Xác thực mọi nguồn PDF về sự tồn tại, kích thước và các byte nhận dạng %PDF- trước khi gọi SDK.
  4. Dựng một client cho mỗi tiến trình và dùng lại nó; với asyncio, hãy giữ nó mở bằng async with.
  5. Gọi phương thức ast hẹp nhất cho tác vụ: extract_cited_text() cho văn xuôi, extract_cited_tables() cho bảng, get_document_ast() chỉ khi bạn cần toàn bộ cây.
  6. Bắt ngoại lệ cụ thể nhất mà bạn có thể xử lý, rồi quay về NextPDFError.
  7. Với các tài liệu trên 100 MiB, hãy dùng đường truyền phát qua CLI thay vì hiện thực hóa mọi block trong bộ nhớ.
  8. Chạy mypy ở chế độ strict và thêm một bài kiểm thử chế độ lỗi cho mỗi ngoại lệ bạn xử lý.
LỗiNgoại lệPhản hồi được khuyến nghị
PDF chưa gắn thẻ, heuristic tắtAstNoStructTreeError (HTTP 422)Bật chế độ heuristic trên endpoint hoặc cung cấp PDF đã gắn thẻ.
Hết thời gian dựng phía máy chủAstBuildTimeoutError (HTTP 504)Giảm phạm vi trang rồi thử lại.
Yêu cầu bậc giấy phépNextPDFLicenseError (HTTP 402)Nâng cấp giấy phép máy chủ hoặc quay về một tính năng được phép.
Giới hạn tốc độ hoặc hạn mứcQuotaExceededError (HTTP 429)Chờ retry_after giây, rồi thử lại với cơ chế chờ giãn.
Lỗi HTTP khácNextPDFAPIErrorKiểm tra status_codeerror_code; ghi nhật ký và hiển thị lỗi đã định nghĩa.
Bất kỳ lỗi SDK nàoNextPDFErrorPhương án dự phòng cuối cùng; không bao giờ để nó thoát ra dưới dạng một ngoại lệ chưa được xử lý.

Endpoint báo lỗi theo ngữ nghĩa trạng thái HTTP của Đề nghị lấy ý kiến (RFC) 9110 và dùng thân lỗi mà máy đọc được theo RFC 9457. Mỗi ngoại lệ giữ lại status_code gốc. Hãy ánh xạ các lỗi đó sang phản hồi lỗi của riêng bạn thay vì để lộ chi tiết truyền tải cho bên gọi.

Vấn đềMặc địnhKhi nào nên ghi đè
Phiên bản APIv1.Chỉ thay đổi khi endpoint hỗ trợ một phiên bản mới hơn.
Xác minh Bảo mật tầng giao vận (TLS)Được bật; không hiển thị công tắc kém an toàn nào.Không bao giờ tắt với lưu lượng môi trường sản xuất.
Thông tin xác thựcĐọc từ môi trường; không bao giờ ghi thẳng vào mã.Dùng một trình quản lý bí mật trong môi trường sản xuất.
Giới hạn kích thước trong bộ nhớTừ chối các PDF trên 100 MiB ở đường truyền của client.Hạ thấp đối với dịch vụ đa khách thuê; dùng CLI cho tệp lớn hơn.
Mức đồng thờiBị giới hạn bởi một semaphore trong các lô bất đồng bộ.Điều chỉnh theo hạn mức của endpoint, không theo số lõi của máy chủ.
Ghi nhật kýGhi nhật ký tên tệp, kích thước, trạng thái và thời lượng.Không bao giờ ghi nhật ký các byte PDF hoặc khóa API.
  • Kiểm thử dựng client khẳng định rằng một base_url hoặc api_key rỗng sẽ làm phát sinh ValueError.
  • Kiểm thử xác thực bao quát các đầu vào thiếu, rỗng, quá lớn và không phải PDF.
  • Kiểm thử trích xuất khẳng định các kiểu mô hình được trả về và một CitationAnchor trên mỗi block.
  • Kiểm thử chế độ lỗi bao quát AstNoStructTreeError, AstBuildTimeoutError, NextPDFLicenseError, QuotaExceededErrorNextPDFAPIError.
  • Kiểm thử bất đồng bộ khẳng định rằng client chạy như một trình quản lý ngữ cảnh async with và rằng mức đồng thời nằm trong giới hạn của semaphore.
  • Kiểm thử vòng đời khẳng định rằng close() giải phóng kênh truyền tải và có tính lũy đẳng.
  • Tiêm một backend giả bằng AsyncNextPDF(backend=...) để các bài kiểm thử chạy mà không cần endpoint thực.