datawhalechina/hello-agents · error · MovieServiceError

TMDB 未配置:请在 .env 设置 TMDB_ACCESS_TOKEN 或 TMDB_API_KEY

Error message

TMDB 未配置:请在 .env 设置 TMDB_ACCESS_TOKEN 或 TMDB_API_KEY

What it means

MovieServiceError (HTTP 503) raised inside _auth_headers_and_params when settings.resolve_tmdb_credentials() returns neither a Bearer access token nor an api_key. It is a configuration guard: the service knows it cannot authenticate any TMDB request, so it fails fast with a service-unavailable semantic instead of sending a doomed request.

Source

Thrown at Co-creation-projects/aatanxiao12-beep-YingQian/backend/app/services/movie_service.py:90

class MovieService:
    """TMDB 电影查询服务:search / discover / 类型名 id 映射。"""

    def __init__(self, settings: Optional[Settings] = None) -> None:
        """初始化配置、类型缓存占位,以及复用的 httpx 客户端。"""
        self.settings = settings or get_settings()
        self._genre_id_to_name: Optional[Dict[int, str]] = None
        self._genre_name_to_id: Optional[Dict[str, int]] = None
        self._client = httpx.Client(timeout=30.0)

    def close(self) -> None:
        """关闭底层 HTTP 客户端(进程退出或测试 teardown 时调用)。"""
        self._client.close()

    def _auth_headers_and_params(self) -> tuple[dict, dict]:
        """组装鉴权:优先 Bearer Access Token,否则 query 带 api_key。"""
        token, api_key = self.settings.resolve_tmdb_credentials()
        if not token and not api_key:
            raise MovieServiceError(
                "TMDB 未配置:请在 .env 设置 TMDB_ACCESS_TOKEN 或 TMDB_API_KEY",
                status_code=503,
            )

        headers: dict = {"Accept": "application/json"}
        params: dict = {
            "language": self.settings.tmdb_language,
            "include_adult": str(self.settings.tmdb_include_adult).lower(),
        }
        if token:
            headers["Authorization"] = f"Bearer {token}"
        else:
            params["api_key"] = api_key  # type: ignore[assignment]
        return headers, params

    def _get(self, path: str, extra_params: Optional[Dict[str, Any]] = None) -> dict:
        """对 TMDB 发 GET,统一处理超时、网络错误与非 2xx / 非 JSON。"""
        headers, params = self._auth_headers_and_params()

View on GitHub (pinned to 606a07d341)

Solutions

  1. Set TMDB_ACCESS_TOKEN (v4 Bearer token, preferred) or TMDB_API_KEY (v3 key) in backend/.env and confirm the settings module loads that exact file
  2. Verify with a quick check: python -c "from app.config import get_settings; print(get_settings().resolve_tmdb_credentials())" — should return a non-empty tuple
  3. For docker compose, add env_file: .env or explicit environment entries to the backend service
  4. Fail fast at startup: validate credentials in app lifespan and log a clear message instead of discovering it per-request

Example fix

# before
# .env (backend root)
# TMDB_ACCESS_TOKEN=

# after
# .env
TMDB_ACCESS_TOKEN=eyJhbGciOi...your_v4_read_access_token

# optional startup guard in main.py lifespan:
from .config import get_settings
from .services.movie_service import MovieServiceError

@asynccontextmanager
async def lifespan(app: FastAPI):
    token, key = get_settings().resolve_tmdb_credentials()
    if not token and not key:
        raise RuntimeError("TMDB 未配置:请在 .env 设置 TMDB_ACCESS_TOKEN 或 TMDB_API_KEY")
    yield
Defensive patterns

Strategy: validation

Validate before calling

from app.config import get_settings

def tmdb_configured() -> bool:
    token, key = get_settings().resolve_tmdb_credentials()
    return bool(token or key)

Try / catch

from app.services.movie_service import MovieServiceError

try:
    detail = service.get_detail(mid)
except MovieServiceError as e:
    if e.status_code == 503 and 'TMDB 未配置' in str(e):
        return degrade_to_no_metadata(mid)  # or a friendly setup notice
    raise

Prevention

When it happens

Trigger: Any MovieService call (get_detail, search, discover) when neither TMDB_ACCESS_TOKEN nor TMDB_API_KEY is present in the environment/.env loaded by pydantic-settings; .env exists but is not on the loaded path (wrong cwd, env_file misconfigured); variable set to an empty string, which resolve_tmdb_credentials treats as missing; keys defined only in the shell that started a different process (systemd unit, docker compose without env_file).

Common situations: Local dev works but container deployment lacks env passthrough; .env renamed or placed in backend/ vs repo root; CI test suite running without secrets; empty-string value left after commenting out a key.

Related errors


AI-assisted analysis of datawhalechina/hello-agents@606a07d341 (2026-08-14). Data as JSON: /api/errors/4ff327ac53895b89. Report an issue: GitHub.