Перейти к содержимому

Руководство для разработчика Python SDK

Python Software Development Kit (SDK) NextPDF — это тонкий типизированный клиент для конечной точки NextPDF Connect. Ваше приложение отвечает за проверку входных данных в формате Portable Document Format (PDF), работу с учётными данными и политику параллелизма. SDK отвечает за построение запроса, транспорт и типизацию ответа. Держите эту границу явной: безопасно считайте PDF, выберите клиент, вызовите нужный метод ast и обработайте конкретный сбой.

Используйте это руководство, когда создаёте сервисы извлечения, пакетные задания на asyncio, инструменты для агентов искусственного интеллекта (AI) или рабочие процессы командной строки вокруг SDK. Предполагается, что вы прочитали обзор и быстрый старт, а также что у вас есть Python 3.10 или новее и конечная точка NextPDF Connect.

УровеньЗа кем закрепленоОтветственностьНе размещайте здесь
Источник входных данныхПриложениеАвторизует вызывающую сторону, проверяет источник PDF и выбирает политику извлечения.Литералы Uniform Resource Locator (URL) конечной точки или учётных данных.
Создание клиентаПриложениеЧитает base_url и api_key из окружения или менеджера секретов.Жёстко прописанные секреты.
NextPDF / AsyncNextPDFSDKСтроит запрос, вызывает Connect и возвращает типизированные модели Pydantic.Доменная логика или политика хранения.
ast пространство имён методовSDKСопоставляет вызов метода с конечной точкой Connect и разбирает ответ.Политика повторов или отсрочки сверх той, что вы настраиваете.
Конечная точка NextPDF ConnectРазвёртываниеВыполняет извлечение и обеспечивает аутентификацию, квоты и лицензирование.Авторизация приложения.

SDK никогда не выполняет оптическое распознавание символов (OCR). Если PDF отсканирован или содержит только изображения, выполните OCR перед извлечением. Считайте этот шаг задачей приложения за пределами этой границы.

ЭтапПоведениеДействие разработчика
Создание клиентаbase_url и api_key проверяются; любое пустое значение вызывает ValueError.Читайте оба значения из окружения; никогда не задавайте их в коде.
Создание бэкендаУдалённый бэкенд открывает соединение с Connect из пула.Переиспользуйте один клиент для разных вызовов, а не создавайте его на каждый запрос.
Вызов методаМетод ast сериализует запрос, отправляет байты PDF и разбирает ответ в модель Pydantic.Передавайте уже проверенные bytes.
Сопоставление ошибокSDK сопоставляет ошибочный статус Hypertext Transfer Protocol (HTTP) с конкретным подклассом исключения.Сначала перехватывайте наиболее конкретный класс.
Завершение работыAsyncNextPDF.close() освобождает пул соединений; асинхронный контекстный менеджер вызывает его за вас.Используйте async with или вызывайте close() в блоке finally.
ПутьНазначение
app/pdf/clients.pyСоздаёт и кэширует настроенный NextPDF или AsyncNextPDF.
app/pdf/extraction.pyОбёртка приложения вокруг вызовов метода ast.
app/pdf/validation.pyПроверка источника PDF, ограничения размера и проверки содержимого.
tests/pdf/Тесты извлечения, режимов сбоя и асинхронной пакетной обработки.

Держите проверку 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 для скриптов, пакетных заданий и блокнотов. Проверяйте входные данные перед вызовом 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. Создавайте один клиент через асинхронный контекстный менеджер и переиспользуйте его для параллельных вызовов; не открывайте клиент на каждый документ. Ограничивайте параллелизм семафором, чтобы не выйти за квоту конечной точки.

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 аргументФиксация версии application programming interface (API) Connect.По умолчанию v1; меняйте только когда конечная точка поддерживает целевую версию.
Конфигурация окруженияПередача NEXTPDF_BASE_URL и NEXTPDF_API_KEY в интерфейс командной строки (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 на существование, размер и сигнатурные байты %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 в строгом режиме и добавляйте тест сценария сбоя для каждого обрабатываемого исключения.
СбойИсключениеРекомендуемая реакция
PDF без тегов, эвристика отключенаAstNoStructTreeError (HTTP 422)Включите эвристический режим на конечной точке или предоставьте PDF с тегами.
Тайм-аут построения на стороне сервераAstBuildTimeoutError (HTTP 504)Уменьшите диапазон страниц и повторите.
Требуется уровень лицензииNextPDFLicenseError (HTTP 402)Обновите лицензию сервера или используйте разрешённую функцию.
Лимит частоты или квотаQuotaExceededError (HTTP 429)Подождите retry_after секунд, затем повторите с экспоненциальной отсрочкой.
Другая ошибка HTTPNextPDFAPIErrorИзучите status_code и error_code; запишите в журнал и верните определённую ошибку.
Любая ошибка SDKNextPDFErrorПоследний запасной вариант; никогда не оставляйте его необработанным.

Конечная точка сообщает о сбоях по семантике статусов HTTP, согласованной с Request for Comments (RFC) 9110, и возвращает машиночитаемые тела ошибок, согласованные с RFC 9457. Каждое исключение сохраняет исходный status_code. Преобразуйте эти сбои в собственные ответы об ошибках, а не раскрывайте вызывающим сторонам детали транспорта.

АспектПо умолчаниюКогда переопределять
Версия APIv1.Меняйте только когда конечная точка поддерживает более новую версию.
Проверка Transport Layer Security (TLS)Включена; небезопасный переключатель не предоставляется.Никогда не отключайте для продакшен-трафика.
Учётные данныеЧитаются из окружения; никогда не задаются в коде.Используйте менеджер секретов в продакшене.
Ограничение размера в памятиОтклоняются PDF больше 100 MiB на клиентском пути.Уменьшите для многопользовательских сервисов; для файлов большего размера используйте CLI.
ПараллелизмОграничивается семафором в асинхронной пакетной обработке.Настраивайте под квоту конечной точки, а не под число ядер хоста.
ЖурналированиеЗаписывайте в журнал имя файла, размер, статус и длительность.Никогда не записывайте в журнал байты PDF или ключ API.
  • Тесты создания клиента проверяют, что пустой base_url или api_key вызывает ValueError.
  • Тесты проверки покрывают отсутствующие, пустые, превышающие лимит размера и не-PDF входные данные.
  • Тесты извлечения проверяют типы возвращаемых моделей и наличие CitationAnchor в каждом блоке.
  • Тесты режимов сбоя покрывают AstNoStructTreeError, AstBuildTimeoutError, NextPDFLicenseError, QuotaExceededError и NextPDFAPIError.
  • Асинхронные тесты проверяют, что клиент работает как контекстный менеджер async with и что параллелизм остаётся в пределах лимита семафора.
  • Тесты жизненного цикла проверяют, что close() освобождает транспорт и является идемпотентным.
  • Внедрите фиктивный бэкенд через AsyncNextPDF(backend=...), чтобы тесты выполнялись без рабочей конечной точки.