حزم SDK

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 بجانب تسجيل الإدخال:

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:

fast_transcription.py
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 من الصوت المطلوب، ويغلق العميل عبر مدير السياق غير المتزامن:

realtime_transcription.py
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 أثناء تغذية الصوت، كي لا تترك مهلة الإغلاق مكررًا منتظرًا:

realtime_diarization.py
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:

tts_to_wav.py
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؛ ولا تُحدد مدة احتفاظ حتى عند تفعيل الحفظ.

batch_error_retry.py
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())

لا تستخدم هذه الحلقة نفسها بلا تمييز لإنشاء مهمة. إذا انتهت مهلة الرفع، فقد لا يعرف التطبيق ما إذا كانت المهمة قد أنشئت.

المرجع: أنواع النتائج والأخطاء

النوعالحقول والسلوك المنشوران
JobResponsejob_id وstatus؛ يبقى اسم البروتوكول jobId
TranscriptionResponsestatus؛ والحقول الاختيارية 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
DiarizationUpdateid و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.constantsEVENT_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.constantsEVENT_RT_AUDIO_STREAM="audio_stream", EVENT_RT_END_AUDIO_STREAM="end_audio_stream"
humain_voice.stt.constantsEVENT_DIARIZATION_STREAM="diarization_stream", EVENT_DIARIZATION_RESULT="diarization_result"
humain_voice.ttsEVENT_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
RealtimeSubtitleswords و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. فعّل الوضع الصارم عندما يجب أن يفشل التوقيت غير الصالح أو غير المرتب بدل تسويته أو تخطيه.

الخطوات التالية

في هذه الصفحة