# تلخيص ملفات PDF باستخدام بايثون — دليل واجهة برمجة تطبيقات تلخيص PDF

أضف ميزة تلخيص مستندات PDF إلى سكربت بايثون، أو دفتر ملاحظات، أو نظام خلفي في أسطر قليلة. يغطي هذا الدليل المصادقة، والطلب الأول، وتنسيق الاستجابة، والبث، ومعالجة مجلد كامل، والتعامل مع الأخطاء بشكل صحيح.

## Key facts

- نقطة النهاية (Endpoint): POST https://pdf-summarize.com/api/summarize.php باستخدام multipart/form-data والحقل file.
- المصادقة: ترويسة Authorization: Bearer sk_... — مفتاح مجاني عند التسجيل، بدون بطاقة ائتمان.
- الخيارات: length (قصير/متوسط/طويل/مفصل)، format (فقرة/نقاط/مختلط)، outputLang (تلقائي أو رمز اللّغة)، includeKeywords.
- الاستجابة: كائن JSON يحتوي على summary، keywords، page_count، processing_time، requests_remaining.
- أضف ?stream=1 لتلقي الملخص عبر أحداث مرسلة من الخادم (Server-Sent Events).

## المتطلبات الأساسية

- بايثون 3.8+ ومكتبة `requests` (`pip install requests`).
- مفتاح API: [أنشئ حساباً مجانياً](/signup) وانسخ مفتاحك من لوحة التحكم. احفظه في متغير بيئي بدلاً من تضمينه في الكود:

```bash
export PDF_SUMMARIZE_KEY="sk_live_..."
```

## أول ملخص PDF لك باستخدام بايثون

1. **تثبيت مكتبة requests** — استخدم الأمر pip install requests.
2. **إعداد مفتاح API** — ضعه في متغير البيئة PDF_SUMMARIZE_KEY.
3. **إرسال ملف PDF** — بتنسيق multipart/form-data مع اسم الحقل file.
4. **قراءة بيانات JSON** — يوجد الملخص في حقل summary؛ وتحقق من success وحالة HTTP.

```python
import os
import requests

API_URL = "https://pdf-summarize.com/api/summarize.php"
API_KEY = os.environ["PDF_SUMMARIZE_KEY"]

def summarize_pdf(path, length="medium", fmt="bullets", lang="auto"):
    with open(path, "rb") as f:
        resp = requests.post(
            API_URL,
            headers={"Authorization": f"Bearer {API_KEY}"},
            files={"file": (os.path.basename(path), f, "application/pdf")},
            data={"length": length, "format": fmt, "outputLang": lang, "includeKeywords": "1"},
            timeout=180,
        )
    data = resp.json()
    if resp.status_code != 200 or not data.get("success"):
        raise RuntimeError(f"{resp.status_code}: {data.get('error', data)}")
    return data

result = summarize_pdf("annual-report.pdf")
print(result["summary"])
print("الصفحات:", result["page_count"], "| الكلمات الرئيسية:", result.get("keywords"))
```

## الاستجابة

```json
{
  "success": true,
  "summary": "- نمت الإيرادات بنسبة 6% لتصل إلى...",
  "keywords": "الإيرادات، الهامش، التوجيهات،...",
  "page_count": 48,
  "original_length": 182340,
  "summary_length": 1210,
  "processing_time": 6.214,
  "requests_remaining": 4987
}
```

حقل `requests_remaining` يمثل حصتك الشهرية المتبقية (القيمة `-1` تعني بلا حدود).

## بث الملخص (Streaming)

للمستندات الطويلة أو التطبيقات التفاعلية، قم ببث الملخص أثناء توليده:

```python
import json

def stream_summary(path):
    with open(path, "rb") as f:
        with requests.post(
            API_URL + "?stream=1",
            headers={"Authorization": f"Bearer {API_KEY}"},
            files={"file": (os.path.basename(path), f, "application/pdf")},
            data={"length": "long", "format": "mixed"},
            stream=True, timeout=300,
        ) as resp:
            resp.raise_for_status()
            for line in resp.iter_lines(decode_unicode=True):
                if not line or not line.startswith("data: "):
                    continue
                payload = line[6:]
                if payload == "[DONE]":
                    break
                event = json.loads(payload)
                if "error" in event:
                    raise RuntimeError(event["error"])
                if event.get("type") == "summary":
                    print(event["content"], end="", flush=True)

stream_summary("research-paper.pdf")
```

## معالجة مجلد كامل من ملفات PDF

```python
import pathlib, time

out_dir = pathlib.Path("summaries")
out_dir.mkdir(exist_ok=True)

for pdf in sorted(pathlib.Path("pdfs").glob("*.pdf")):
    target = out_dir / (pdf.stem + ".md")
    if target.exists():
        continue                      # يدعم استئناف المعالجة
    for attempt in range(3):
        try:
            data = summarize_pdf(str(pdf), length="long", fmt="mixed")
            target.write_text(data["summary"], encoding="utf-8")
            print("تم بنجاح", pdf.name, data["page_count"], "صفحة")
            break
        except RuntimeError as e:
            if str(e).startswith("429"):
                time.sleep(30 * (attempt + 1))   # تجاوز الحد: الانتظار ثم إعادة المحاولة
            else:
                print("فشل", pdf.name, e)
                break
```

## الأخطاء التي يجب التعامل معها

| الحالة | المعنى | الإجراء المطلوب |
|---|---|---|
| 400 | ملف مفقود، نوع خطأ، أو تجاوز حد الصفحات | تحقق من الملف ومن حد صفحات خطتك |
| 401 | مفتاح API مفقود أو غير صالح | تحقق من ترويسة `Authorization` |
| 403 | الحساب معلق | تواصل مع الدعم الفني |
| 413 | الملف كبير جداً | قم بضغط ملف PDF أو تقسيمه |
| 422 | لا يوجد نص قابل للقراءة (فارغ، محمي، أو مسح ضوئي غير مقروء) | أزل كلمة المرور وحسّن المسح الضوئي |
| 429 | تم الوصول للحد الأقصى للطلبات أو الحصة الشهرية | انتظر قليلاً ثم أعد المحاولة أو قم بترقية باقتك |
| 500 | خدمة التلخيص غير متوفرة مؤقتاً | أعد المحاولة مع تأخير زمني تدريجي |

> **هل تريد التجربة دون كتابة كود برمجياً؟** — جرب نفس المحرك في متصفحك مجاناً.

## نصائح هامة

- **اضبط مهلة الانتظار (Timeouts)** بسخاء (2-3 دقائق) لملفات PDF الطويلة.
- **خزن النتائج مؤقتاً (Cache)** باستخدام تجزئة الملف (File Hash) لتجنب دفع التكلفة مرتين لنفس المستند.
- **حافظ على سرية المفاتيح في الخادم الخلفي** — ولا تضمنها أبداً في تطبيقات الواجهة الأمامية أو الجوال.
- للتعرف على كافة المعلمات: راجع [توثيق واجهة برمجة التطبيقات](/docs).

## FAQ

### هل توجد خطة API مجانية؟

نعم. تتضمن الخطة المجانية حصة شهرية من الطلبات دون الحاجة لبطاقة ائتمان. راجع الأسعار.

### هل يمكنني إرسال رابط (URL) لملف PDF بدلاً من الملف مباشرة؟

تستقبل واجهة برمجة التطبيقات الملف نفسه. قم بتحميل ملف PDF في الكود الخاص بك (باستخدام مكتبة requests مثلاً) ثم أرسل البيانات الثنائية (Bytes).

### ما هي اللغات التي يمكن استخدامها في الملخص؟

استخدم الخيار outputLang=auto للحفاظ على لغة المستند، أو حدد رمز اللغة المطلوبة مثل en، fr، es، de.

### كيف يمكنني تلخيص ملفات PDF الممسوحة ضوئياً (Scanned) عبر API؟

أرسلها تماماً مثل أي ملف PDF؛ حيث يتحول نظام الاستخراج تلقائياً إلى التعرف الضوئي على الحروف (OCR) عندما لا توجد طبقة نصية قابلة للاستخدام.

---
Source: https://pdf-summarize.com/ar/guides/pdf-summary-api-python — PDF Summarizer (free PDF summarizer, Q&A with page citations, OCR, REST API). Site overview: https://pdf-summarize.com/llms.txt
