ข้ามไปยังเนื้อหา

คู่มือนักพัฒนา Python SDK

NextPDF Python Software Development Kit (SDK) เป็นไคลเอนต์แบบบางที่มีการกำหนดชนิดข้อมูลอย่างชัดเจนสำหรับปลายทาง NextPDF Connect แอปพลิเคชันของคุณรับผิดชอบการตรวจสอบความถูกต้องของอินพุต Portable Document Format (PDF) การจัดการข้อมูลรับรอง และนโยบายการทำงานพร้อมกัน ส่วน SDK รับผิดชอบการสร้างคำขอ การขนส่ง และการกำหนดชนิดข้อมูลของการตอบกลับ รักษาขอบเขตนี้ให้ชัดเจน: อ่าน PDF อย่างปลอดภัย เลือกไคลเอนต์ เรียกเมท็อด ast ที่ต้องการ และจัดการความล้มเหลวเฉพาะกรณี

ใช้คู่มือนี้เมื่อคุณสร้างบริการสกัดข้อมูล งาน batch แบบ asyncio เครื่องมือสำหรับเอเจนต์ปัญญาประดิษฐ์ (AI) หรือเวิร์กโฟลว์บรรทัดคำสั่งรอบ SDK คู่มือนี้ถือว่าคุณได้อ่าน ภาพรวม และ เริ่มต้นฉบับย่อ แล้ว และมี Python 3.10 หรือใหม่กว่าพร้อมปลายทาง NextPDF Connect

เลเยอร์รับผิดชอบโดยหน้าที่รับผิดชอบอย่าใส่ไว้ที่นี่
แหล่งอินพุตแอปพลิเคชันอนุญาตสิทธิ์ผู้เรียก ตรวจสอบความถูกต้องของแหล่ง PDF และเลือกนโยบายการสกัดข้อมูลค่าคงที่ Uniform Resource Locator (URL) ของปลายทางหรือข้อมูลรับรอง
การสร้างไคลเอนต์แอปพลิเคชันอ่าน base_url และ api_key จากสภาพแวดล้อมหรือตัวจัดการความลับความลับที่ฮาร์ดโค้ด
NextPDF / AsyncNextPDFSDKสร้างคำขอ เรียก Connect และส่งคืนโมเดล Pydantic ที่กำหนดชนิดข้อมูลแล้วตรรกะเชิงโดเมนหรือนโยบายการจัดเก็บ
ast เนมสเปซเมท็อดSDKแมปการเรียกเมท็อดไปยังปลายทาง Connect และแยกวิเคราะห์การตอบกลับนโยบายลองใหม่หรือ backoff ที่เกินกว่าค่าที่คุณกำหนดไว้
NextPDF Connect endpointการปรับใช้รันการสกัดข้อมูลและบังคับใช้การยืนยันตัวตน โควตา และสิทธิ์การใช้งานการอนุญาตสิทธิ์ของแอปพลิเคชัน

SDK ไม่ทำการรู้จำอักขระด้วยแสง (OCR) หาก PDF เป็นไฟล์สแกนหรือมีเฉพาะรูปภาพ ให้รัน OCR ก่อนการสกัดข้อมูล และถือว่าขั้นตอนนั้นเป็นความรับผิดชอบของแอปพลิเคชันซึ่งอยู่นอกขอบเขตนี้

ขั้นพฤติกรรมการดำเนินการของนักพัฒนา
การสร้างไคลเอนต์base_url และ api_key จะถูกตรวจสอบความถูกต้อง หากค่าใดค่าหนึ่งว่างเปล่าจะทำให้เกิด ValueErrorอ่านทั้งสองค่าจากสภาพแวดล้อม อย่าเขียนค่าเหล่านั้นไว้ในโค้ดโดยตรง
การสร้างแบ็กเอนด์แบ็กเอนด์ระยะไกลจะเปิด connection pool ไปยัง Connectใช้ไคลเอนต์ตัวเดียวซ้ำในการเรียกทั้งหมด แทนการสร้างใหม่ต่อคำขอ
การเรียกเมท็อดเมท็อด ast จะ serialize คำขอ ส่งไบต์ PDF และแยกวิเคราะห์การตอบกลับเป็นโมเดล Pydanticส่ง bytes ที่ผ่านการตรวจสอบความถูกต้องแล้ว
การแมปข้อผิดพลาดSDK จะแมปสถานะ Hypertext Transfer Protocol (HTTP) ที่ไม่สำเร็จไปยังคลาสย่อยของข้อยกเว้นเฉพาะกรณีจับคลาสที่เฉพาะเจาะจงที่สุดก่อน
การปิดระบบAsyncNextPDF.close() จะปล่อย connection pool ตัวจัดการบริบทแบบ async จะเรียกใช้ให้คุณใช้ async with หรือเรียก close() ในบล็อก finally
เส้นทางวัตถุประสงค์
app/pdf/clients.pyสร้างและแคช NextPDF หรือ AsyncNextPDF ที่กำหนดค่าแล้ว
app/pdf/extraction.pyตัวห่อหุ้มระดับแอปพลิเคชันรอบการเรียกเมท็อด ast ต่าง ๆ
app/pdf/validation.pyการตรวจสอบความถูกต้องของแหล่ง PDF การจำกัดขนาด และการตรวจสอบเนื้อหา
tests/pdf/การทดสอบการสกัดข้อมูล โหมดความล้มเหลว และการประมวลผล batch แบบ async

แยกการตรวจสอบความถูกต้องของ PDF ออกจากการสกัดข้อมูล ส่งเฉพาะไบต์ที่ได้รับอนุญาตและผ่านการตรวจสอบขนาดแล้วเข้าสู่เลเยอร์การสกัดข้อมูล และยังต้องพึ่งพาปลายทางเพื่อเสริมการป้องกันเชิงลึก

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)

ใช้ไคลเอนต์ NextPDF แบบซิงโครนัสสำหรับสคริปต์ งาน batch และโน้ตบุ๊ก ตรวจสอบความถูกต้องของอินพุตก่อนเรียก SDK และจัดการเฉพาะความล้มเหลวที่การเรียกนั้นอาจทำให้เกิดขึ้น

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

รายการผลลัพธ์หนึ่งรายการมีรูปแบบดังนี้:

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

ใช้ไคลเอนต์ AsyncNextPDF แบบอะซิงโครนัสภายในรันไทม์แบบ asyncio เช่น FastAPI สร้างไคลเอนต์ตัวเดียวเป็นตัวจัดการบริบทแบบ async แล้วใช้ร่วมกันในการเรียกพร้อมกันหลายรายการ อย่าเปิดไคลเอนต์ใหม่สำหรับแต่ละเอกสาร จำกัดการทำงานพร้อมกันด้วย semaphore เพื่อให้เป็นไปตามโควตาของปลายทาง

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))

อย่าเขียน except ที่ว่างเปล่าเด็ดขาด ให้จัดการความล้มเหลว แปลงเป็นผลลัพธ์ที่กำหนดไว้ หรือโยนซ้ำ

จุดขยายใช้สำหรับข้อจำกัด
AsyncNextPDF(backend=...)แทรกแบ็กเอนด์แบบกำหนดเองหรือแบบโลคัลในการทดสอบแบ็กเอนด์ต้องเป็นไปตามโปรโตคอล PdfBackend
api_version อาร์กิวเมนต์ปักหมุดเวอร์ชันของ Connect application programming interface (API)ค่าเริ่มต้นเป็น v1 เปลี่ยนเฉพาะเมื่อปลายทางรองรับเวอร์ชันเป้าหมายเท่านั้น
การกำหนดค่าสภาพแวดล้อมจัดเตรียม NEXTPDF_BASE_URL และ NEXTPDF_API_KEY ให้กับ command-line interface (CLI) และเซิร์ฟเวอร์ Model Context Protocol (MCP)ปฏิบัติต่อคีย์นั้นเสมือนเป็นความลับที่จำกัดขอบเขตไว้เฉพาะเวิร์กโหลด
เซิร์ฟเวอร์ MCP (python -m nextpdf.mcp)เปิดเผยเครื่องมือสกัดข้อมูลให้แก่เอเจนต์ที่รองรับ MCPต้องใช้ส่วนเสริม nextpdf[mcp] และปลายทางที่ควบคุมได้
  1. ติดตั้ง SDK ด้วย pip install nextpdf หรือใช้ pip install nextpdf[mcp] สำหรับเซิร์ฟเวอร์เอเจนต์
  2. อ่าน NEXTPDF_BASE_URL และ NEXTPDF_API_KEY จากสภาพแวดล้อม เพื่อไม่ให้ความลับเข้าสู่ระบบควบคุมซอร์ส
  3. ตรวจสอบความถูกต้องของแหล่ง PDF ทุกแหล่งในเรื่องการมีอยู่ ขนาด และ magic bytes %PDF- ก่อนเรียก SDK
  4. สร้างไคลเอนต์หนึ่งตัวต่อหนึ่งโพรเซสและนำมาใช้ซ้ำ สำหรับ asyncio ให้คงเปิดไว้ด้วย async with
  5. เรียกเมท็อด ast ที่แคบที่สุดสำหรับงานนั้น: extract_cited_text() สำหรับร้อยแก้ว extract_cited_tables() สำหรับตาราง get_document_ast() เฉพาะเมื่อคุณต้องการโครงสร้างทรีทั้งหมดเท่านั้น
  6. จับข้อยกเว้นที่เฉพาะเจาะจงที่สุดที่คุณสามารถจัดการได้ แล้วจึงถอยกลับไปยัง NextPDFError
  7. สำหรับเอกสารที่เกิน 100 MiB ให้ใช้เส้นทางการสตรีมแบบ CLI แทนการสร้างทุกบล็อกขึ้นในหน่วยความจำ
  8. รัน mypy ในโหมด strict และเพิ่มการทดสอบโหมดความล้มเหลวสำหรับแต่ละข้อยกเว้นที่คุณจัดการ
ความล้มเหลวข้อยกเว้นการตอบสนองที่แนะนำ
PDF ที่ไม่มีแท็กเมื่อปิดฮิวริสติกAstNoStructTreeError (HTTP 422)เปิดโหมดฮิวริสติกบนปลายทางหรือจัดเตรียม PDF ที่มีแท็ก
การหมดเวลาการสร้างฝั่งเซิร์ฟเวอร์AstBuildTimeoutError (HTTP 504)ลดช่วงหน้าแล้วลองใหม่
ต้องมีระดับสิทธิ์การใช้งานNextPDFLicenseError (HTTP 402)อัปเกรดสิทธิ์การใช้งานของเซิร์ฟเวอร์หรือถอยกลับไปใช้คุณลักษณะที่ได้รับอนุญาต
การจำกัดอัตราหรือโควตาQuotaExceededError (HTTP 429)รอ retry_after วินาที แล้วลองใหม่พร้อม backoff
ข้อผิดพลาด HTTP อื่น ๆNextPDFAPIErrorตรวจสอบ status_code และ error_code บันทึกล็อกและแสดงข้อผิดพลาดที่กำหนดไว้
ข้อผิดพลาด SDK ใด ๆNextPDFErrorการถอยกลับขั้นสุดท้าย อย่าปล่อยให้หลุดออกไปเป็นข้อยกเว้นที่ไม่ถูกจัดการเด็ดขาด

ปลายทางจะรายงานความล้มเหลวด้วยความหมายของสถานะ HTTP ที่สอดคล้องกับ Request for Comments (RFC) 9110 และเนื้อความข้อผิดพลาดที่เครื่องอ่านได้ซึ่งสอดคล้องกับ RFC 9457 ข้อยกเว้นแต่ละรายการจะเก็บรักษา status_code ต้นทางไว้ แมปความล้มเหลวเหล่านั้นไปยังการตอบกลับข้อผิดพลาดของคุณเอง แทนที่จะปล่อยให้รายละเอียดการขนส่งรั่วไหลไปยังผู้เรียก

ประเด็นค่าเริ่มต้นเมื่อใดควรแทนที่
เวอร์ชัน APIv1เปลี่ยนเฉพาะเมื่อปลายทางรองรับเวอร์ชันที่ใหม่กว่าเท่านั้น
การยืนยัน Transport Layer Security (TLS)เปิดใช้งาน ไม่มีการเปิดสวิตช์ที่ไม่ปลอดภัยให้ใช้อย่าปิดใช้งานสำหรับการรับส่งข้อมูลในระบบจริงเด็ดขาด
ข้อมูลรับรองอ่านจากสภาพแวดล้อม ไม่เคยเขียนในโค้ดโดยตรงใช้ตัวจัดการความลับในระบบจริง
การจำกัดขนาดในหน่วยความจำปฏิเสธ PDF ที่เกิน 100 MiB บนเส้นทางฝั่งไคลเอนต์ลดลงสำหรับบริการแบบหลายผู้เช่า ใช้ CLI สำหรับไฟล์ขนาดใหญ่กว่า
การทำงานพร้อมกันจำกัดด้วย semaphore ในการประมวลผล batch แบบ asyncปรับให้เข้ากับโควตาของปลายทาง ไม่ใช่จำนวนคอร์ของโฮสต์
การบันทึกล็อกบันทึกล็อกชื่อไฟล์ ขนาด สถานะ และระยะเวลาอย่าบันทึกล็อกไบต์ PDF หรือ API key เด็ดขาด
  • การทดสอบการสร้างยืนยันว่า base_url หรือ api_key ที่ว่างเปล่าจะทำให้เกิด ValueError
  • การทดสอบการตรวจสอบความถูกต้องครอบคลุมอินพุตที่ขาดหายไป ว่างเปล่า เกินขนาด และที่ไม่ใช่ PDF
  • การทดสอบการสกัดข้อมูลยืนยันชนิดของโมเดลที่ส่งคืนและ CitationAnchor บนแต่ละบล็อก
  • การทดสอบโหมดความล้มเหลวครอบคลุม AstNoStructTreeError, AstBuildTimeoutError, NextPDFLicenseError, QuotaExceededError และ NextPDFAPIError
  • การทดสอบ async ยืนยันว่าไคลเอนต์ทำงานเป็นตัวจัดการบริบทแบบ async with และว่าการทำงานพร้อมกันอยู่ภายในขอบเขตของ semaphore
  • การทดสอบวงจรชีวิตยืนยันว่า close() ปล่อยการขนส่งและเป็น idempotent
  • แทรกแบ็กเอนด์จำลองด้วย AsyncNextPDF(backend=...) เพื่อให้การทดสอบรันได้โดยไม่ต้องมีปลายทางที่ใช้งานจริง