توثيق API — مكتبة شاملة

واجهة مكتبة شاملة البرمجية

قاعدة: https://api.91.229.245.90.nip.io — كل المسارات تبدأ بـ /v1، وكل الردود JSON بترميز UTF-8.

البداية السريعة

curl "https://api.91.229.245.90.nip.io/v1/retrieve?q=القهقهة%20في%20الوضوء&limit=3" \
  -H "Authorization: Bearer jb_live_مفتاحك"

التوثيق بالمفتاح

أرسل المفتاح بإحدى الطرق الثلاث:

الطريقةمثال
ترويسة Bearer (موصى به)Authorization: Bearer jb_live_...
ترويسة مخصّصةX-API-Key: jb_live_...
معامل استعلام (للمتصفح فقط)?key=jb_live_...

تحصل على مفتاح مجاني من POST /v1/register أو من زر «أنشئ مفتاحاً» في الصفحة الرئيسية. المفتاح يظهر مرة واحدة عند الإنشاء، ويُخزَّن عندنا مُجزَّأً (SHA-256) فقط.

الحصص والتحديد

الخطةيومياًدقيقةمحادثات/يومأقصى نتائجتجاري
free300102010لا
plus20,000602,00020نعم
partner500,00024050,00020نعم

الحصة تتجدّد عند 00:00 UTC. كل رد يحمل ترويسات:

X-RateLimit-Limit: 10
X-RateLimit-Remaining: 9
X-Quota-Limit: 300
X-Quota-Used: 12
X-Quota-Remaining: 288
X-Request-Id: 9f2c1a7b4d8e1033
X-Cache: HIT | MISS

GET /v1/retrieve — استرجاع مقاطع (RAG)

القلب النابض للخدمة: يبحث في 7.6 مليون صفحة، ويعيد مقطعاً من داخل الصفحة حول كلماتك لا الصفحة كاملة.

المعاملافتراضيالوصف
q *مطلوب—نص البحث (عربي، حتى 500 حرف)
limit8عدد المقاطع (يُقيّد حسب الخطة)
book—معرّف الكتاب (مثل 8653) أو جزء من اسمه
category—اسم التصنيف أو جزء منه (مثل «الفقه الحنبلي»)
author—اسم المؤلف أو جزء منه (مثل «ابن تيمية»)
max_chars700أقصى طول المقطع (120–2000)
page=1—أضف نص الصفحة كاملة في page_text
curl -s "BASE/v1/retrieve?q=القهقهة&limit=2&category=الفقه+الحنبلي" -H "Authorization: Bearer $KEY"

معرّف الصفحة id بصيغة رقم_الكتاب-رقم_الصفحة، وهو نفسه معرّف صفحة المصدر في مكتبة شاملة، فيمكن التتبع إلى الأصل مباشرة.

مثل retrieve لكنه يعيد مقطعاً أوسع من الصفحة (حتى ضعف max_chars) — مفيد حين تبني فهرساً أو قاعدة معرفة ولا تريد تفتيت الصفحات.

GET /v1/page — نص صفحة كاملة

المعاملالوصف
id *مطلوبمعرّف الصفحة، مثال 217-45
html=1أعد النص بوسومه الأصلية بدل النص المجرّد
GET /v1/page?id=217-45
{ "found": true, "id": "217-45", "book_id": "217", "book": "المغني",
  "category": "الفقه الحنبلي", "authors": "…", "part": "…", "chars": 5310, "text": "…" }

الفهرس والتصفّح

GET /v1/books — قائمة كتب مع تصفية وترقيم صفحات:

المعاملالوصف
qبحث في اسم الكتاب أو المؤلف
category / authorتصفية
limit / offsetترقيم الصفحات (حتى 100 لكل صفحة)
with_parts=1أضف parts_count لكل كتاب
GET /v1/books?q=المغني&limit=3&with_parts=1
{ "total": 11, "offset": 0, "limit": 3, "count": 3,
  "books": [ { "id": "8653", "name": "المغني في تصريف الأفعال",
               "category": "النحو والصرف", "authors": "محمد عبد الخالق عضيمة",
               "author_ids": "1982", "death": "1404", "parts_count": 11 } ] }

GET /v1/toc?book=217 — أجزاء كتاب (فهرس ما بعده) مع ترقيم:

GET /v1/book?id=217 — بيانات كتاب كاملة مع عدد أجزائه ومؤلفيه.

التصنيفات والمؤلفون والإحصاءات

GET /v1/categories — كل التصنيفات مع عدد كتب كل منها.

GET /v1/authors?limit=50&q=تيمية — المؤلفون مرتّبين بعدد كتبهم، مع سنة وفاتهم.

GET /v1/stats — حجم الفهرس وبنيته.

POST /v1/chat/completions — دردشة فوق النصوص (متوافقة مع OpenAI)

يستقبل نفس جسم طلب OpenAI، ويجيب من نصوص المكتبة مع ذكر المصادر. يدعم stream: true.

from openai import OpenAI
client = OpenAI(base_url="BASE/v1", api_key="jb_live_...")
r = client.chat.completions.create(
    model="jahbath-rag",
    messages=[{"role": "user", "content": "اذكر مسألة في قضاء الصلاة إذا فاتته ركعة"}])
print(r.choices[0].message.content)
for s in r.jahbath["sources"]:
    print(s["book"], s["id"])

الحقل الإضافي jahbath (متجاهل من عملاء OpenAI) يحمل hits وsources وai. الوصول إليه من Python:

from openai import OpenAI
client = OpenAI(base_url="BASE/v1", api_key="jb_live_...")
r = client.chat.completions.create(model="jahbath-rag",
    messages=[{"role": "user", "content": "اذكر مسألة في قضاء الصلاة إذا فاتته ركعة"}])
print(r.choices[0].message.content)
print(r.jahbath["sources"])   # مصادر مرقّمة صفحات مع روابط مباشرة
مهم: jahbath-rag سؤال‑وجواب مباشر: يستخرج بنفسه من المكتبة ويتجاهل أي سياق أو تعليمات نظام ترسلها إليه. لبناء خط أنابيب RAG بنموذجك أنت، استعمل两步: /v1/retrieve لتأمين المقاطع ثم مرّرها إلى نموذجك (OpenAI أو Ollama أو أي نموذج محلي).

GET /v1/models — يسرد النموذج المتاح: jahbath-rag.

استخدام المفتاح مع نموذج ذكاء اصطناعي

طريقتان، واحدة مجانية بالكامل والأخرى مع نموذجك:

1) سؤال‑وجواب مباشر من المكتبة (بلا حساب OpenAI)

from openai import OpenAI
client = OpenAI(base_url="BASE/v1", api_key="jb_live_...")
while True:
    q = input("سؤالك: ")
    r = client.chat.completions.create(model="jahbath-rag",
                                       messages=[{"role": "user", "content": q}])
    print(r.choices[0].message.content)
    for s in r.jahbath["sources"][:3]:
        print("   📖", s["book"], s["id"])

2) خط RAG بنموذجك أنت (OpenAI أو محلي)

import requests
from openai import OpenAI

BASE = "BASE"; KEY = "jb_live_..."
def retrieve(q, k=6, **f):
    p = {"q": q, "limit": k}; p.update(f)
    d = requests.get(f"{BASE}/v1/retrieve", params=p,
                     headers={"Authorization": f"Bearer {KEY}"}, timeout=30).json()
    return d["passages"]

def answer(question, **f):
    ps = retrieve(question, **f)
    ctx = "\n\n".join(f"[{i}] {p['book']} — {p['text']}" for i, p in enumerate(ps, 1))
    llm = OpenAI(api_key="sk-...")           # مفتاح نموذجك أنت
    r = llm.chat.completions.create(
        model="gpt-4o-mini",
        messages=[{"role": "system", "content":
                   "أجب من النص التالي فقط، وضع رقم المصدر بين قوسين:\n" + ctx},
                  {"role": "user", "content": question}])
    return r.choices[0].message.content, ps

print(answer("ما حكم صلاة التيمم للمسافر إذا وجد الماء؟",
             category="الفقه الحنبلي", limit=8)[0])

مع LangChain أو LlamaIndex: اجعل /v1/retrieve مسترجعاً (Retriever) يمرّر page_content = passage["text"] وmetadata = passage، ثم اربطه بأي نموذج عندك.

مع نموذج محلي (Ollama): نفس الكود مع base_url="http://localhost:11434/v1".
مع دردشة الويب أو تطبيقات الجوال: أرسل المفتاح في Authorization: Bearer من الخادم فقط، ولا تضعه في كود الواجهة.

الحساب والحصص

POST /v1/register — {"email":"...", "org":"..."} → مفتاح مجاني (3 مفاتيح لكل بريد يومياً، 5 لكل IP).

GET /v1/me — بيانات مفتاحك: الخطة، الحدود، استهلاك اليوم، إجمالي الاستدعاءات منذ الإنشاء.

GET /v1/usage?days=30 — استهلاك آخر 30 يوماً.

الأخطاء

كل خطأ بصيغة موحّدة متوافقة مع OpenAI:

{ "error": { "message": "استُنفدت حصة اليوم (300 استدعاء). تتجدد عند 00:00 UTC",
              "type": "insufficient_quota", "code": "quota_exceeded",
              "param": null, "plan": "free", "limit": 300, "used": 300 } }
الحالةtypeمتى
401authentication_errorمفتاح غائب أو خاطئ
403permission_errorمفتاح موقوف
422invalid_request_errorمعامل ناقص أو غير صالح
429rate_limit_errorتجاوز حدّ الدقيقة
429insufficient_quotaنفدت حصة اليوم
502 / 504upstream_errorعطل مؤقت في الفهرس

وصفات جاهزة

بناء RAG بسيط

context = "\n\n".join(
  f"[{p['book']} — {p['part']} ({p['id']})] {p['text']}"
  for p in passages)
prompt = f"Using only the context, answer in Arabic and cite [book, id].\n\n{context}\n\nQ: {question}"

حصر النتائج في مذهب

/v1/retrieve?q=الصوم&category=الفقه+الحنبلي&limit=20
/v1/retrieve?q=الاجتهاد&author=ابن+تيمية

تقطيع كتاب كامل إلى مقاطع

parts = GET /v1/toc?book=217&limit=5000
for part in parts.parts:
    page = GET /v1/page?id=part.id
    chunk(page.text, 700, overlap=100)

التحقق من إجابة نموذج

ans = POST /v1/chat/completions
for s in ans.jahbath["sources"]:
    src = GET /v1/page?id=s.id     # تعيد النص الأصلي للتحقق

الاستخدام والإسناد

الاستخدام: الخطة المجانية للبحث والاستخدام غير التجاري. الاستخدام التجاري (منتج، تطبيق، خدمة مدفوعة) يتطلب خطة plus أو partner.

الإسناد: نرجو ذكر «مكتبة شاملة — عبر API الجهبذ» مع رابط الصفحة /v1/page?id=… في أي واجهة تعرض النصوص. روابط الصفحة دائمة وقابلة للتحقق.

الخصوصية: نخزّن عدّادات الاستدعاءات فقط. لا نبيع بيانات ولا نشاركها. نصوص المكتبة نفسها متاحة للجميع في مصدرها الأصلي.