{"record":{"id":"11dc10c947b07543","repo":"ruvnet/RuView","slug":"sensingclient-requires-the-websockets-package-i","errorCode":null,"errorMessage":"SensingClient requires the `websockets` package. Install with `pip install \"wifi-densepose[client]\"` to enable the client extras.","messagePattern":"SensingClient requires the `websockets` package\\. Install with `pip install \"wifi-densepose\\[client\\]\"` to enable the client extras\\.","errorType":"exception","errorClass":"ImportError","httpStatus":null,"severity":"error","filePath":"python/wifi_densepose/client/ws.py","lineNumber":221,"sourceCode":"    automation vs \"fail fast\" for a CLI tool that should exit).\n\n    Auth: pass ``token=`` to send ``Authorization: Bearer <token>`` on\n    the WS upgrade, for sensing-servers started with ``RUVIEW_API_TOKEN``\n    set. If ``token`` is omitted it defaults to the ``RUVIEW_API_TOKEN``\n    environment variable; when neither is set, no header is sent.\n    \"\"\"\n\n    def __init__(\n        self,\n        url: str,\n        *,\n        token: Optional[str] = None,\n        ping_interval: float = 20.0,\n        ping_timeout: float = 20.0,\n        max_size: int = 16 * 1024 * 1024,\n    ) -> None:\n        if not _WEBSOCKETS_AVAILABLE:\n            raise ImportError(\n                \"SensingClient requires the `websockets` package. Install with \"\n                \"`pip install \\\"wifi-densepose[client]\\\"` to enable the client extras.\"\n            )\n        self.url = url\n        # Bearer token for auth-enabled sensing-servers. Explicit\n        # constructor argument wins; otherwise fall back to the\n        # RUVIEW_API_TOKEN environment variable. An empty value (unset\n        # env, or \"\") means \"no auth\" — no Authorization header is sent.\n        self._token = token if token is not None else os.environ.get(TOKEN_ENV_VAR)\n        self._ping_interval = ping_interval\n        self._ping_timeout = ping_timeout\n        self._max_size = max_size\n        self._ws: Any = None  # websockets.WebSocketClientProtocol — typed Any to avoid import cost\n\n    async def __aenter__(self) -> \"SensingClient\":\n        connect_kwargs: dict[str, Any] = dict(\n            ping_interval=self._ping_interval,\n            ping_timeout=self._ping_timeout,","sourceCodeStart":203,"sourceCodeEnd":239,"githubUrl":"https://github.com/ruvnet/RuView/blob/4685618388a5e49fad5b3005806f3bdd6a7c25c3/python/wifi_densepose/client/ws.py#L203-L239","documentation":"SensingClient.__init__ raises ImportError when the optional `websockets` package is missing. The module-level import is guarded via _WEBSOCKETS_AVAILABLE so importing wifi_densepose.client.ws succeeds regardless; the failure is deferred to construction time with instructions to install the `client` extra.","triggerScenarios":"Constructing `SensingClient(\"ws://host:8765/ws/sensing\")` where the base wifi-densepose wheel is installed without the `[client]` extra and websockets (>=12) is absent.","commonSituations":"Slim production images; environments installed from a bare `pip install wifi-densepose`; dependency graphs that strip extras.","solutions":["Install the extra: pip install \"wifi-densepose[client]\"","Or install directly: pip install websockets (>=12; the client adapts to the 13/14 header-kwarg rename by signature inspection)","Add the extra to requirements so every environment and lockfile includes it"],"exampleFix":"# before\npip install wifi-densepose\n\n# after\npip install \"wifi-densepose[client]\"","handlingStrategy":"validation","validationCode":"import importlib.util\n\nif importlib.util.find_spec(\"websockets\") is None:\n    raise SystemExit(\n        \"websockets missing; run: pip install 'wifi-densepose[client]'\"\n    )\nfrom wifi_densepose.client import SensingClient","typeGuard":null,"tryCatchPattern":"try:\n    client = SensingClient(url)\nexcept ImportError as e:\n    log.warning(\"WS ingestion disabled: %s\", e)\n    client = None","preventionTips":["Depend on wifi-densepose[client] in every environment that touches SensingClient","Add a construction smoke test for SensingClient in CI","Keep one canonical requirements file for deployable images"],"tags":["python","websocket","optional-dependency","pip","extras"],"backgroundTag":null,"analyzedSha":"4685618388a5e49fad5b3005806f3bdd6a7c25c3","analyzedAt":"2026-08-16T06:09:40.886Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}