دليل المطوّر لـ Python SDK
لمحة سريعة
قسم بعنوان «لمحة سريعة»مجموعة أدوات تطوير البرامج (SDK) الخاصة بـ NextPDF لـ Python هي عميل خفيف ومُحدَّد الأنواع لنقطة نهاية NextPDF Connect. يتولّى تطبيقك التحقّق من صحّة مدخلات صيغة المستندات المحمولة (PDF)، ومعالجة بيانات الاعتماد، وسياسة التزامن. وتتولّى الـ SDK بناء الطلب، والنقل، وتحديد أنواع الاستجابة. حافِظ على وضوح هذا الفاصل: اقرأ ملف PDF بأمان، واختر عميلاً، واستدعِ طريقة ast التي تحتاجها، وعالِج العطل المحدّد.
استخدِم هذا الدليل عند بناء خدمات الاستخراج، أو مهام الدفعات باستخدام asyncio، أو أدوات وكلاء الذكاء الاصطناعي (AI)، أو سير عمل سطر الأوامر حول الـ SDK. يفترض الدليل أنّك قرأت النظرة العامة والبدء السريع، وأنّ لديك Python 3.10 أو أحدث ونقطة نهاية NextPDF Connect.
حدّ البنية
قسم بعنوان «حدّ البنية»| الطبقة | يملكها | المسؤولية | ما لا يُوضع هنا |
|---|---|---|---|
| مصدر الإدخال | التطبيق | خوِّل المُستدعي بالصلاحية، وتحقّق من صحّة مصدر ملف PDF، واختر سياسة الاستخراج. | محدِّد موقع المورد المُوحّد (URL) لنقطة النهاية أو قيم بيانات الاعتماد النصّية. |
| إنشاء العميل | التطبيق | اقرأ base_url وapi_key من بيئة التشغيل أو من مدير أسرار. | الأسرار المكتوبة مباشرةً في الشيفرة. |
NextPDF / AsyncNextPDF | SDK | يبني الطلب، ويتصل بـ Connect، ويُرجِع نماذج Pydantic مُحدَّدة الأنواع. | منطق المجال أو سياسة التخزين. |
مساحة أسماء طرق ast | SDK | يربط استدعاء الطريقة بنقطة نهاية Connect ويحلّل الاستجابة. | سياسة إعادة المحاولة أو التراجع التدريجي خارج ما تُهيّئه. |
| نقطة نهاية NextPDF Connect | النشر | تُشغّل الاستخراج وتفرض المصادقة والحصص والترخيص. | تفويض صلاحية التطبيق. |
لا تنفّذ الـ SDK مطلقاً التعرّف الضوئي على الحروف (OCR). إذا كان ملف PDF ممسوحاً ضوئياً أو مقتصراً على الصور، فشغِّل OCR قبل الاستخراج. عامِل تلك الخطوة بوصفها شأناً يخصّ التطبيق خارج هذا الفاصل.
دورة حياة وقت التشغيل
قسم بعنوان «دورة حياة وقت التشغيل»| المرحلة | السلوك | إجراء المطوّر |
|---|---|---|
| إنشاء العميل | يجري التحقّق من صحّة base_url وapi_key؛ وأيّ قيمة فارغة منهما تُطلِق ValueError. | اقرأهما كليهما من بيئة التشغيل؛ ولا تكتبهما مباشرةً في الشيفرة مطلقاً. |
| إنشاء الواجهة الخلفية | تفتح الواجهة الخلفية البعيدة اتصالاً من مجمّع الاتصالات إلى Connect. | أعِد استخدام عميل واحد بين الاستدعاءات بدلاً من إنشاء عميل لكلّ طلب. |
| استدعاء الطريقة | تُسلسِل طريقة ast الطلب، وترسل بايتات PDF، وتحلّل الاستجابة إلى نموذج Pydantic. | مرِّر bytes التي جرى التحقّق من صحّتها مسبقاً. |
| ربط الأخطاء | تربط الـ SDK حالات بروتوكول نقل النصوص الفائقة (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 textprint(block.citation.page_index) # 0-based page indexprint(block.citation.confidence) # 0.0 - 1.0نمط العمل غير المتزامن وتجميع الدفعات
قسم بعنوان «نمط العمل غير المتزامن وتجميع الدفعات»استخدِم عميل AsyncNextPDF غير المتزامن داخل بيئات تشغيل asyncio مثل FastAPI. أنشِئ عميلاً واحداً بوصفه مدير سياق غير متزامن وشارِكه بين الاستدعاءات التي تعمل بالتزامن؛ ولا تفتح عميلاً لكلّ مستند. اضبط التزامن باستخدام إشارة سيمافور كي تراعي حصّة نقطة النهاية.
import asyncioimport 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 | تثبيت إصدار واجهة برمجة التطبيقات (API) لـ Connect. | القيمة الافتراضية هي v1؛ لا تُغيّرها إلّا عندما تدعم نقطة النهاية الإصدار المستهدف. |
| تهيئة بيئة التشغيل | وفِّر NEXTPDF_BASE_URL وNEXTPDF_API_KEY لواجهة سطر الأوامر (CLI) وخادم بروتوكول سياق النموذج (MCP). | عامِل المفتاح بوصفه سرّاً محصوراً في نطاق عبء العمل. |
خادم MCP (python -m nextpdf.mcp) | يُتيح أدوات الاستخراج للوكلاء القادرين على استخدام MCP. | يتطلّب الإضافة nextpdf[mcp] ونقطة نهاية خاضعة للتحكّم. |
سير عمل التطوير
قسم بعنوان «سير عمل التطوير»- ثبِّت الـ SDK باستخدام
pip install nextpdf، أو استخدِمpip install nextpdf[mcp]لخادم الوكيل. - اقرأ
NEXTPDF_BASE_URLوNEXTPDF_API_KEYمن بيئة التشغيل كي لا يدخل أيّ سرّ إلى نظام التحكّم بالمصدر. - تحقّق من صحّة كلّ مصدر PDF من حيث الوجود والحجم وبايتات التوقيع السحري
%PDF-قبل استدعاء الـ SDK. - أنشِئ عميلاً واحداً لكلّ عملية وأعِد استخدامه؛ وفي حالة asyncio، أبقِه مفتوحاً بـ
async with. - استدعِ طريقة
astالأكثر تحديداً والملائمة للمهمّة:extract_cited_text()للنصوص النثرية، وextract_cited_tables()للجداول، وget_document_ast()فقط عندما تحتاج إلى الشجرة الكاملة. - التقِط أكثر استثناء تحديداً يمكنك التصرّف إزاءه، ثمّ تراجَع إلى
NextPDFError. - للمستندات التي تتجاوز 100 MiB، استخدِم مسار البثّ في الـ CLI بدلاً من تحميل المحتوى كله في الذاكرة.
- شغِّل mypy في الوضع الصارم وأضِف اختباراً لوضع عطل لكلّ استثناء تعالجه.
معالجة الأعطال
قسم بعنوان «معالجة الأعطال»| العطل | الاستثناء | الاستجابة المُوصى بها |
|---|---|---|
| ملف PDF غير موسوم، والاستدلالات معطّلة | AstNoStructTreeError (HTTP 422) | فعِّل وضع الاستدلال على نقطة النهاية أو وفِّر ملف PDF موسوماً. |
| انتهاء مهلة البناء من جانب الخادم | AstBuildTimeoutError (HTTP 504) | قلِّص نطاق الصفحات وأعِد المحاولة. |
| فئة ترخيص مطلوبة | NextPDFLicenseError (HTTP 402) | رقِّ ترخيص الخادم أو تراجَع إلى ميزة مسموح بها. |
| حدّ المعدّل أو الحصّة | QuotaExceededError (HTTP 429) | انتظر retry_after ثانية، ثمّ أعِد المحاولة مع تراجع تدريجي. |
| خطأ HTTP آخر | NextPDFAPIError | افحص status_code وerror_code؛ وسجِّل خطأً مُعرّفاً وأظهِره. |
| أيّ خطأ في الـ SDK | NextPDFError | خيار التراجع النهائي؛ لا تسمح بمروره مطلقاً بوصفه استثناءً غير معالَج. |
تُبلِغ نقطة النهاية عن الأعطال باستخدام دلالات حالة HTTP المتوافقة مع طلب التعليقات (RFC) 9110 وبأجسام أخطاء قابلة للقراءة آلياً متوافقة مع RFC 9457. يحافظ كلّ استثناء على status_code الأصلي. اربط تلك الأعطال باستجابات الأخطاء الخاصّة بك بدلاً من تسريب تفاصيل النقل إلى المُستدعين.
الإعدادات الافتراضية الآمنة
قسم بعنوان «الإعدادات الافتراضية الآمنة»| الجانب المعني | الافتراضي | متى تتجاوزه |
|---|---|---|
| إصدار API | v1. | لا تُغيّره إلّا عندما تدعم نقطة النهاية إصداراً أحدث. |
| التحقّق من أمان طبقة النقل (TLS) | مُفعَّل؛ ولا يتوفّر أيّ مُبدِّل غير آمن. | لا تُعطّله مطلقاً لحركة المرور الإنتاجية. |
| بيانات الاعتماد | تُقرأ من بيئة التشغيل؛ ولا تُكتب مباشرةً في الشيفرة مطلقاً. | استخدِم مدير أسرار في بيئة الإنتاج. |
| حدّ الحجم في الذاكرة | ارفض ملفات PDF التي تتجاوز 100 MiB على مسار العميل. | اخفِضه في الخدمات متعدّدة المستأجرين؛ واستخدِم الـ CLI للملفات الأكبر. |
| التزامن | محدود بإشارة سيمافور في الدفعات غير المتزامنة. | اضبطه وفقاً لحصّة نقطة النهاية، لا وفقاً لعدد أنوية المضيف. |
| التسجيل | سجِّل اسم الملف والحجم والحالة والمدّة. | لا تُسجِّل مطلقاً بايتات PDF أو مفتاح API. |
قائمة التحقّق للاختبار
قسم بعنوان «قائمة التحقّق للاختبار»- تؤكّد اختبارات الإنشاء أنّ
base_urlأوapi_keyالفارغ يُطلِقValueError. - تغطّي اختبارات التحقّق المدخلات المفقودة والفارغة والمتجاوزة للحجم والتي ليست PDF.
- تؤكّد اختبارات الاستخراج أنواع النماذج المُرجَعة ووجود
CitationAnchorفي كلّ كتلة. - تغطّي اختبارات أوضاع الأعطال
AstNoStructTreeErrorوAstBuildTimeoutErrorوNextPDFLicenseErrorوQuotaExceededErrorوNextPDFAPIError. - تؤكّد الاختبارات غير المتزامنة أنّ العميل يعمل بوصفه مدير سياق
async withوأنّ التزامن يبقى ضمن الحدّ الذي تفرضه إشارة السيمافور. - تؤكّد اختبارات دورة الحياة أنّ
close()تُحرّر طبقة النقل وأنّ استدعاءها مُتساوي الأثر عند التكرار. - احقن واجهة خلفية وهمية بـ
AsyncNextPDF(backend=...)كي تعمل الاختبارات دون نقطة نهاية حيّة.
انظر أيضاً
قسم بعنوان «انظر أيضاً»- مرجع Python API — كلّ طريقة ونموذج واستثناء في العميل.
- واجهة Python CLI — الاستخراج بالبثّ للمستندات الكبيرة.
- خادم Python MCP — أدوات الاستخراج لوكلاء الذكاء الاصطناعي.
- نظرة عامة على Python SDK — خيارات الواجهة الخلفية وقيودها.