HKUDS/DeepTutor · error · ImportError

dashscope SDK not installed. Run `pip install dashscope` (or

Error message

dashscope SDK not installed. Run `pip install dashscope` (or add to your project deps) to enable Aliyun DashScope.

What it means

The multimodal path of the DashScope adapter imports dashscope.MultiModalEmbedding lazily and converts ImportError into a helpful ImportError with install instructions. dashscope is an optional dependency, only required when actually using Aliyun DashScope multimodal embeddings.

Source

Thrown at deeptutor/services/embedding/adapters/dashscope_native.py:107

        params: Dict[str, Any] = {}
        dim_value = request.dimensions or self.dimensions
        if dim_value:
            params["dimension"] = dim_value
        return params

    async def embed(self, request: EmbeddingRequest) -> EmbeddingResponse:
        model_name = request.model or self.model
        if is_dashscope_multimodal_embedding_model(model_name):
            return await self._embed_multimodal(request, model_name)
        return await self._embed_text(request, model_name)

    async def _embed_multimodal(
        self, request: EmbeddingRequest, model_name: str
    ) -> EmbeddingResponse:
        try:
            from dashscope import MultiModalEmbedding
        except ImportError as exc:
            raise ImportError(
                "dashscope SDK not installed. Run `pip install dashscope` "
                "(or add to your project deps) to enable Aliyun DashScope."
            ) from exc

        contents = self._build_contents(request)
        parameters = self._build_parameters(request)

        logger.debug(
            "Calling dashscope.MultiModalEmbedding.call "
            f"(model={model_name}, items={len(contents)}, params={parameters})"
        )

        # SDK call is sync — run in worker thread to avoid blocking the loop.
        # IMPORTANT: the dashscope SDK takes a flat list for `input`
        # (e.g. ``input=[{"text": "..."}]``) and internally wraps it as
        # ``{"contents": [...]}`` before POSTing to the REST endpoint. Do NOT
        # pass ``{"contents": contents}`` here — that produces a double-wrap
        # and the API responds with HTTP 400 ("Input should be a valid list").

View on GitHub (pinned to 3e82f13042)

Solutions

  1. pip install dashscope (or add to project deps / the relevant extras group)
  2. Switch to a provider whose SDK is already installed if DashScope isn't actually needed

Example fix

# before
ImportError: dashscope SDK not installed...
# after
pip install dashscope
# requirements.txt: dashscope>=1.20
Defensive patterns

Strategy: validation

Validate before calling

try:
    import dashscope  # noqa: F401
    dashscope_ok = True
except ImportError:
    dashscope_ok = False

if request.contents and not dashscope_ok:
    raise ImportError("install dashscope before using multimodal embeddings")

Try / catch

try:
    await adapter.embed(req)
except ImportError as e:
    if "dashscope" in str(e):
        subprocess.check_call([sys.executable, "-m", "pip", "install", "dashscope"])
        return await adapter.embed(req)
    raise

Prevention

When it happens

Trigger: Configuring the dashscope embedding provider with contents in the request and calling embed() in an environment where the dashscope package is absent.

Common situations: Slim deployment images excluding the optional extra; new envs provisioned from a trimmed requirements list; venvs created before the multimodal feature was enabled.

Related errors


AI-assisted analysis of HKUDS/DeepTutor@3e82f13042 (2026-08-27). Data as JSON: /api/errors/4406e46779ed0566. Report an issue: GitHub.