واجهة سطر الأوامر في Python
واجهة سطر الأوامر في Python
قسم بعنوان «واجهة سطر الأوامر في Python»استخدم الأمر nextpdf لاستخراج المحتوى من ملفات تنسيق المستندات المحمولة (PDF) عبر الطرفية. وجِّهه إلى نقطة نهاية NextPDF Connect، ومرِّر ملف PDF، وتلقَّ مخرجات مُنظَّمة: نصًّا موثَّقًا بالاستشهادات، أو جداول، أو شجرة البنية النحوية المجردة (AST) الدلالية الكاملة، أو ملخص بيانات وصفية، وذلك على الإخراج القياسي (stdout) أو في ملف.
بنية الأمر
قسم بعنوان «بنية الأمر»يمثّل الأمر nextpdf مجموعة أوامر في Click. تنتمي خيارات الاتصال والجلسة — --base-url، و--api-key، و--log-level، و--output/-o، و--strict — إلى المجموعة، لذا ضعها قبل الأمر الفرعي. ثم ضع الأمر الفرعي وخياراته، مثل --format أو --page، بعده:
nextpdf [GROUP OPTIONS] COMMAND [SUBCOMMAND] PDF_PATH [COMMAND OPTIONS]إذا وضعت خيار مجموعة بعد الأمر الفرعي، فسيفشل الأمر. على سبيل المثال، يعرض nextpdf info document.pdf --base-url ... الرسالة Error: No such option: --base-url ويخرج برمز الحالة 2، لأن Click يكون قد بدأ بالفعل في تحليل الأمر الفرعي info عند رؤية --base-url، بينما لا يعرِّف info ذلك الخيار.
لتجنُّب مشكلة الترتيب، زوِّد بيانات الاعتماد عبر متغيرات البيئة (انظر التهيئة مرة واحدة لكل صَدَفة). تُظهِر الأمثلة أدناه صيغة الأعلام الصريحة أولًا حتى يكون الترتيب الصحيح واضحًا.
مرجع سريع
قسم بعنوان «مرجع سريع»استخراج النص بصيغة تدوين كائنات JavaScript (JSON):
nextpdf --base-url http://localhost:8080 --api-key "$NEXTPDF_API_KEY" extract text document.pdfاستخراج الجداول بصيغة القيم المفصولة بفواصل (CSV):
nextpdf --base-url http://localhost:8080 --api-key "$NEXTPDF_API_KEY" extract tables invoice.pdf --format csvفحص البيانات الوصفية للمستند وبنيته:
nextpdf --base-url http://localhost:8080 --api-key "$NEXTPDF_API_KEY" info document.pdfالحصول على شجرة البنية النحوية المجردة (AST) الدلالية الكاملة:
nextpdf --base-url http://localhost:8080 --api-key "$NEXTPDF_API_KEY" ast document.pdfطباعة إصدار مجموعة تطوير البرمجيات (SDK) المُثبَّتة دون الاتصال بخادم:
nextpdf versionالأمر version هو الأمر الوحيد الذي لا يحتاج إلى --base-url ولا إلى --api-key. أما كل أمر آخر فيتصل بالخادم ويتطلب كليهما.
يقرأ كل مثال مفتاح واجهة برمجة التطبيقات (API) من متغير البيئة NEXTPDF_API_KEY بدلًا من تضمينه في سطر الأوامر. تعامَل مع المفتاح بوصفه سرًّا. يظهر المفتاح الحرفي على سطر الأوامر في سِجِل الصَّدَفة الخاص بك وفي قائمة العمليات (ps) لدى مستخدمين آخرين على المُضيف.
الأوامر والخيارات
قسم بعنوان «الأوامر والخيارات»خيارات المجموعة
قسم بعنوان «خيارات المجموعة»ضع هذه الخيارات قبل الأمر الفرعي. يقرأ كل خيار اتصال أيضًا من متغير بيئة، لذا يمكنك حذف العَلَم عند تعيين المتغير.
| الخيار | متغير البيئة | الافتراضي | الغرض |
|---|---|---|---|
--base-url | NEXTPDF_BASE_URL | (مطلوب) | محدد موارد موحَّد (URL) لخادم NextPDF Connect. |
--api-key | NEXTPDF_API_KEY | (مطلوب) | مفتاح API للمصادقة باستخدام حامل الرمز. |
--log-level | — | warning | إسهاب التسجيل: debug، أو info، أو warning، أو error. تذهب السجلات إلى الخطأ القياسي (stderr). |
--output, -o | — | stdout | كتابة مخرجات الأمر إلى ملف بدلًا من stdout. |
--strict | — | مُعطَّل | محجوز للاستخدام المستقبلي. يُحلَّل العَلَم حاليًا لكنه لا يُغيِّر السلوك. |
--help, -h | — | — | عرض التعليمات والخروج. |
القيمتان --base-url و--api-key مطلوبتان لكل أمر باستثناء version. إذا كانت إحدى القيمتين مفقودة — لا عَلَم ولا متغير بيئة — فإن الأمر يطبع خطأً ويخرج بالحالة 1.
nextpdf extract text
قسم بعنوان «nextpdf extract text»استخراج كتل النص الموثَّقة بالاستشهادات. تتضمن كل كتلة مِرساة استشهاد مع مُعرِّف عُقدة، وفهرس صفحة، ومربع إحاطة، ودرجة ثقة.
nextpdf [GROUP OPTIONS] extract text PDF_PATH [--format FORMAT] [--page N] [--headings-only]| الخيار | القيم | الافتراضي | الغرض |
|---|---|---|---|
--format | json, markdown, plain | json | صيغة المخرجات. |
--page | عدد صحيح | كل الصفحات | استخراج فهرس هذه الصفحة فقط، المُرقَّم ابتداءً من 0. |
--headings-only | عَلَم | مُعطَّل | استخراج عُقد العناوين فقط. |
PDF_PATH هو مسار ملف، أو - لقراءة بايتات PDF من المُدخَل القياسي (stdin).
nextpdf extract tables
قسم بعنوان «nextpdf extract tables»استخراج كل جدول مع مراسي استشهاد وبنية على مستوى الخلايا.
nextpdf [GROUP OPTIONS] extract tables PDF_PATH [--format FORMAT] [--page-start N] [--page-end N]| الخيار | القيم | الافتراضي | الغرض |
|---|---|---|---|
--format | json, csv | json | صيغة المخرجات. |
--page-start | عدد صحيح | الصفحة الأولى | فهرس صفحة البدء (مُرقَّم ابتداءً من 0). |
--page-end | عدد صحيح | الصفحة الأخيرة | فهرس صفحة النهاية (مُرقَّم ابتداءً من 0). |
PDF_PATH هو مسار ملف، أو - للقراءة من stdin.
nextpdf ast
قسم بعنوان «nextpdf ast»إرجاع شجرة البنية النحوية المجردة (AST) الدلالية الكاملة بصيغة JSON: شجرة هرمية من العُقد، تتضمن العناوين والفقرات والجداول والقوائم والأشكال، مع مربعات الإحاطة والمحتوى النصي.
nextpdf [GROUP OPTIONS] ast PDF_PATH [--page-start N] [--page-end N] [--token-budget N]| الخيار | القيم | الافتراضي | الغرض |
|---|---|---|---|
--page-start | عدد صحيح | الصفحة الأولى | فهرس صفحة البدء (مُرقَّم ابتداءً من 0). |
--page-end | عدد صحيح | الصفحة الأخيرة | فهرس صفحة النهاية (مُرقَّم ابتداءً من 0). |
--token-budget | عدد صحيح | غير محدود | حد تقريبي لعدد الرموز في شجرة AST المُعادة. |
PDF_PATH هو مسار ملف، أو - للقراءة من stdin. يُنتِج الأمر ast شجرة مستند واحدة؛ وهو لا يقارن بين ملفي PDF. لإجراء المقارنة البنيوية، انظر وصفة: مقارنة مراجعتين من PDF.
nextpdf info
قسم بعنوان «nextpdf info»طباعة ملخص JSON مُوجَز لمستند واحد: إصدار المخطط، وتجزئة المصدر، وعدد الصفحات، وعدد الرموز المُقدَّر، ونوع العُقدة الجذرية، وعدد العناصر الفرعية للجذر.
nextpdf [GROUP OPTIONS] info PDF_PATHPDF_PATH هو مسار ملف، أو - للقراءة من stdin.
nextpdf version
قسم بعنوان «nextpdf version»طباعة إصدار SDK المُثبَّتة، مثل nextpdf 1.1.0، ثم الخروج. لا يتصل هذا الأمر بأي خادم ولا يحتاج إلى بيانات اعتماد.
nextpdf versionالتهيئة مرة واحدة لكل صَدَفة
قسم بعنوان «التهيئة مرة واحدة لكل صَدَفة»عيِّن خيارات الاتصال مرة واحدة كمتغيرات بيئة، واحذف الأعلام المتكررة. تتجنب هذه الصيغة أيضًا مشكلة ترتيب الخيارات بالكامل، لأن بيانات الاعتماد لا تظهر أبدًا على سطر الأوامر.
export NEXTPDF_BASE_URL=http://localhost:8080export NEXTPDF_API_KEY=your-keynextpdf extract text document.pdfفي Windows PowerShell:
$env:NEXTPDF_BASE_URL = "http://localhost:8080"$env:NEXTPDF_API_KEY = "your-key"nextpdf extract text document.pdfيُفضَّل تحميل المفتاح من مخزن أسرار أو من ملف .env تُبقيه خارج التحكم في الإصدارات. لا تلصق مفتاح إنتاج في جلسة طرفية مشتركة أو في سكربت تدرجه في التحكم بالإصدار.
صيغ المخرجات
قسم بعنوان «صيغ المخرجات»اختر صيغة المخرجات لكل أمر باستخدام --format. يدعم أمرا النص والجداول أكثر من صيغة واحدة؛ أما ast وinfo فيُخرِجان JSON دائمًا.
| الأمر | الصيغ | الافتراضي |
|---|---|---|
extract text | json, markdown, plain | json |
extract tables | json, csv | json |
ast | json | json |
info | json | json |
اختر JSON عندما يحتاج برنامج لاحق إلى فهارس الصفحات أو درجات الثقة أو مُعرِّفات العُقد. اختر CSV عندما تكون الجداول مدخلات لجدول بيانات أو لمسار معالجة جدولي. اختر نص plain أو markdown عندما يقرأ النتيجة شخص أو أداة نصية فقط.
تحليل مخرجات JSON
قسم بعنوان «تحليل مخرجات JSON»يُخرِج أمر النص مصفوفة JSON من الكتل الموثَّقة بالاستشهادات. تتضمن كل كتلة text، وكائن citation (node_id، وpage_index، وbbox، وconfidence)، وحقل node_type اختياري. أرسِل المخرجات إلى ملف باستخدام --output، أو أعِد توجيه stdout، ثم حلِّلها.
يستخدم مثال الصَّدَفة هذا jq للإبقاء على العناوين فقط في الصفحة 0:
nextpdf --output blocks.json extract text report.pdf --format jsonjq '[.[] | select(.citation.page_index == 0 and .node_type == "heading") | .text]' blocks.jsonتُحلَّل البيانات نفسها بسلاسة في Python. تكتب واجهة سطر الأوامر (CLI) مصفوفة JSON، لذا حمِّلها باستخدام المكتبة القياسية واقرأ الحقول المُنمَّطة:
"""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)عندما تحتاج إلى نماذج مُنمَّطة ومُتحقَّق منها بدلًا من القواميس الخام، استدعِ SDK مباشرةً بدلًا من تحليل مخرجات CLI. انظر نظرة عامة على Python للاطلاع على عميل NextPDF ونوع الإرجاع CitedTextBlock الخاص به.
تحليل مخرجات CSV
قسم بعنوان «تحليل مخرجات CSV»باستخدام --format csv، يكتب أمر الجداول كتلة CSV واحدة لكل جدول. يسبق كلَّ جدول صفُّ تعليق، # Table N (pM)، يذكر رقم الجدول المُرقَّم ابتداءً من 1 وفهرس الصفحة المُرقَّم ابتداءً من 0. يفصل سطرٌ فارغ بين الجداول المتتالية. تُحيط CLI قيم الخلايا بعلامات اقتباس وتُهرِّبها باستخدام وحدة csv في Python، حتى تبقى القيم التي تحتوي على فواصل أو علامات اقتباس أو أسطر جديدة آمنة عند القراءة والكتابة.
nextpdf --output tables.csv extract tables statement.pdf --format csvلأن الملف يحتوي على كتل CSV متعددة، قسِّمه عند صفوف التعليقات قبل تحليل كل كتلة كجدول مستقل:
"""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")رموز الخروج واكتشاف الأخطاء
قسم بعنوان «رموز الخروج واكتشاف الأخطاء»تستخدم CLI ثلاثة رموز خروج. تحقَّق من $? في سكربتات الصَّدَفة، أو من $LASTEXITCODE في PowerShell، للتفرُّع بناءً على النجاح أو الفشل. اقرأ رسائل التشخيص من stderr، الذي يبقى منفصلًا عن البيانات الموجودة في stdout.
| رمز الخروج | المعنى | أمثلة |
|---|---|---|
0 | نجاح. | اكتمل أمرٌ ما؛ طُبِع version. |
1 | خطأ وقت التشغيل. تطبع CLI Error: <message> إلى stderr. | ملف الإدخال غير موجود أو ليس ملفًا عاديًّا، أو stdin فارغ، أو --base-url/--api-key مفقود أو غير صالح، أو أي خطأ من جانب الخادم (الترخيص مطلوب، أو تجاوز الحصة، أو ملف PDF غير موسوم، أو انتهاء مهلة البناء، أو فشل آخر في API). |
2 | خطأ استخدام، تُبلِغ عنه Click. | أمر أو خيار غير معروف (بما في ذلك وضع خيار مجموعة بعد الأمر الفرعي)، أو وسيط مطلوب مفقود مثل PDF_PATH. |
يُرجِع كل فشل من جانب الخادم رمز الخروج 1 مع رسالة قابلة للقراءة البشرية على stderr. يُطلِق SDK استثناءً مُنمَّطًا — NextPDFLicenseError (بروتوكول نقل النص التشعبي (HTTP) 402)، أو QuotaExceededError (HTTP 429)، أو AstNoStructTreeError (HTTP 422، ملف PDF غير موسوم)، أو AstBuildTimeoutError (HTTP 504)، أو القاعدة NextPDFAPIError. تلتقط CLI هذه الاستثناءات كلها عبر القاعدة المشتركة NextPDFError، وتطبع الرسالة، وتخرج بالرمز 1. لا تعرض CLI رموز خروج مميزة لكل نوع فشل. للتمييز، على سبيل المثال، بين خطأ حصة وخطأ ترخيص في سكربت، افحص نص الرسالة على stderr أو استدعِ SDK مباشرةً (انظر نظرة عامة على Python للاطلاع على فئات الاستثناء).
استخدم نمط البرمجة النصية هذا لفصل البيانات عن التشخيصات:
#!/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}"fiباستخدام --output، تكتب CLI البيانات إلى الملف المُسمَّى وتطبع سطر التأكيد Written to <path> فقط إلى stderr، فيبقى stdout فارغًا. بدون --output، تذهب البيانات إلى stdout، ويمكنك إعادة توجيهها.
الوصفات
قسم بعنوان «الوصفات»تستخدم كل وصفة أدناه أوامر وأعلامًا تم التحقق منها فقط. في كل حالة، تأتي بيانات الاعتماد من البيئة.
وصفة: استخراج جداول الفواتير إلى CSV
قسم بعنوان «وصفة: استخراج جداول الفواتير إلى CSV»حوِّل مجلدًا من الفواتير إلى ملف CSV واحد لكل مستند من أجل جدول بيانات أو مسار معالجة محاسبي:
#!/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 csvdoneيحتوي كل out/<name>.csv على كتلة CSV واحدة لكل جدول مُكتشَف، مع ترويسة # Table N (pM) قبل كل كتلة. حلِّل الكتل باستخدام قارئ CSV الموضَّح أعلاه.
وصفة: بناء مخطط تفصيلي للمستند
قسم بعنوان «وصفة: بناء مخطط تفصيلي للمستند»اجمع بين --headings-only وصيغة markdown لإنتاج مخطط تفصيلي سريع يمكنك قراءته أو لصقه في الملاحظات:
nextpdf --output outline.md extract text whitepaper.pdf --headings-only --format markdownوصفة: مقارنة مراجعتين من PDF
قسم بعنوان «وصفة: مقارنة مراجعتين من PDF»يُرجِع أمر ast في CLI شجرة مستند واحد؛ وليس له أمر فرعي للمقارنة. تتوفر المقارنة البنيوية في SDK باسم client.ast.get_ast_diff(...) وفي خادم بروتوكول سياق النموذج (MCP) بوصفها أداة nextpdf_diff. شغِّل المقارنة عبر 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"))لتشغيل المقارنة نفسها من عميل ذكاء اصطناعي (AI) بدلًا من سكربت، سجِّل خادم MCP واستدعِ أداة nextpdf_diff. انظر صفحة خادم MCP للغة Python.
وصفة: تدفُّق ملف PDF من أداة أخرى
قسم بعنوان «وصفة: تدفُّق ملف PDF من أداة أخرى»اقرأ بايتات PDF من stdin باستخدام - لربط nextpdf بعد أداة تُخرِج ملف PDF إلى stdout الخاص بها:
curl --silent https://example.com/report.pdf | nextpdf info -يُخبِر الوسيط - الأمرَ بقراءة المستند من stdin. إذا لم تصل أي بايتات، فإن الأمر يُبلِّغ عن خطأ ويخرج بالرمز 1.
ملاحظات الأداء
قسم بعنوان «ملاحظات الأداء»تبني CLI كل استجابة في الذاكرة وتكتبها مرة واحدة. إعادة التوجيه أو تمرير المخرجات عبر pipe أمر بسيط، لكن المخرجات لا تُنتَج تدريجيًّا. تُخزَّن شجرة AST كبيرة أو مجموعة جداول كبيرة بالكامل في المخزن المؤقت قبل أن يصل أول بايت إلى stdout أو إلى ملف --output. خطِّط للذاكرة والكُمون لاستجابات المستند الكامل، لا للتدفُّق.
يُنشئ كل استدعاء لـ nextpdf عميلًا واتصال HTTP جديدين، لذا فإن حلقة على ملفات كثيرة تفتح وتغلق اتصالًا لكل ملف. تكون تكلفة الاتصال عادةً صغيرة مقارنةً بوقت الاستخراج من جانب الخادم، لكنها تصبح عبئًا حقيقيًّا على نطاق واسع.
- أعِد استخدام نقطة نهاية واحدة. وجِّه كل استدعاء إلى نشر NextPDF Connect نفسه حتى يتمكن الخادم من إعادة استخدام الذواكر المؤقتة المُحمَّاة ومجمَّعات الاتصال. تجنَّب توزيع دفعة عبر نقاط نهاية متعددة ما لم تكن توازن الأحمال عمدًا.
- قيِّد العمل لكل استدعاء. استخدم
--page، أو--page-start/--page-end، أو--token-budgetلمعالجة الصفحات التي تحتاجها فقط. تُقلِّل نطاقات الصفحات الأصغر من وقت الخادم وحجم الاستجابة معًا؛ ويُحدِّد--token-budgetسقف شجرة AST التي يتعين على عميلك قراءتها. - جمِّع الدُّفعات في عملية واحدة للمهام الكبيرة. بالنسبة للدُّفعات عالية الحجم، يُفضَّل استخدام Python SDK بدلًا من استدعاءات CLI المتكررة. يعيد عميل
NextPDFأوAsyncNextPDFواحد طويل العمر استخدام اتصال HTTP مُجمَّع واحد عبر كل مستند، مما يُزيل بدء التشغيل لكل عملية وإعداد الاتصال الذي تدفعه حلقة CLI في كل مرة. تُظهِر نظرة عامة على Python دورة حياة العميل، ويدعمAsyncNextPDFالاستخراج المتزامن عبر ملفات PDF كثيرة. - أبقِ السجلات خارج مسار البيانات. اترك
--log-levelعلى قيمته الافتراضية لعمليات الدُّفعات. تذهب سجلات التشخيص إلى stderr ولا تُفسِد بيانات stdout، لكن رفع المستوى إلىdebugيضيف ضوضاء وعبئًا طفيفًا.