DashScope native SDK & async tasks
Alibaba Cloud Bailian (DashScope) Qwen models can be called via the OpenAI SDK like OpenAI (translation mode), or via the DashScope native SDK through the passthrough entry /v1/services/{*rest}. The native SDK needs just one variable changed:
pip install dashscope requestsimport dashscope
dashscope.base_http_api_url = "http://localhost:7890/v1" # point at the gateway
dashscope.api_key = "<your access key>"Passthrough vs translation: choosing a path
| Entry | Behavior | When to use |
|---|---|---|
/v1/services/{*rest} | Passthrough: body forwarded to DashScope as-is, no protocol conversion | DashScope native SDK, or DashScope-specific fields / async tasks |
/v1/chat/completions | Translation: OpenAI ↔ DashScope format | OpenAI SDK, calling Qwen as an OpenAI model |
/v3/{model}/{*rest} | identity passthrough (client protocol == target protocol) | when you need to bypass the /v1/services prefix |
Text generation
from dashscope import Generation
resp = Generation.call(
model="qwen3.8-max",
messages=[{"role": "user", "content": "Introduce yourself in one sentence"}],
)
print(resp.output.choices[0].message.content)Gotcha:
message.contentis an array. DashScope passthrough returnsoutput.choices[0].message.contentas an array ([{"text": "..."}]), not a string, and may also carryreasoning_content(the thinking process). Printing it as a string the way older docs do yields[{...}]. Extract the text withcontent[0]["text"]or"".join(p.get("text","") for p in content).
Image (synchronous API)
from dashscope.aigc.image_generation import ImageGeneration
resp = ImageGeneration.call(
model="wan2.6-image",
messages=[{"role": "user", "content": [{"text": "A cat swimming in an ocean of code, cyberpunk style"}]}],
)
# The synchronous API returns in one shot; the image is in message.content
print(resp.output.choices[0].message.content)Video (async task)
Video generation is a two-stage "submit task → poll result" flow. The SDK's fetch polling path differs from the gateway's task-query path (/v1/services/{model}/tasks/{task_id}), so raw HTTP is used to demonstrate the full flow:
import time, requests
BASE = "http://localhost:7890/v1/services"
H = {"Authorization": "Bearer <your access key>", "Content-Type": "application/json"}
# 1) Submit the async video task (the model must be configured with direct_path + async_mode,
# see the DashScope quick deploy)
r = requests.post(f"{BASE}/aigc/video-generation/video-synthesis", headers=H, json={
"model": "wanx2.1-t2v",
"input": {"prompt": "A cat swimming in an ocean of code, cyberpunk style"},
"parameters": {"size": "1280*720"},
})
task_id = r.json()["output"]["task_id"]
# 2) Poll the task status and take the video URL on success
while True:
s = requests.get(f"{BASE}/wanx2.1-t2v/tasks/{task_id}", headers=H).json()
status = s["output"]["task_status"]
if status == "SUCCEEDED":
print(s["output"]["video_url"])
break
if status in ("FAILED", "CANCELED"):
raise RuntimeError(s)
time.sleep(5)Video model config (
direct_path+async_mode) — see Connect a DashScope upstream → Video generation. "Billing per second" only holds for models that declare aper_secondbilling mode;wanx2.1-t2vbills per your actual config, see Pricing & billing.
Embeddings / rerank / ASR
# Embeddings
from dashscope import TextEmbedding
r = TextEmbedding.call(model="text-embedding-v4", input="hello")
print(r.output["embeddings"][0]["embedding"])
# Rerank
from dashscope import Rerank
r = Rerank.call(model="gte-rerank", query="cat", documents=["a cat", "a car"])
print([x["relevance_score"] for x in r.output["results"]])Embeddings/rerank can also go over the OpenAI protocol (
/v1/embeddings,/v1/rerank) — the gateway interoperatesopenai_embeddings/openai_rerankwithdashscope. Either path works; see Protocol interop matrix.
Identity passthrough /v3/{model}/{*rest}
When the client protocol equals the model's configured target protocol, use /v3/{model}/{*rest} — the body is forwarded as-is, no conversion:
curl -X POST "http://localhost:7890/v3/qwen3.8-max/services/aigc/text-generation/generation" \
-H "Authorization: Bearer <your access key>" \
-H "Content-Type: application/json" \
-d '{"model":"qwen3.8-max","input":{"messages":[{"role":"user","content":"hi"}]},"parameters":{"result_format":"message"}}'Next
- Full upstream config steps and kind variants: see Connect a DashScope upstream.
- DashScope realtime models (
dashscope_realtime) via/v1/realtime: see Realtime & audio.
