ZhuLinsen/daily_stock_analysis · error · FutuPortfolioError

加载 Futu OpenAPI SDK 失败: {exc}

Error message

加载 Futu OpenAPI SDK 失败: {exc}

What it means

FutuPortfolioError raised at src/brokers/futu/portfolio.py:72 when the 'import futu' call fails with something other than ImportError — most commonly an exception thrown during the SDK's module-level initialization (the comment notes it initializes a file logger at import time). The original exception text is embedded so the root cause stays visible.

Source

Thrown at src/brokers/futu/portfolio.py:72

    try:
        from futu import (
            Market,
            OpenQuoteContext,
            OpenSecTradeContext,
            RET_OK,
            SecurityFirm,
            SecurityType,
            TrdEnv,
            TrdMarket,
        )
    except ImportError as exc:
        raise FutuPortfolioError(
            "未安装 Futu OpenAPI SDK;请先执行 "
            "`pip install \"futu-api==10.8.6808\"`。"
        ) from exc
    except Exception as exc:  # noqa: BLE001 - SDK import initializes its file logger
        raise FutuPortfolioError(f"加载 Futu OpenAPI SDK 失败: {exc}") from exc

    return _FutuApi(
        OpenQuoteContext=OpenQuoteContext,
        OpenSecTradeContext=OpenSecTradeContext,
        Market=Market,
        RET_OK=RET_OK,
        SecurityFirm=SecurityFirm,
        SecurityType=SecurityType,
        TrdEnv=TrdEnv,
        TrdMarket=TrdMarket,
    )


def _enum_text(value: Any) -> str:
    """Normalize SDK enum-like values for stable comparisons."""

    if value is None:
        return ""

View on GitHub (pinned to 5159bd72e8)

Solutions

  1. Reproduce the import standalone: python -c "import futu" — the traceback shows the underlying failure (logger path, permissions, missing transitive dep).
  2. Run the process from a writable working directory or grant write access to the futu log location so import-time logger initialization succeeds.
  3. Reinstall the SDK cleanly at the pinned version: pip install --force-reinstall "futu-api==10.8.6808" to repair a partially installed package.
  4. If a transitive dependency is the cause, install/upgrade that dependency per the traceback.

Example fix

# before: app crashes inside broker init with wrapped error

# after: pre-flight check with writable cwd
import os, subprocess, sys
os.makedirs("/tmp/futu-workdir", exist_ok=True)
os.chdir("/tmp/futu-workdir")
try:
    import futu  # noqa: F401
except Exception as exc:
    print(f"futu import failed: {exc}", file=sys.stderr)
    sys.exit(1)
Defensive patterns

Strategy: try-catch

Validate before calling

import os, tempfile

def futu_import_precheck() -> None:
    """futu-api initializes a file logger at import; ensure cwd is writable."""
    if not os.access(os.getcwd(), os.W_OK):
        os.chdir(tempfile.mkdtemp())
    import futu  # noqa: F401  (raises with real cause if broken)

Try / catch

try:
        import futu  # noqa: F401
    except Exception as exc:  # not just ImportError: init-time failures
        print(f'futu import failed: {exc!r}')
        raise

Prevention

When it happens

Trigger: Importing futu in an environment where its import-time logger setup fails: unwritable futu log directory (it writes under the CWD/futu-api path), permission-restricted container filesystem, locale/encoding problems, or a broken/partially-installed package whose submodule import raises RuntimeError/OSError.

Common situations: Running the app as a user without write permission to the directory where futu-api creates its logs; read-only Docker containers; half-completed pip installs; version mismatch where a transitive dependency of futu-api fails to import.

Related errors


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