واجهة مكتبة شاملة البرمجية
قاعدة: 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) فقط.
الحصص والتحديد
| الخطة | يومياً | دقيقة | محادثات/يوم | أقصى نتائج | تجاري |
|---|---|---|---|---|---|
| free | 300 | 10 | 20 | 10 | لا |
| plus | 20,000 | 60 | 2,000 | 20 | نعم |
| partner | 500,000 | 240 | 50,000 | 20 | نعم |
الحصة تتجدّد عند 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 حرف) |
limit | 8 | عدد المقاطع (يُقيّد حسب الخطة) |
book | — | معرّف الكتاب (مثل 8653) أو جزء من اسمه |
category | — | اسم التصنيف أو جزء منه (مثل «الفقه الحنبلي») |
author | — | اسم المؤلف أو جزء منه (مثل «ابن تيمية») |
max_chars | 700 | أقصى طول المقطع (120–2000) |
page=1 | — | أضف نص الصفحة كاملة في page_text |
curl -s "BASE/v1/retrieve?q=القهقهة&limit=2&category=الفقه+الحنبلي" -H "Authorization: Bearer $KEY"
معرّف الصفحة id بصيغة رقم_الكتاب-رقم_الصفحة، وهو نفسه معرّف صفحة المصدر في مكتبة شاملة، فيمكن التتبع إلى الأصل مباشرة.
GET /v1/search — بحث على مستوى الصفحة
مثل 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 | متى |
|---|---|---|
| 401 | authentication_error | مفتاح غائب أو خاطئ |
| 403 | permission_error | مفتاح موقوف |
| 422 | invalid_request_error | معامل ناقص أو غير صالح |
| 429 | rate_limit_error | تجاوز حدّ الدقيقة |
| 429 | insufficient_quota | نفدت حصة اليوم |
| 502 / 504 | upstream_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=… في أي واجهة تعرض النصوص. روابط الصفحة دائمة وقابلة للتحقق.
الخصوصية: نخزّن عدّادات الاستدعاءات فقط. لا نبيع بيانات ولا نشاركها. نصوص المكتبة نفسها متاحة للجميع في مصدرها الأصلي.