Python
ابنِ مسارات Batch والنسخ السريع والفوري والتمييز وTTS باستخدام humain-voice 0.18.0.
يستهدف هذا الدليل بالضبط humain-voice==0.18.0 على Python 3.10 أو أحدث.
تُحلل برامجه المعروضة وتُفحص أنواعها مقابل وسم الإصدار python/v0.18.0.
ثبّت واضبط
ثبّت الحزمة المثبتة الإصدار في بيئة الخادم أو البيئة الافتراضية:
python -m pip install humain-voice==0.18.0اضبط القيم الصادرة لبيئتك:
export API_URL="https://api.voice.humain.com"
export API_KEY="YOUR_API_KEY"
export API_VERSION="v1"استورد الشيفرة الجديدة عبر humain_voice. مساحة sautech التاريخية استيراد
توافق مهمل في 0.18.0 وتصدر تحذيرًا.
يستخدم Batch القيم API_URL وAPI_KEY وAPI_VERSION. ويتطلب عملاء
Socket.IO الحقلين api_url وapi_key فقط، ويكون api_path افتراضيًا
/socket.io. مرّر مسارًا فقط لتجاوز النشر؛ وتتطلب نقطة النهاية القديمة
sautech.humain.com المسار /realtime/socket.io.
يدعم كل عميل Python التنظيف غير المتزامن ومديري السياق غير المتزامن والمتزامن.
تغطية الدوال غير متناظرة: استخدم فقط الدوال المتزامنة المسماة لكل عميل أدناه.
لا توجد دالتا connect_sync() أو disconnect_sync() عامتان.
المهمة الأولى: انسخ تسجيلًا مكتملًا
ابدأ بـBatchTranscribeClient عندما يكون التسجيل الكامل موجودًا، وخصوصًا
لاجتماع طويل أو بودكاست أو مقابلة أو ملف أرشيف. احفظ هذا المصدر المختبر باسم
batch_transcription.py بجانب تسجيل الإدخال:
from __future__ import annotations
import asyncio
import os
import sys
from pathlib import Path
from humain_voice import stt
from humain_voice.stt.batchtranscription import BatchDiarization
def required_env(name: str) -> str:
value = os.environ.get(name)
if not value:
raise RuntimeError(f"{name} is required")
return value
async def main() -> None:
input_path = Path(sys.argv[1] if len(sys.argv) > 1 else "meeting.wav")
output_path = Path(sys.argv[2] if len(sys.argv) > 2 else "meeting.vtt")
async with stt.BatchTranscribeClient(
api_url=required_env("API_URL"),
api_key=required_env("API_KEY"),
api_version=os.environ.get("API_VERSION", "v1"),
) as client:
result = await client.transcribe(
input_path,
lang=stt.Language.ArEn,
asr=stt.BatchTranscriptionModel.BayanArEn,
diarization=BatchDiarization.On,
save_result=True,
poll_interval=2.0,
timeout_seconds=300.0,
on_progress=lambda response: print("status:", response.status.value),
)
print(result.results.transcript if result.results else "")
output_path.write_text(
stt.Subtitles.from_response(result).to_vtt(),
encoding="utf-8",
)
if __name__ == "__main__":
asyncio.run(main())
شغله مع ملف إدخال ومسار خرج:
python batch_transcription.py meeting.wav meeting.vttيبلغ التشغيل الناجح عن تقدم المهمة، ويطبع النسخة النهائية، ويكتب إشارات WebVTT
النهائية في meeting.vtt.
سطح Batch المنشور
| السطح | عقد 0.18.0 |
|---|---|
| المُنشئ | BatchTranscribeClient(api_url, api_key, max_retries=0, api_version="v1") |
| الدوال غير المتزامنة | submit(), get_result(), transcribe(), close() |
| الدوال المتزامنة | submit_sync(), get_result_sync(), transcribe_sync(), close_sync() |
| الخيارات والقيم الافتراضية | submit: diarization, asr, itn, redact؛ get_result: save_result؛ transcribe: هذه الخيارات مع poll_interval=2 وtimeout_seconds=300 وon_progress وsave_result. الخيار max_retries متجاهل. |
| الإدخال | يقبل AudioInput الدفعي القيم الشبيهة بالبايت، ومسار Path أو سلسلة، والقراء المخزنين، وBytesIO. |
ينجح transcribe() عند done، ويرفع خطأً عند failed، ويواصل الاستعلام عن
queued أوprocessing أوcleared حتى مهلته. إذا كان العامل يملك حلقة
الاستعلام، فتوقف صراحة عند الحالات الطرفية الثلاث: done وfailed وcleared.
قد تمسح القيمة الافتراضية save_result=False نتيجة done أو failed بعد
بناء الاستجابة. مرر save_result=True قبل الاستعلام عندما يجب أن يتحمل تسليم
النتيجة النهائية فقد استجابة. لا ينشئ ذلك مدة احتفاظ بالنتيجة.
استخدم العميل كمدير سياق غير متزامن أو عادي. يغلق خروج السياق جلسة aiohttp
الداخلية. تفهرس أقسام المرجع أدناه أنواع نتائج Batch والترجمات.
اختر مهمة أخرى
| المدخل والهدف | العميل | إشارة الاكتمال |
|---|---|---|
| تسجيل مكتمل أو اجتماع طويل أو بودكاست أو مقابلة أو وسائط أرشيف | BatchTranscribeClient | تصل المهمة إلى done أوfailed أوcleared |
| وحدة صوتية مكتملة وحساسة لزمن الاستجابة، مثل دور محادثة واحد لوكيل ذكاء اصطناعي | FastTranscriptionClient | تحمل الاستجابة النهائية is_final=True |
| صوت ما زال يصل من ميكروفون أو مكالمة أو مصدر مباشر | RealtimeClient | تحمل استجابة البروتوكول is_final=True |
| تقسيم مباشر للمتحدثين | RealtimeDiarizationClient | يصل التحديث النهائي أو يعيد الإغلاق أفضل خط زمني معروف |
| تحويل النص إلى كلام مولّد | TTSClient | تحمل استجابة الصوت is_last=True |
النسخ السريع ليس مسار الاجتماعات الطويلة أو البودكاست أو وسائط الأرشيف. استخدم Batch لهذه التسجيلات الأطول والمكتملة.
مهمة سريعة: انسخ وحدة محادثة مكتملة
استخدم FastTranscriptionClient بعد اكتمال وحدة صوتية محدودة وحساسة لزمن
الاستجابة، مثل دور مستخدم واحد في محادثة مع وكيل ذكاء اصطناعي. يرسل الوحدة
كاملة عبر Socket.IO؛ ولا يقبل تدفق ميكروفون مفتوح النهاية.
سطح Fast المنشور
| السطح | عقد 0.18.0 |
|---|---|
| المُنشئ | FastTranscriptionClient(api_url, api_key, api_path=None, on_connect?, on_file_upload?, on_error?, verbose=False)؛ ويبقى ترتيب ما قبل 0.17 (api_url, api_path, api_key, ...) مدعومًا مع تحذير إهمال |
| الدوال غير المتزامنة | connect(), transcribe(), close() |
| الدوال المتزامنة | transcribe_sync(), close_sync()؛ لا توجد connect_sync() |
| الخيارات والقيم الافتراضية | يقبل transcribe(audio, language, model, …) القيم on_response وon_file_upload وon_error وtimeout_seconds=60 وdiarization_model وitn_model وredact_model. |
| الإدخال | bytes أو قارئ مخزن؛ يجب فتح المسار أو قراءته أولًا. |
يبلغ هذا البرنامج المختبر عن تقدم الرفع، ويميز النص الجزئي والنهائي، ويتطلب نتيجة نهائية، ويكتب SRT:
from __future__ import annotations
import asyncio
import os
import sys
from pathlib import Path
from humain_voice import stt
def required_env(name: str) -> str:
value = os.environ.get(name)
if not value:
raise RuntimeError(f"{name} is required")
return value
def handle_response(response: stt.FtTranscribeResponse) -> None:
kind = "final" if response.is_final else "partial"
print(f"{kind}:", response.transcription)
def handle_upload(response: stt.FileUploadedResponse) -> None:
print("uploaded:", response.id)
def handle_error(error: stt.ErrorResponse | None) -> None:
if error is not None:
print("server error:", error.code, error.message)
async def main() -> None:
input_path = Path(sys.argv[1] if len(sys.argv) > 1 else "short-call.wav")
output_path = Path(sys.argv[2] if len(sys.argv) > 2 else "short-call.srt")
async with stt.FastTranscriptionClient(
api_url=required_env("API_URL"),
api_path=required_env("API_PATH"),
api_key=required_env("API_KEY"),
) as client:
result = await client.transcribe(
input_path.read_bytes(),
stt.Language.Ar,
stt.FastTranscriptionModel.BayanAr,
on_response=handle_response,
on_file_upload=handle_upload,
on_error=handle_error,
timeout_seconds=60.0,
)
if result is None:
raise RuntimeError("Fast transcription ended without a final result")
output_path.write_text(
stt.Subtitles.from_response(result).to_srt(),
encoding="utf-8",
)
if __name__ == "__main__":
asyncio.run(main())
يحدد FileUploadedResponse عملية الرفع. تتلقى الاستدعاءات الجزئية والنهائية
FtTranscribeResponse؛ وتحمل الاستجابة النهائية المعادة is_final=True ويمكنها
إنشاء الترجمات. المهلة الافتراضية في Python هي 60 ثانية.
يقبل SDK 0.18.0 القيم diarization_model وitn_model وredact_model
للتوافق مع البروتوكول، لكن خدمة Fast العامة المتحقق منها لا تطبقها. احذفها،
واستخدم Batch عندما تحتاج إلى خيارات المعالجة هذه.
لا تعد إرسال الوحدة الصوتية بلا تمييز بعد مهلة غامضة؛ لا يوجد عقد منشور لمفتاح idempotency. استخدم مدير سياق العميل كي تغلق موارد Socket.IO وHTTP الداخلية في كل المسارات.
مهمة فورية: انسخ الصوت عند وصوله
استخدم RealtimeClient لصوت ميكروفون أو مكالمة أو صوت آخر ما زال يصل. يجب أن
يكون الإدخال PCM16 little-endian بتردد 16 kHz وأحادي القناة.
سطح Realtime المنشور
| السطح | عقد 0.18.0 |
|---|---|
| المُنشئ | RealtimeClient(api_url, api_key, api_path=None, verbose=False) |
| الدوال غير المتزامنة | connect(), start_stream(), disconnect() |
| الدوال المتزامنة | start_stream_sync()؛ دوال التدفق send_sync() وclose_sync() وstop_sync() عامة، لكن connect_sync() وdisconnect_sync() ليستا كذلك |
| خيارات البدء | language, on_connect, on_disconnect, on_response, on_error, subtitles |
| التدفق | send() / send_sync()؛ يرسل close(timeout_seconds=1) / close_sync() النهاية وينتظر؛ يزيل stop() / stop_sync() التدفق من دون الانتظار النهائي. |
يرسل هذا البرنامج مقاطع حجمها 3,200 بايت، تمثل 100 ms من الصوت المطلوب، ويغلق العميل عبر مدير السياق غير المتزامن:
from __future__ import annotations
import asyncio
import os
import sys
from pathlib import Path
from humain_voice import stt
CHUNK_BYTES = 3_200 # 100 ms of PCM16LE, 16 kHz, mono audio.
def required_env(name: str) -> str:
value = os.environ.get(name)
if not value:
raise RuntimeError(f"{name} is required")
return value
async def main() -> None:
input_path = Path(sys.argv[1] if len(sys.argv) > 1 else "speech.pcm")
output_path = Path(sys.argv[2] if len(sys.argv) > 2 else "speech.vtt")
finalized_words: list[stt.WordSegment] = []
server_error: stt.ErrorResponse | None = None
protocol_final_observed = False
def handle_response(response: stt.RtTranscribeResponse) -> None:
nonlocal protocol_final_observed
if response.is_final:
kind = "final"
elif response.is_speech_final:
kind = "speech-final"
else:
kind = "partial"
print(f"{kind}:", response.transcription)
if response.is_final:
protocol_final_observed = True
if response.is_final or response.is_speech_final:
# The current public Realtime contract does not guarantee increasing
# seq values, so collect final words in arrival order instead of
# asking RealtimeSubtitles to deduplicate by id:seq.
finalized_words.extend(response.words)
def handle_error(error: stt.ErrorResponse | None) -> None:
# The released SDK can invoke a stream handler more than once for one
# routed error, so keep this callback idempotent.
nonlocal server_error
server_error = error
client = stt.RealtimeClient(
api_url=required_env("API_URL"),
api_path=required_env("API_PATH"),
api_key=required_env("API_KEY"),
)
async with client:
stream = await client.start_stream(
language=stt.Language.ArEn,
on_response=handle_response,
on_error=handle_error,
)
pcm = input_path.read_bytes()
for offset in range(0, len(pcm), CHUNK_BYTES):
await stream.send(pcm[offset : offset + CHUNK_BYTES])
await asyncio.sleep(0.1)
# close() sends the last frame and waits for protocol is_final, a routed
# error, or this timeout. It returns rather than raising on timeout.
await stream.close(timeout_seconds=5.0)
if server_error is not None:
raise RuntimeError(server_error.message or server_error.code or "Realtime stream failed")
if not protocol_final_observed:
raise RuntimeError("Realtime stream ended before protocol is_final")
output_path.write_text(
stt.Subtitles.from_words(finalized_words).to_vtt(),
encoding="utf-8",
)
if __name__ == "__main__":
asyncio.run(main())
يضيف RtTranscribeResponse الحقل is_speech_final إلى حقول استجابة Fast.
عامله بوصفه نهاية مقطع كلام، واستبدل نص واجهة الاستخدام المؤقت، وأبقِ التدفق
مفتوحًا حتى is_final على مستوى البروتوكول.
يرسل stream.close(timeout_seconds=...) الإطار النهائي ويعود عند انتهاء انتظار
is_final على مستوى البروتوكول. لا يضمن الرجوع وصول is_final؛ ولا تنهي
is_speech_final ذلك الانتظار. يجمع المثال كلمات
الأحداث النهائية بترتيب الوصول ويعرضها باستخدام Subtitles؛ ولا يعتمد على
seq لأن ترتيبها وتفرّدها ليسا جزءًا من عقد السلك العام الحالي. يزيل
RealtimeSubtitles التكرار حسب id:seq وقد يدمج أحداثًا نهائية متميزة. يبقى
سياق العميل مطلوبًا لأن الخطأ الموجه قد يزيل سياق التدفق قبل تشغيل الإغلاق.
مهمة التمييز: تتبع المتحدثين مباشرة
استخدم RealtimeDiarizationClient عندما يحتاج التطبيق إلى خط زمني للمتحدثين
أثناء وصول الصوت. غذِّ واستهلك بالتزامن؛ قد يؤدي انتظار الاستهلاك حتى إرسال
الصوت كله إلى توقف المسار.
سطح التمييز المنشور
| السطح | عقد 0.18.0 |
|---|---|
| المُنشئ | RealtimeDiarizationClient(api_url, api_key, api_path=None, verbose=False) |
| الدوال غير المتزامنة | connect(), start_stream(), disconnect() |
| الدوال المتزامنة | start_stream_sync()؛ دالتا التدفق send_sync() وclose_sync() عامتان، لكن connect_sync() وdisconnect_sync() ليستا كذلك |
| خيارات البدء | language=Language.Ar، مع استدعاءات الاتصال والتحديث والخطأ |
| التدفق | stream_id, speakers, send() / send_sync(), close(timeout_seconds=5) / close_sync()، وإدارة سياق غير متزامنة، ومكرر غير متزامن واحد. يرفع فشل المكرر DiarizationStreamError. |
يُستورد DIARIZATION_RECOMMENDED_CHUNK_BYTES من
humain_voice.stt.constants، لا من مساحة stt العليا. يستقبل هذا البرنامج
التحديثات عبر on_update أثناء تغذية الصوت، كي لا تترك مهلة الإغلاق مكررًا
منتظرًا:
from __future__ import annotations
import asyncio
import os
import sys
from pathlib import Path
from humain_voice import stt
from humain_voice.stt.constants import DIARIZATION_RECOMMENDED_CHUNK_BYTES
def required_env(name: str) -> str:
value = os.environ.get(name)
if not value:
raise RuntimeError(f"{name} is required")
return value
async def main() -> None:
input_path = Path(sys.argv[1] if len(sys.argv) > 1 else "meeting.pcm")
output_path = Path(sys.argv[2] if len(sys.argv) > 2 else "meeting.rttm")
client = stt.RealtimeDiarizationClient(
api_url=required_env("API_URL"),
api_path=required_env("API_PATH"),
api_key=required_env("API_KEY"),
)
async with client:
final_observed = False
def on_update(update: stt.DiarizationUpdate) -> None:
nonlocal final_observed
final_observed = final_observed or update.is_final
for segment in update.newly_finalized:
print(segment.speaker, segment.start_time, segment.end_time)
stream = await client.start_stream(
on_update=on_update,
on_error=lambda error: print("server error:", error),
)
pcm = input_path.read_bytes()
if not pcm or len(pcm) % 2:
raise ValueError("Input must be nonempty PCM16 with an even byte length")
for offset in range(0, len(pcm), DIARIZATION_RECOMMENDED_CHUNK_BYTES):
await stream.send(
pcm[offset : offset + DIARIZATION_RECOMMENDED_CHUNK_BYTES]
)
await asyncio.sleep(0.48)
# close() returns the best-known reconciled timeline after five seconds,
# even when no is_final update arrived. A callback avoids leaving an async
# iterator waiting forever on that timeout path.
timeline = await stream.close(timeout_seconds=5.0)
destination = output_path if final_observed else Path(f"{output_path}.partial")
destination.write_text(stt.to_rttm(timeline, uri="meeting"), encoding="utf-8")
if not final_observed:
print(f"Final result not observed; wrote incomplete output to {destination}")
if __name__ == "__main__":
asyncio.run(main())
يعرض كل DiarizationUpdate خط segments الزمني الموفق كاملًا، و
newly_finalized وactive_segments والاستجابة الخام. ينتظر الإغلاق حتى خمس
ثوان لتحديث نهائي، ويعيد أفضل خط زمني معروف عند انتهاء الانتظار. يكتب المثال
ملف RTTM بلاحقة .partial ما لم يرصد is_final. يظل خروج السياق مالكًا لتنظيف
العميل.
مهمة TTS: اكتب ملف WAV قابلًا للتشغيل
استخدم TTSClient لاكتشاف صوت وتوليد صوت خام. لا تملك قائمة الأصوات أو
التوليف في Python مهلة ما لم تمرر timeout_seconds. تعيد list_voices()
قواميس هويات متعددة اللغات بالشكل { id, label, profile }. يحمل profile
بيانات speaker مشتركة وقائمة languages مفتوحة؛ مرر id الخاص بالهوية
نفسها في voice_id.
في هويات العربية/الإنجليزية الحالية، يختار أي حرف من محارف الكتابة العربية
في text النسخة العربية؛ وإلا تُختار الإنجليزية. تبقى معرّفات النسخ الفعلية
داخلية وتُرفض.
سطح TTS المنشور
| السطح | عقد 0.18.0 |
|---|---|
| المُنشئ | TTSClient(api_url, api_key, api_path=None, verbose=False, on_connect?, on_error?)؛ ويبقى ترتيب ما قبل 0.17 (api_url, api_path, api_key, ...) مدعومًا مع تحذير إهمال |
| الدوال غير المتزامنة | connect(), list_voices(), synthesize(), synthesize_stream(), close() |
| الدوال المتزامنة | list_voices_sync(), synthesize_sync(), close_sync()؛ لا توجد synthesize_stream_sync() أوconnect_sync() أوdisconnect_sync() |
| الخيارات والقيم الافتراضية | يتطلب التوليف نصًا يحتوي بعد إزالة الفراغات على حرف Unicode أو رقم واحد على الأقل، وواحدًا بالضبط من voice_id أوvoice_references غير الفارغة؛ model=TtsModel.Nebula؛ والخيارات timeout_seconds وon_audio للتوليف المخزن وon_error وrequest_id. |
| النتيجة | تعيد list_voices() قواميس تحمل id وlabel وprofile الاختياري؛ وتحمل استجابات التوليف id وis_last وaudio: bytes. |
يرفض هذا البرنامج قائمة أصوات فارغة، ويطبق مهلًا صريحة، ويغلف PCM المعاد في ترويسة WAV:
from __future__ import annotations
import asyncio
import os
import sys
import wave
from pathlib import Path
from humain_voice import stt, tts
def required_env(name: str) -> str:
value = os.environ.get(name)
if not value:
raise RuntimeError(f"{name} is required")
return value
def write_pcm16_wav(path: Path, pcm: bytes, sample_rate: int) -> None:
with wave.open(str(path), "wb") as wav_file:
wav_file.setnchannels(1)
wav_file.setsampwidth(2)
wav_file.setframerate(sample_rate)
wav_file.writeframes(pcm)
def handle_error(error: stt.ErrorResponse | None) -> None:
if error is not None:
print("server error:", error.code, error.message)
async def main() -> None:
output_path = Path(sys.argv[1] if len(sys.argv) > 1 else "speech.wav")
async with tts.TTSClient(
api_url=required_env("API_URL"),
api_path=required_env("API_PATH"),
api_key=required_env("API_KEY"),
) as client:
voices = await client.list_voices(timeout_seconds=5.0)
if not voices:
raise RuntimeError("No TTS voices are available")
voice = next((item for item in voices if item.get("profile")), voices[0])
if profile := voice.get("profile"):
print(
"profile:",
voice["label"],
profile["speaker"]["dialect"],
profile["languages"],
)
model = tts.TtsModel.Nebula
pcm = await client.synthesize(
"Hello from HUMAIN Voice",
voice_id=voice["id"],
model=model,
# This is an inactivity timeout applied while awaiting each chunk.
timeout_seconds=30.0,
on_error=handle_error,
)
write_pcm16_wav(output_path, pcm, tts.get_sample_rate(model))
if __name__ == "__main__":
asyncio.run(main())
يعيد TTS عبر Socket.IO بايتات PCM16 little-endian خام بتردد 24 kHz وأحادية
القناة. يستخدم المثال وحدة wave القياسية لكتابة الحاوية المطابقة. استخدم
synthesize_stream() عندما ينبغي للتطبيق معالجة كل مقطع صوتي.
بالنسبة إلى voice_references، أرسل مرجعًا واحدًا يكون audio فيه RIFF/WAVE
بترميز base64 القياسي ويحتوي بيانات PCM16 أحادية غير فارغة.
ويفرض الخادم بصورة مستقلة مهلة كلية غير قابلة لإعادة الضبط قدرها 25 ثانية
ومراقب خمول قدره 60 ثانية. إذا سبقت المهلة الكلية الإطار النهائي، يكون
TTS_DEADLINE_EXCEEDED قابلاً لإعادة المحاولة ويظل الصوت المستلم جزئيًا.
يتلقى استدعاء on_error كائن ErrorResponse مسوّى؛ تحتفظ الحمولات المنظمة
بـcode وretryable، وتصبح الحمولة القديمة غير الكائنية رسالة. يرفع كوروتين
التوليف المرفوض RuntimeError عامًا يحمل الرسالة فقط، لذلك احتفظ بتفاصيل
الاستدعاء قبل التنظيف. أغلق العميل دائمًا بمدير سياق.
مهمة إعادة المحاولة: اقرأ نتيجة Batch محفوظة
ينفذ SDK 0.18.0 استدعاء HTTP واحدًا لكل عملية Batch. max_retries مهمل
ومتجاهل. يضبط هذا المثال save_result=True ثم يعيد قراءة النتيجة المحفوظة
بتراجع محدود، ويستخدم الخاصيتين المنشورتين status_code وretry_after، ويسجل
السعة. من دون الحفظ، قد تتبع الاستجابة النهائية المفقودة حالة cleared؛ ولا
تُحدد مدة احتفاظ حتى عند تفعيل الحفظ.
from __future__ import annotations
import asyncio
import os
import random
import sys
from humain_voice import stt
from humain_voice.stt.batchtranscription import TranscriptionResponse
def required_env(name: str) -> str:
value = os.environ.get(name)
if not value:
raise RuntimeError(f"{name} is required")
return value
async def get_result_with_retry(
client: stt.BatchTranscribeClient,
job_id: str,
attempts: int = 5,
) -> TranscriptionResponse:
for attempt in range(1, attempts + 1):
try:
# save_result prevents a terminal read from clearing the stored
# result before a retry. It does not define a retention duration.
return await client.get_result(
job_id, stt.Language.ArEn, save_result=True
)
except stt.BatchTranscribeError as error:
rate_limited = isinstance(error, stt.BatchTranscribeRateLimitError)
retryable = rate_limited or error.retryable is True
print(
{
"status_code": error.status_code,
"code": error.code,
"capacity": error.capacity,
}
)
if not retryable or attempt == attempts:
raise
server_delay = 0
if isinstance(error, stt.BatchTranscribeRateLimitError):
server_delay = error.retry_after or 0
exponential_delay = 0.5 * 2 ** (attempt - 1)
await asyncio.sleep(max(server_delay, exponential_delay) + random.random() * 0.25)
raise RuntimeError("Retry loop exhausted")
async def main() -> None:
if len(sys.argv) < 2:
raise RuntimeError("Pass a batch job ID as the first argument")
async with stt.BatchTranscribeClient(
api_url=required_env("API_URL"),
api_key=required_env("API_KEY"),
) as client:
result = await get_result_with_retry(client, sys.argv[1])
print(result.status.value, result.results.transcript if result.results else "")
if __name__ == "__main__":
asyncio.run(main())
لا تستخدم هذه الحلقة نفسها بلا تمييز لإنشاء مهمة. إذا انتهت مهلة الرفع، فقد لا يعرف التطبيق ما إذا كانت المهمة قد أنشئت.
المرجع: أنواع النتائج والأخطاء
| النوع | الحقول والسلوك المنشوران |
|---|---|
JobResponse | job_id وstatus؛ يبقى اسم البروتوكول jobId |
TranscriptionResponse | status؛ والحقول الاختيارية results وapi_version وversion وmetadata وdiarization_segments وerror وerror_code؛ والخصائص job_id وfile_duration وis_complete وis_failed وis_pending؛ وsubtitles() |
FileUploadedResponse / FtTranscribeResponse | الرفع: id وmessage اختياري. نتيجة Fast: id وseq وtranscription وwords وis_final، مع subtitles(). |
RtTranscribeResponse | حقول Fast مع is_speech_final الذي يحدد نهاية مقطع كلام؛ ولا ينهي التدفق إلا is_final |
DiarizationUpdate | id وsegments الموفقة وnewly_finalized وactive_segments وis_final وraw |
SpeakerContext / VoiceProfile / VoiceInfo | { gender, dialect }؛ و{ speaker, languages }؛ و{ id, label, profile? }. توفر الواجهة الحالية profile دائمًا. |
VoiceReference / TtsAudioResponse | { text, audio } مع صوت base64؛ وid وis_last وaudio: bytes. الحقلان voice_id وvoice_references متنافيان. |
ErrorResponse | الحقول الاختيارية id وmessage وcode وretryable وtimestamp وretry_after_seconds وdata وreason وretry_scope؛ وتصبح أخطاء Socket.IO القديمة غير الكائنية رسالة |
| استثناءات Batch | يعرض BatchTranscribeError القيم status_code وpayload وcode وretryable وjob_id وdetail وtimestamp وcapacity وraw_body؛ وفئاته BatchTranscribeAuthError وBatchTranscribeTimeoutError (elapsed_seconds) وBatchTranscribeJobFailedError (error، error_code) وBatchTranscribeRateLimitError (retry_after). |
| مسارات فشل Socket.IO | تستدعي أخطاء Fast الموجهة on_error ثم ترفع RuntimeError يحمل الرسالة فقط؛ ويشير Realtime إلى استدعائه وانتظاره النهائي؛ ويرفع مكرر التمييز DiarizationStreamError؛ وتحافظ أخطاء TTS الموجهة على الاستدعاء المنظم لكن التوليف يرفع RuntimeError يحمل الرسالة فقط. قد يصل الخطأ غير القابل للتوجيه إلى الاستدعاء العام فقط، لذلك احتفظ بمهلة للتطبيق ونظف دائمًا. |
المرجع: الاستيرادات وثوابت الأحداث
يصدر BatchDiarization وBatchRedact وAudioInput الدفعي وأنواع استجابة
Batch من humain_voice.stt.batchtranscription، لا من مساحة
humain_voice.stt العليا. يتوفر BatchTranscriptionModel عبر stt.
يصدر TTS القيم TtsModel وDEFAULT_SAMPLE_RATE وMODEL_SAMPLE_RATES و
get_sample_rate() وdecode_tts_audio_frame().
| مسار الاستيراد | ثوابت الأحداث العامة وقيم البروتوكول |
|---|---|
humain_voice.stt.constants | EVENT_FT_ERROR="error", EVENT_FT_TRANSCRIBE_FILE="audio_file", EVENT_FT_TRANSCRIBE_FILE_UPLOAD_SUCCESS="audio_file_upload_success", EVENT_FT_TRANSCRIBE_RESULT="transcription_result" |
humain_voice.stt.constants | EVENT_RT_AUDIO_STREAM="audio_stream", EVENT_RT_END_AUDIO_STREAM="end_audio_stream" |
humain_voice.stt.constants | EVENT_DIARIZATION_STREAM="diarization_stream", EVENT_DIARIZATION_RESULT="diarization_result" |
humain_voice.tts | EVENT_TTS_REQUEST="tts", EVENT_TTS_AUDIO="tts_audio", EVENT_TTS_ERROR="error", EVENT_TTS_VOICE_LIST_REQUEST="tts_voice_list", EVENT_TTS_VOICE_LIST_RESULT="tts_voice_list_result" |
تصدّر humain_voice.errors ثوابت رموز الخطأ الكبيرة نفسها المدرجة في دليل
JavaScript. كما تصدّر is_asr_code() وis_tts_code() و
is_request_scoped_code() وis_realtime_owned() وis_tts_owned() و
is_diarization_code() وis_diarization_owned() لتوجيه أخطاء Socket.IO
المنظمة. لا تعيد مساحة humain_voice.stt العليا تصدير ثوابت أحداث STT.
المرجع: مساعدات الترجمات
| API | عقد 0.18.0 |
|---|---|
Subtitles | الأنواع SubtitleCue وSubtitleOptions وSubtitleError؛ المُنشئ وcues؛ وfrom_words وfrom_cues وfrom_response؛ وto_srt وto_vtt |
RealtimeSubtitles | words وcues وadd_response وsubtitles وto_srt وto_vtt؛ يتجاهل المؤقت ويزيل تكرار استجابات id:seq النهائية |
| المساعدات العليا | words_to_cues وcues_to_srt وcues_to_vtt وsubtitles وto_srt وto_vtt |
| قيم التشكيل الافتراضية | max_duration_seconds=6، وmax_gap_seconds=0.7، وmin_duration_seconds=0.5، وmax_chars_per_line=42، وmax_lines=2، وsplit_on_speaker_change=True، وstrict=False؛ وstart_index=1 في SRT |
يقبل دخل الترجمات إزاحات كلمات Batch ومقاطع كلمات Realtime. فعّل الوضع الصارم عندما يجب أن يفشل التوقيت غير الصالح أو غير المرتب بدل تسويته أو تخطيه.
الخطوات التالية
مسار Batch للإنتاج
امتلك استعلام الحالة الطرفية وإعادة قراءة النتائج المحفوظة وتسوية المتحدثين والترجمات.
مسار Realtime للإنتاج
حضّر PCM واستبدل النص المؤقت واحتفظ بالترجمات النهائية ونظف التدفقات.
مسار TTS إلى WAV
تعامل مع اكتشاف الأصوات وجمع PCM وترويسات الخرج والمهل والتنظيف.
الأخطاء وحدود المعدل
صنف حالات الفشل المنظمة واحفظ نتيجة Batch قبل إعادة قراءتها.