Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ The DashScope Python SDK is the official client for [Alibaba Cloud Model Studio
| Entry point | Module-level static classes: `Generation.call(...)` | A resource-style client: `client.chat.completions.create(...)` |
| One-liner | — | `dashscope.chat("qwen-plus", "Tell me a joke")` |
| Response | Raw dict-like; check `status_code == HTTPStatus.OK` | Typed object; read `resp.output_text`, `resp.usage.total_tokens` |
| Errors | Inspect `resp.code` / `resp.message` by hand | Typed `DashScopeError` exceptions raised by default |
| Errors | Inspect `resp.code` / `resp.message` by hand | Typed `DashScopeError` exceptions raised by default *(evolving)* |
| Streaming | Generator of raw frames | `ChatStream` with `.text_stream`, `.reasoning_stream`, `.get_final_message()` |
| Protocols | DashScope native + a separate compatible-mode entry | One client speaks `native`, `openai`, or `anthropic` via `protocol=` |
| Async | Separate `Aio*` classes | `dashscope.AsyncClient()` mirrors the whole sync surface |
Expand All @@ -26,13 +26,11 @@ The DashScope Python SDK is the official client for [Alibaba Cloud Model Studio
pip install -U dashscope
```

The base install covers SDK API calls and the `dashscope` CLI command. Python 3.9+ is required. Optional feature groups are available as extras:
The base install covers SDK API calls, the `dashscope` CLI command, Agentic RL fine-tuning and the local tokenizer. Python 3.9+ is required. One optional feature group remains:

| Extra | Provides | Install |
|-------|----------|---------|
| `acli` | Interactive AI assistant (DashScope SDK Expert) | `pip install "dashscope[acli]"` |
| `rl` | Agentic RL fine-tuning | `pip install "dashscope[rl]"` |
| `tokenizer` | Local tokenizer without downloads | `pip install "dashscope[tokenizer]"` |

To install from a source checkout:

Expand Down Expand Up @@ -191,6 +189,8 @@ By default each frame is incremental. Pass `incremental_output=False` to receive

### Errors

> **Still evolving.** The 2.0 typed error surface is under active development — new exception classes may be added and the API-error-code → exception mapping may be refined. Catch the base `errors.DashScopeError` if you need to stay forward-compatible.

Failures raise a typed `DashScopeError` by default (both non-2xx HTTP statuses and HTTP-200-with-a-business-error land here):

```python
Expand Down
8 changes: 4 additions & 4 deletions README_zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ DashScope Python SDK 是[阿里云百炼(Model Studio)](https://help.aliyun.
| 入口 | 模块级静态类:`Generation.call(...)` | 资源风格客户端:`client.chat.completions.create(...)` |
| 一行调用 | —— | `dashscope.chat("qwen-plus", "讲个笑话")` |
| 响应 | 裸字典;需判断 `status_code == HTTPStatus.OK` | 类型化对象;直接读 `resp.output_text`、`resp.usage.total_tokens` |
| 错误 | 手动检查 `resp.code` / `resp.message` | 默认抛出类型化的 `DashScopeError` 异常 |
| 错误 | 手动检查 `resp.code` / `resp.message` | 默认抛出类型化的 `DashScopeError` 异常 *(完善中)* |
| 流式 | 裸帧生成器 | `ChatStream`,提供 `.text_stream`、`.reasoning_stream`、`.get_final_message()` |
| 协议 | DashScope 原生 + 单独的 compatible-mode 入口 | 一个客户端通过 `protocol=` 讲 `native`、`openai` 或 `anthropic` |
| 异步 | 独立的 `Aio*` 类 | `dashscope.AsyncClient()` 完整镜像同步接口 |
Expand All @@ -26,13 +26,11 @@ DashScope Python SDK 是[阿里云百炼(Model Studio)](https://help.aliyun.
pip install -U dashscope
```

基础安装包含 SDK API 调用和 `dashscope` CLI 命令,要求 Python 3.9+。可选功能组通过 extras 安装:
基础安装包含 SDK API 调用、`dashscope` CLI 命令、Agentic RL 微调和本地 tokenizer,要求 Python 3.9+。仅剩一个可选功能组:

| Extra | 提供的能力 | 安装命令 |
|-------|----------|---------|
| `acli` | 交互式 AI 助手(DashScope SDK Expert) | `pip install "dashscope[acli]"` |
| `rl` | Agentic RL 微调 | `pip install "dashscope[rl]"` |
| `tokenizer` | 本地 tokenizer(无需下载) | `pip install "dashscope[tokenizer]"` |

从源码安装:

Expand Down Expand Up @@ -191,6 +189,8 @@ for text in stream.text_stream: # 内容增量

### 错误

> **仍在完善中。** 2.0 的类型化错误体系正在持续开发 —— 可能新增异常类,API 错误码到异常类的映射也可能调整。若需要向前兼容,请捕获基类 `errors.DashScopeError`。

失败默认抛出类型化的 `DashScopeError`(非 2xx 的 HTTP 状态码,以及 HTTP 200 但业务报错,都会归入这里):

```python
Expand Down
8 changes: 4 additions & 4 deletions dashscope/cli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -489,13 +489,13 @@ def _register_rl_app():

def _rl_unavailable_detail(exception: Exception) -> str:
"""Render a deferred rl import failure as an actionable message."""
# The message quotes a literal 'dashscope[rl]'; unescaped, rich reads
# [rl] as a style tag and prints an install command with no extras.
# Unescaped, rich reads a bracketed run in the exception text as a style
# tag and drops it from the printed output.
detail = escape(str(exception))
if "pip install" not in detail:
detail += (
". Install the optional dependencies with: "
"[bold]pip install 'dashscope\\[rl]'[/bold]"
". Reinstall to pull in the missing dependencies: "
"[bold]pip install -U dashscope[/bold]"
)
return detail

Expand Down
4 changes: 2 additions & 2 deletions dashscope/finetune/reinforcement/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
import yaml # noqa: F401
except ImportError as _rl_dep_err:
raise ImportError(
"Agentic RL fine-tuning needs optional dependencies. "
"Install them with: pip install 'dashscope[rl]'",
"Agentic RL fine-tuning dependencies are missing from this "
"install. Reinstall with: pip install -U dashscope",
) from _rl_dep_err

from dashscope.finetune.reinforcement.common.constants import (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,12 +102,9 @@ def _run_with_span(
if tracer is None or not _OTEL_SPAN_API:
if is_tracing_enabled() and tracer is None:
logger.warning(
(
"ENABLE_TRAJECTORY is set but "
"OpenTelemetry is not "
"installed. "
"pip install 'dashscope[agentic_rl_tracing]'"
),
"ENABLE_TRAJECTORY is set but "
"OpenTelemetry is not installed. "
"Reinstall the SDK with: pip install -U dashscope",
)
return fn(self, input_data, *args, **kwargs)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
"""
OpenTelemetry tracing for rollout / reward processors.

Enable tracing (install OpenTelemetry, e.g.
``pip install 'dashscope[agentic_rl_tracing]'``):
OpenTelemetry ships with the SDK; enable tracing with:

- ``ENABLE_TRAJECTORY=true``

Expand Down Expand Up @@ -752,8 +751,8 @@ def trace_processor_process(
if not _OTEL_AVAILABLE:
logger.warning(
"ENABLE_TRAJECTORY is set but "
"OpenTelemetry is not installed. Install with: "
"pip install 'dashscope[agentic_rl_tracing]'",
"OpenTelemetry is not installed. Reinstall the SDK with: "
"pip install -U dashscope",
)
return processor.process(input_data)

Expand Down Expand Up @@ -796,8 +795,8 @@ async def async_trace_processor_process(
if not _OTEL_AVAILABLE:
logger.warning(
"ENABLE_TRAJECTORY is set but "
"OpenTelemetry is not installed. Install with: "
"pip install 'dashscope[agentic_rl_tracing]'",
"OpenTelemetry is not installed. Reinstall the SDK with: "
"pip install -U dashscope",
)
return await processor.process(input_data)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
- `trace_tool(...)`: tool instrumentation (one canonical shape)

Prerequisites (example):
pip install -e ".[agentic_rl_tracing]"
pip install -e .
pip install loongsuite-util-genai

Run:
Expand Down
2 changes: 1 addition & 1 deletion requirements-test.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ coverage
pydantic>=2.0,<3.0
tenacity
typing_extensions
# Optional extras exercised by tests/unit (cli, acli, rl)
# Optional extras exercised by tests/unit (cli, acli)
typer>=0.9.0
rich>=13.0.0
prompt-toolkit>=3.0
Expand Down
7 changes: 7 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,10 @@ rich>=13.0.0
httpx>=0.27.0
httpx-sse>=0.4.0
typing_extensions>=4.16.0
tiktoken
pydantic>=2.0
tenacity
PyYAML>=6.0
fastapi>=0.100
uvicorn>=0.20
opentelemetry-sdk>=1.20
10 changes: 0 additions & 10 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,6 @@ def run(self):
install_requires=get_dependencies(),
include_package_data=True,
extras_require={
"tokenizer": ["tiktoken"],
# Interactive AI assistant (dashscope.acli); typer/rich are core deps
"acli": [
"prompt-toolkit>=3.0",
Expand All @@ -124,15 +123,6 @@ def run(self):
"numpy>=1.20",
"opencv-python-headless>=4.5",
],
# Agentic RL fine-tuning (dashscope.finetune.reinforcement)
"rl": [
"pydantic>=2.0",
"tenacity",
"PyYAML>=6.0",
"fastapi>=0.100",
"uvicorn>=0.20",
"opentelemetry-sdk>=1.20",
],
},
zip_safe=False,
cmdclass=cmdclass,
Expand Down
31 changes: 17 additions & 14 deletions tests/unit/test_cli_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -267,15 +267,15 @@ def test_rl_import_failure_is_silent_until_the_command_is_used(
monkeypatch,
capsys,
):
# `rl` is an optional extra, so importing dashscope.cli must not tell
# The rl import is deferred, so importing dashscope.cli must not tell
# the user about a dependency they may never ask for.
monkeypatch.setattr(dashscope.cli, "_RL_IMPORT_ERROR", None)
monkeypatch.setitem(
sys.modules,
"dashscope.cli.agentic_rl",
_ImportErrorOnApp(
"Agentic RL fine-tuning needs optional dependencies. "
"Install them with: pip install 'dashscope[rl]'",
"Agentic RL fine-tuning dependencies are missing from this "
"install. Reinstall with: pip install -U dashscope",
),
)

Expand All @@ -284,16 +284,19 @@ def test_rl_import_failure_is_silent_until_the_command_is_used(
assert capsys.readouterr().err == ""
assert isinstance(dashscope.cli._RL_IMPORT_ERROR, ImportError)

def test_rl_command_keeps_the_extras_name(self, monkeypatch, capsys):
# rich reads a literal [rl] as a style tag and drops it, which used to
# print `pip install 'dashscope'` — a command that installs none of
# the extras the message is about.
def test_rl_command_prints_the_install_command_verbatim(
self,
monkeypatch,
capsys,
):
# The error already carries its own remedy, so the fallback hint in
# _rl_unavailable_detail must not be appended a second time.
monkeypatch.setattr(
dashscope.cli,
"_RL_IMPORT_ERROR",
ImportError(
"Agentic RL fine-tuning needs optional dependencies. "
"Install them with: pip install 'dashscope[rl]'",
"Agentic RL fine-tuning dependencies are missing from this "
"install. Reinstall with: pip install -U dashscope",
),
)
monkeypatch.setattr(sys, "argv", ["dashscope", "rl", "list"])
Expand All @@ -303,8 +306,8 @@ def test_rl_command_keeps_the_extras_name(self, monkeypatch, capsys):

assert exception_info.value.code == 1
err = " ".join(capsys.readouterr().err.split())
assert "pip install 'dashscope[rl]'" in err
assert err.count("Install") == 1
assert "pip install -U dashscope" in err
assert err.count("Reinstall") == 1

def test_rl_command_adds_a_hint_when_the_error_has_none(
self,
Expand All @@ -323,17 +326,17 @@ def test_rl_command_adds_a_hint_when_the_error_has_none(

err = " ".join(capsys.readouterr().err.split())
assert "No module named 'typer_x'" in err
assert "pip install 'dashscope[rl]'" in err
assert "pip install -U dashscope" in err

def test_unrelated_command_is_not_told_about_missing_rl_extras(
def test_unrelated_command_is_not_told_about_missing_rl_dependencies(
self,
monkeypatch,
capsys,
):
monkeypatch.setattr(
dashscope.cli,
"_RL_IMPORT_ERROR",
ImportError("pip install 'dashscope[rl]'"),
ImportError("Reinstall with: pip install -U dashscope"),
)
monkeypatch.setattr(sys, "argv", ["dashscope"])
monkeypatch.setattr(
Expand Down
Loading