ZhuLinsen/daily_stock_analysis · error · ValueError

TUSHARE_HTTP_URL 必须以 http:// 或 https:// 开头,当前值为 {url!r}

Error message

TUSHARE_HTTP_URL 必须以 http:// 或 https:// 开头,当前值为 {url!r}

What it means

ValueError raised while parsing the TUSHARE_HTTP_URL environment variable: if set, the value must start with http:// or https://. The guard exists because requests treats a bare hostname like 'api.tushare.pro' as a relative URL and fails confusingly later, so the fetcher fails fast at config-load time instead.

Source

Thrown at data_provider/tushare_fetcher.py:90

    return bool(re.match(r'^[A-Z]{1,5}(\.[A-Z])?$', code))


def _resolve_tushare_http_url() -> Optional[str]:
    """读取 ``TUSHARE_HTTP_URL`` 环境变量并做基本校验。

    - 留空 / 仅空白 / 未设置 → 返回 ``None``,调用方继续走官方默认地址。
    - 设置则去掉首尾空白后返回,并校验必须是 ``http://`` 或 ``https://`` 前缀,
      避免有人误填成纯主机名(如 ``api.tushare.pro``)导致 ``requests`` 把它
      当成相对路径请求失败。
    """
    raw = os.getenv("TUSHARE_HTTP_URL")
    if not raw:
        return None
    url = raw.strip()
    if not url:
        return None
    if not (url.startswith("http://") or url.startswith("https://")):
        raise ValueError(
            "TUSHARE_HTTP_URL 必须以 http:// 或 https:// 开头,"
            f"当前值为 {url!r}"
        )
    return url


class _TushareHttpClient:
    """Lightweight Tushare Pro client that does not require the tushare SDK."""

    def __init__(self, token: str, timeout: int = 30, api_url: str = "http://api.tushare.pro") -> None:
        self._token = token
        self._timeout = timeout
        self._api_url = api_url

    def query(self, api_name: str, fields: str = "", **kwargs) -> pd.DataFrame:
        req_params = {
            "api_name": api_name,
            "token": self._token,

View on GitHub (pinned to 5159bd72e8)

Solutions

  1. Edit .env / environment and prefix the value with http:// or https:// (e.g. https://api.tushare.pro).
  2. Leave TUSHARE_HTTP_URL unset or blank to use the official default endpoint.
  3. Add a config lint step or startup validation that scheme-checks all *_URL variables.

Example fix

# before
# .env
TUSHARE_HTTP_URL=api.tushare.pro   # ValueError

# after
# .env
TUSHARE_HTTP_URL=https://api.tushare.pro
# or simply remove the line to use the default
Defensive patterns

Strategy: validation

Validate before calling

import os

url = (os.getenv("TUSHARE_HTTP_URL") or "").strip()
if url and not url.startswith(("http://", "https://")):
    raise SystemExit(f"TUSHARE_HTTP_URL must start with http:// or https://, got {url!r}")

Try / catch

try:
    fetcher = TushareFetcher()
except ValueError as e:
    if "TUSHARE_HTTP_URL" in str(e):
        fix_and_restart("set TUSHARE_HTTP_URL=https://... or unset it")
    else:
        raise

Prevention

When it happens

Trigger: Setting TUSHARE_HTTP_URL to a hostname without scheme (e.g. TUSHARE_HTTP_URL=api.tushare.pro), with a typo like 'ttp://', or with leading whitespace plus a missing scheme; the error is raised the first time the env helper reads the variable.

Common situations: Copy-pasting a host:port into .env without the scheme; switching from a proxy hostname to URL and forgetting the prefix; CI secrets storing only the hostname.

Related errors


AI-assisted analysis of ZhuLinsen/daily_stock_analysis@5159bd72e8 (2026-08-15). Data as JSON: /api/errors/59d707c8a760490d. Report an issue: GitHub.