This article focuses on the last two categories: TaskHandle polling for asynchronous tasks and the details, pitfalls, and cross-language differences of chat streaming responses.
I. TaskHandle — Unified Abstraction for Asynchronous Tasks
All three SDKs encapsulate asynchronous tasks intoTaskHandle, providing the same four methods:
Two Calling Methods for Creating Tasks
Each asynchronous resource (images.generate / video.generate / audio.generate) has a wait parameter:
wait=False(default): Immediately returnsTaskHandle, business code decides when to poll.wait=True: The SDK internally callshandle.wait(), returning the response after completion. Only use this when you are sure the target API will return thestatus: succeededfield—a few providers do not adhere to this convention, causingwaitto keep polling untilmax_waitthrows aTimeoutError.
Unit Differences (⚠️ Must Read)
The units ofpoll_interval and max_wait differ across the three languages, which is a common pitfall during cross-language migration:
Treating TS’s{ pollInterval: 3000 }as seconds and translating it to Pythonpoll_interval=3000will cause the SDK to wait 50 minutes before polling a second time.
Example: Python Explicit Polling for Midjourney
images.generate(..., wait=False)submits thepromptto the Midjourney API, immediately obtaining thehandlewithout blocking.handle.wait(poll_interval=3.0, max_wait=180.0)internally POSTs to/midjourney/tasksevery 3 seconds untilstatuschanges tosucceededorfailed, or the total time exceeds 180 seconds, throwing aTimeoutError.- After completion,
result["response"]["data"]usually contains 4 images (Midjourney defaults to a 2x2 grid).
Example: TypeScript Explicit Polling
Trade-offs Between Synchronous Generation and Asynchronous Tasks
If your provider itself generates images synchronously (NanoBanana / Flux / Seedream), do not passwait:
task_id + /tasks pair, it is synchronous generation; the response of synchronous generation already contains the final result in the data field.
Internal Protocol of TaskHandle
TheTaskHandle.get() call is:
response wrapper—it directly reads the top-level status, so switching between old and new responses does not affect business code.
II. SSE Streaming Response (chat.completions)
chat.completions.create(stream=True) is currently the only streaming interface in the SDK (audio/video streams are not yet supported). The iterative styles of the three languages are native to each:
TypeScript
Python
Go
Structure of Stream Chunks
Each chunk is an OpenAI compatiblechat.completion.chunk:
- The first chunk usually carries
delta.role: "assistant"but has an emptycontent. - The middle chunks each carry
delta.content, which can be concatenated directly. - The last chunk has an empty
delta, andfinish_reasonisstop/length/content_filter.
Cancelling Midway
Tokens generated before cancellation are still billed — tokens generated before the cancellation moment will still be charged based on actual consumption.
III. Timeouts and Retries
The three SDKs share the same retry strategy:
To disable retries: pass
max_retries=0 / maxRetries: 0 / WithMaxRetries(0) when constructing the client.
Polling of asynchronous tasks (TaskHandle) is not affected by max_retries — its loop is business-level rather than HTTP-level, controlled by max_wait for total duration.
IV. Common Pitfalls
- Do not pass
waitfor synchronous providers: NanoBanana / Flux / Seedream are synchronously generated, forcingwait=Truewill make the SDK poll atasksinterface that will not update at all. - TaskHandle unit differences: Python is in seconds, TS is in milliseconds, make sure to convert when porting across languages.
wait=Truemay still result inTimeoutError: The response must meetstatus in ('succeeded','failed')to exit the loop; if the provider uses different field names, the business code must handlehandle.get()parsing itself.- Streaming cancellation: Tokens generated before cancellation have already been billed.
- Reuse client within the same process: The SDK has a built-in connection pool, frequently calling
new AceDataCloud()/AceDataCloud()will make TLS handshake a bottleneck.

