Uh oh!
There was an error while loading. Please reload this page.
feat(transcriber): add AsyncTranscriber for asyncio callers - #224
Open
he-james wants to merge 2 commits into
Open
feat(transcriber): add AsyncTranscriber for asyncio callers#224he-james wants to merge 2 commits into
he-james wants to merge 2 commits into
Conversation
Closes#80. `Transcriber.transcribe_async` returns a `concurrent.futures.Future`. That future is not awaitable, and `.result()` blocks the event loop. An asyncio caller must therefore use a thread pool. The hardware limits the thread count. `AsyncTranscriber` provides the same API as `Transcriber`, with coroutines. It takes the same `TranscriptionConfig`. Its result has the same fields. It needs one thread. - `AsyncClient` wraps an `httpx.AsyncClient`. There is no process-wide default instance. An `httpx.AsyncClient` pool belongs to the event loop that first used it. A global pool therefore fails on a second `asyncio.run()`. - `async_api` provides an asyncio version of each transcript request function in `api`. - `AsyncTranscript` has the same fields as `Transcript`. Only the methods that call the API are coroutines. - The transcriber provides `get_by_id` and `delete_by_id`, because the async transcript needs the transcriber's pool. - An upload sends a path or a file object in chunks. A worker thread reads each chunk. The request sets `Content-Length` when the size is known. - `transcribe_group` and `submit_group` keep the input order. Both limit concurrent work to `max_concurrency`. Both report every error. The sync group methods discard errors when `return_failures` is not set. - LeMUR remains synchronous only. `LemurSource` now accepts an `AsyncTranscript`. Tests: 38 new unit tests in `tests/unit/test_async_transcriber.py`. They pass under the pydantic v1-compat path and under pydantic v2. `pytest tests/unit` gives 420 passed, 3 failed. The 3 failures need `pyaudio` and also fail on master. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The `py311-httpx0.22` and `py311-httpx0.24` tox envs pin httpx below 0.25. pip then resolves pytest-httpx back to 0.20 or 0.24, because the current pytest-httpx requires httpx 0.28. Nine tests used APIs that those versions do not have. The SDK code is correct on every pinned httpx version. Two causes, two fixes: - `add_response(is_reusable=True)` does not exist before pytest-httpx 0.31, and `add_callback` runs the callback synchronously before 0.25. An async callback therefore returns a coroutine as the response. The 5 group tests now stub `async_api.create_transcript` instead. The group methods only orchestrate `submit`, so a stub at the transport boundary tests the order, the concurrency limit, and the error collection. - `request.read()` returns an empty body for an async-iterator request under pytest-httpx 0.20. The 4 upload tests now assert the request headers only. 5 new tests call `_upload_request` directly and assert the streamed bytes. One new test covers a pipe, which cannot report a size. Tests: 43 tests in `tests/unit/test_async_transcriber.py`, up from 38. The full suite gives 425 passed, 3 failed on httpx 0.22, 0.24, and 0.28, and under both pydantic paths. The 3 failures need `pyaudio` and also fail on master. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
jchang-assemblyai
approved these changes
Aug 10, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Transcriber.transcribe_asyncreturns aconcurrent.futures.Future. That future is not awaitable, and.result()blocks the event loop. An asyncio caller must therefore use a thread pool, and the hardware limits the thread count.Updates
assemblyai/async_client.pyAsyncClientwraps anhttpx.AsyncClient.assemblyai/async_api.pyassemblyai/async_transcriber.pyAsyncTranscriberandAsyncTranscript.assemblyai/types.pyLemurSourcenow accepts anAsyncTranscript.assemblyai/__init__.pyAsyncTranscriber,AsyncTranscript,AsyncClient.README.md,CLAUDE.mdtests/unit/test_async_transcriber.pyNew functionality
AsyncTranscriber:transcribe,submit,transcribe_group,submit_group,get_by_id,delete_by_id,list_transcripts,upload_file,aclose, and the async context manager protocol.AsyncTranscript: the same fields asTranscript. Only the methods that call the API are coroutines.AsyncClient: anhttpx.AsyncClientpool. Share one pool between several transcribers.