acedatacloud is the official Python SDK for Ace Data Cloud, encapsulating all services on api.acedata.cloud into typed methods such as client.openai.chat.completions.create(...), client.images.generate(...), client.search.google(...), etc., while providing both synchronous and asynchronous clients.
It is built on top of httpx, supporting SSE streaming, automatic retries, typed exceptions, and pydantic type validation.
Source code and package links:
- SDK repository: https://github.com/AceDataCloud/SDK
- PyPI: https://pypi.org/project/acedatacloud/
Installation
- The package version is
2026.4.26.1(CalVer, revised on April 26, 2026). AceDataCloudis the synchronous client, andAsyncAceDataCloudis the asyncio asynchronous client.- This SDK does not depend on
pydantic, and the response body uniformly returns adict. This is different fromopenai-python, so be careful during migration.
Prepare API Token
Refer to SDK Overview - Apply for API Token to obtain the token, thenexport it in the shell:
api_token; the SDK will automatically read the ACEDATACLOUD_API_TOKEN environment variable. If you already have ACEDATACLOUD_API_KEY stored in your environment (as per project repository convention), please explicitly pass it: AceDataCloud(api_token=os.environ["ACEDATACLOUD_API_KEY"]).
Example 1: chat.completions (Synchronous)
idis the response ID, which can be found in the Usage History.content ADC_PY_SDK_OKis the fixed identifier returned by the model.res["usage"]returns adict, not a pydantic model; a single call consumes approximately 24 tokens.
Example 2: chat.completions (SSE Streaming)
Whenstream=True, create returns a regular generator that yields a parsed chunk dict each time.
- The first frame delay is 2104 ms, and the subsequent 11 frames only took 7 ms to complete—once the service starts streaming, it can be consumed locally effortlessly.
- The chunk is a regular dict, and values can be safely accessed using
.get()according to the OpenAI SSE format. - In actual production, it is recommended to yield while pushing SSE to the frontend, with an overall first-frame delay close to 2 seconds.
Example 3: AsyncAceDataCloud (Asynchronous)
The API ofAsyncAceDataCloud is completely symmetrical to the synchronous version, except that all IO methods return coroutines. It is suitable for FastAPI / aiohttp / asyncio services.
- The asynchronous version and the synchronous version use the same HTTP path, but the connection pool implementation is different (
httpx.AsyncClient). - Explicitly
await client.close()when exiting to close the connection pool; in long-lived services, it only needs to be closed once before the process exits. - The single delay is similar to the synchronous version, and the advantages of asynchronous become apparent in concurrent scenarios—one event loop can handle dozens or hundreds of inflight requests simultaneously.
Example 4: images.generate (NanoBanana)
The NanoBanana API is a synchronous image generation service; do not passwait—the SDK call will wait for the service to return 200.
image_urlis a stable address on the CDN, which can be directly downloaded or embedded in a webpage.- Almost all of the 18.9 seconds were spent on model inference; the local SDK overhead was only a few milliseconds.
- For truly asynchronous tasks like Midjourney, Sora, Veo, and Suno, you need to use
wait=Trueor manuallyTaskHandle.wait()for polling, see SDK task polling and streaming response.
Example 5: Typed Error Handling
AuthenticationError (401), TokenMismatchError (token does not match the service), InsufficientBalanceError (insufficient balance), ResourceDisabledError (service disabled), ValidationError (400), RateLimitError (429), ModerationError (403 content review), APIError (catch-all), TimeoutError (timeout), TransportError (network layer).
Configuration Options
Thetimeoutof the Python SDK and thepoll_interval/max_waitof TaskHandle are both in seconds, while the TypeScript SDK uses milliseconds. Be particularly careful during cross-language migration. See SDK task polling and streaming response.
The SDK reads theACEDATACLOUD_API_TOKENenvironment variable by default; this article usesACEDATACLOUD_API_KEYin the example to align with other tutorials like Claude Code VS Code tutorial, requiringapi_token=os.environ["ACEDATACLOUD_API_KEY"]to be explicitly injected.

