bayan-proxy / README.md
hatimqman's picture
bayan-proxy: README.md
89a511b verified
|
Raw
History Blame Contribute Delete
6.04 kB
metadata
title: Muaalem Proxy
sdk: docker
app_port: 7860
pinned: false

وسيط «بيان» — Muaalem Proxy

المصدر الرسميّ لِـHF Space hatimqman-muaalem-proxy. كان يعيش صندوقًا أسود على HF فقط؛ هذا مصدره الحقيقيّ داخل المستودع (Quran_Rateel/hf-endpoint/proxy/).

يجلس بين عميل بيان المنشور على Cloudflare Pages وبين ثلاث نقاط HF Inference، فيؤدّي:

  • يحمل توكن HF سرًّا (من متغيّر البيئة HF_TOKEN) ويحقنه في نداء النقطة — لا يصل التوكن للعميل أبدًا.
  • يتجاوز حجب Cloudflare 1010: العميل ينادي هذا الـSpace، والـSpace ينادي خادم HF.
  • فان-آوت لثلاث نقاط علويّة عبر ثلاثة مسارات.
  • يقبل جسمًا مسطّحًا ويغلّفه { "inputs": { … } } قبل تمريره للنقطة، فيبقى STT_URL وMUAALEM_URL في bayan/web/app.js بلا تغيير عنوان.
  • CORS لنطاق Pages، حدّ معدّل لكلّ IP، إعادة محاولة على البدء البارد (scale-to-zero)، وتدهورٌ آمن: أيّ فشلٍ للنقطة يُرجَع خطأ HTTP نظيفًا (لا استثناء) فيتجاهله العميل بصمتٍ.

المسارات (واجهة العميل — مسطّحة)

المسار يقبل من العميل يُمرَّر للنقطة النقطة العلويّة
POST /stt {pcm} أو {pcm, ref} {inputs:{pcm, ref?}} STT_ENDPOINT_URL (الطبقة الصوتية)
POST /analyze {pcm, surah, ayahs|ayah, mode?, scope?, sifat?} {inputs:{…}} ANALYZE_ENDPOINT_URL (المُعلِّم QPS)
WS /stream?kind=tlog|clean إطارات int16 PCM 16k + نصّ "end" تمريرٌ شفّاف STREAM_ENDPOINT_URL (بثّ احتياطيّ)
GET /health فحص جهوزيّة (يكشف أيّ نقطةٍ مُهيَّأة)

عقد POST /analyze

req  {"pcm":"<b64 PCM16 LE 16k أحاديّ>", "surah":1, "ayahs":[1,2,3,4,5,6,7],
      "mode?":"whole|teacher", "scope?":{…}, "sifat?":true}
      // أو "ayah":n لآيةٍ مفردة بدل ayahs
res  ردّ النقطة كما هو: {uthmani, match, per, words:[{w,hard,soft, …}],
      word_hard, word_soft, flagged, ops, ref_phonemes, pred_phonemes, mode, …}

mode/scope/sifat تُمرَّر شفّافةً؛ النقطة الحاليّة تتجاهلها بأمان، وطبقتا P1/P2 تستهلكانها.

عقد POST /stt

req  {"pcm":"<b64 PCM16 LE 16k>", "ref?":"<كلمات التشكيل للمحاذاة القسريّة>"}
res  {"text":"…", "words?":[{w,start_ms,end_ms,prob,gop,status}], "provider":"quran-stt-acoustic"}

بلا ref: نصّ فقط. مع ref: محاذاة قسريّة + توقيت/GOP/رأس نطق.

متغيّرات البيئة (Settings → Variables and secrets)

المتغيّر النوع الافتراضيّ الوصف
HF_TOKEN سرّ توكن HF (Bearer) لنقاط الاستدلال. إلزاميّ إن كانت النقاط محميّة.
STT_ENDPOINT_URL متغيّر URL كامل لنقطة الطبقة الصوتية. فارغٌ ⇒ /stt يُرجِع 503 نظيفًا.
ANALYZE_ENDPOINT_URL متغيّر URL كامل لنقطة المُعلِّم QPS. فارغٌ ⇒ /analyze يُرجِع 503 نظيفًا.
STREAM_ENDPOINT_URL متغيّر URL كامل لنقطة البثّ (ws:///wss://). فارغٌ ⇒ /stream يُغلَق بلطف.
ALLOWED_ORIGINS متغيّر أصولٌ صريحة مفصولة بفواصل (بجانب النمط أدناه).
ALLOWED_ORIGIN_REGEX متغيّر *.pages.dev/*.workers.dev/localhost نمط CORS. عدِّله لتقييده على نطاق Pages بعينه.
RATE_LIMIT_PER_MIN متغيّر 40 سقف الطلبات لكلّ IP في الدقيقة. 0 = مُعطَّل.
UPSTREAM_TIMEOUT متغيّر 150 سقف ميزانية الطلب الكلّيّة (ث) عبر كلّ المحاولات.
ATTEMPT_TIMEOUT متغيّر 60 مهلة قراءة المحاولة الواحدة (ث).
MAX_RETRIES متغيّر 6 أقصى عدد محاولات على البدء البارد.
RETRY_BACKOFF متغيّر 4 أساس التراجع الخطّيّ (ث).
RETRY_BACKOFF_MAX متغيّر 20 سقف التراجع بين المحاولات (ث).
MAX_BODY_BYTES متغيّر 25165824 سقف حجم جسم الطلب (~24MB).
LOG_LEVEL متغيّر INFO مستوى السجلّ.

إعادة المحاولة تُطلَق على حالات 500/502/503/504 (النقطة تستيقظ من scale-to-zero) وعلى أخطاء الاتصال/المهلة. أمّا 4xx الحتميّة فتُعاد فورًا بلا إعادة محاولة.

التشغيل المحلّيّ

pip install -r requirements.txt
export HF_TOKEN=hf_xxx
export ANALYZE_ENDPOINT_URL=https://<endpoint>.endpoints.huggingface.cloud
export STT_ENDPOINT_URL=https://<endpoint>.endpoints.huggingface.cloud
python app.py                 # يستمع على :7860 (أو $PORT)
# فحص:  curl localhost:7860/health

النشر على HF Space

  1. أنشئ Space من نوع Docker.
  2. ارفع app.py وrequirements.txt وDockerfile وREADME.md (front matter أعلاه يضبط app_port=7860).
  3. أضِف الأسرار/المتغيّرات من الجدول أعلاه (HF_TOKEN سرًّا؛ عناوين النقاط متغيّراتٍ).
  4. أبقِ MUAALEM_URL/STT_URL في bayan/web/app.js على https://<space>.hf.space/{analyze,stt} بلا تغيير.

لا شيء هنا يَنشُر تلقائيًّا — كودٌ فقط.