Repository navigation
feat: CLI: Dynamic connector load - #407
Conversation
Signed-off-by: Ilya Boyandin <[email protected]>
Signed-off-by: Ilya Boyandin <[email protected]>
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds a modular DB bridge package (types, registry, factory, base connector, Postgres & Snowflake connectors, utils), removes the old monolithic Python db_bridge module, surfaces per-connector diagnostics in the runtime config, wires diagnostics into the frontend store, and adds a ConnectorDriversDialog UI that shows missing drivers and install commands. Changes
Sequence Diagram(s)sequenceDiagram
participant Browser as Browser/UI
participant UI as ConnectorDriversDialog
participant API as Launcher/API
participant Registry as DbBridgeRegistry
participant Connector as BridgeConnector
Browser->>API: GET /runtime-config
API->>Registry: runtime_diagnostics()
Registry->>Connector: dependency_diagnostics()
Connector-->>Registry: { id, engineId, title, available, error?, requiredPackages?, installCommands? }
Registry-->>API: diagnostics array
API-->>Browser: runtime config (includes dbBridge.diagnostics)
Browser->>UI: render diagnostics
UI->>Browser: display install commands & copy actions
Browser->>UI: click copy -> clipboard + toast
Estimated code review effort🎯 5 (Critical) | ⏱️ ~120 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment Tip CodeRabbit can enforce grammar and style rules using `languagetool`.Configure the |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
apps/sqlrooms-cli-ui/src/components/ConnectorDriversDialog.tsx (1)
11-15: Use selector-based store access instead of directruntimeConfigimport.At Line [11], this component reads config outside Zustand selector patterns, which can bypass reactive updates and guideline-required access patterns. Please source diagnostics via a selector/custom hook, then derive
missingConnectorsfrom that selected slice.As per coding guidelines,
**/*.{ts,tsx}: “Use Zustand selectors with memoization to avoid unnecessary re-renders …” and “Use custom Zustand selectors for accessing DuckDB store state … rather than direct connector access”.Also applies to: 72-78
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/sqlrooms-cli-ui/src/components/ConnectorDriversDialog.tsx` around lines 11 - 15, This component directly imports runtimeConfig and computes ConnectorDiagnostic/missingConnectors from it, bypassing Zustand selector patterns; replace direct runtimeConfig usage by creating/using a Zustand selector or custom hook (e.g., useRuntimeConfig or a selector like selectDbDiagnostics) to read the diagnostics slice reactively, then compute missingConnectors from that selected diagnostics value inside ConnectorDriversDialog (also update the logic around the existing missingConnectors usage at the section referenced around lines 72-78) so the component uses memoized selector access and re-renders correctly; reference runtimeConfig, ConnectorDiagnostic, and missingConnectors when locating the code to change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@python/sqlrooms-cli/sqlrooms/web/db_bridge/connectors/snowflake.py`:
- Around line 72-75: In dependency_diagnostics, guard the
importlib.util.find_spec call for "snowflake.connector" against parent-package
import errors by wrapping the lookup in a try/except ModuleNotFoundError (or
first checking find_spec("snowflake") and only then checking
"snowflake.connector"); on exception or missing spec return {"available": False,
"reason": "<exception message>"} (or similar) so dependency_diagnostics reports
availability instead of raising; update the dependency_diagnostics function to
catch ModuleNotFoundError and return a false/diagnostic dict referencing the
"snowflake.connector" lookup.
In `@python/sqlrooms-cli/sqlrooms/web/db_bridge/registry.py`:
- Around line 17-18: The register method on the registry currently overwrites an
existing connector silently (self._connectors[connector.connection_id] =
connector); change register (method register, type DbBridgeConnector and dict
_connectors) to detect duplicates and prevent silent overwrite by checking if
connector.connection_id already exists and raising a clear exception (e.g.,
ValueError) or returning an error, so callers must explicitly choose to replace
via a dedicated replace/update method if needed; update register to perform the
existence check and raise with a descriptive message referencing the duplicate
connection_id.
---
Nitpick comments:
In `@apps/sqlrooms-cli-ui/src/components/ConnectorDriversDialog.tsx`:
- Around line 11-15: This component directly imports runtimeConfig and computes
ConnectorDiagnostic/missingConnectors from it, bypassing Zustand selector
patterns; replace direct runtimeConfig usage by creating/using a Zustand
selector or custom hook (e.g., useRuntimeConfig or a selector like
selectDbDiagnostics) to read the diagnostics slice reactively, then compute
missingConnectors from that selected diagnostics value inside
ConnectorDriversDialog (also update the logic around the existing
missingConnectors usage at the section referenced around lines 72-78) so the
component uses memoized selector access and re-renders correctly; reference
runtimeConfig, ConnectorDiagnostic, and missingConnectors when locating the code
to change.
ℹ️ Review info
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (16)
apps/sqlrooms-cli-ui/src/components/ConnectorDriversDialog.tsxapps/sqlrooms-cli-ui/src/components/SheetsPanel.tsxapps/sqlrooms-cli-ui/src/runtimeConfig.tsapps/sqlrooms-cli-ui/src/store.tspython/sqlrooms-cli/sqlrooms/web/db_bridge.pypython/sqlrooms-cli/sqlrooms/web/db_bridge/__init__.pypython/sqlrooms-cli/sqlrooms/web/db_bridge/connectors/__init__.pypython/sqlrooms-cli/sqlrooms/web/db_bridge/connectors/postgres.pypython/sqlrooms-cli/sqlrooms/web/db_bridge/connectors/snowflake.pypython/sqlrooms-cli/sqlrooms/web/db_bridge/factory.pypython/sqlrooms-cli/sqlrooms/web/db_bridge/registry.pypython/sqlrooms-cli/sqlrooms/web/db_bridge/types.pypython/sqlrooms-cli/sqlrooms/web/db_bridge/utils.pypython/sqlrooms-cli/sqlrooms/web/launcher.pypython/sqlrooms-cli/tests/test_db_bridge.pypython/sqlrooms-cli/tests/test_launcher.py
💤 Files with no reviewable changes (1)
- python/sqlrooms-cli/sqlrooms/web/db_bridge.py
Signed-off-by: Ilya Boyandin <[email protected]>
Signed-off-by: Ilya Boyandin <[email protected]>
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (2)
python/sqlrooms-cli/sqlrooms/web/db_bridge/connectors/snowflake.py (1)
73-116: Consider extracting shared install commands to reduce duplication.The
installCommandsdict is duplicated between the exception handler (lines 85-96) and the unavailable case (lines 104-115). Consider extracting this to a constant or helper.♻️ Optional refactor to reduce duplication
+_SNOWFLAKE_UNAVAILABLE_DIAGNOSTICS = { + "available": False, + "error": "Missing Python dependency: snowflake-connector-python", + "requiredPackages": ["snowflake-connector-python>=4.3.0"], + "installCommands": { + "uvProject": "uv sync --extra snowflake", + "uvxRelaunch": ( + 'uvx --from "sqlrooms-cli[snowflake]" sqlrooms ' + "--db-path :memory:" + ), + "uvxWith": ( + 'uvx --from sqlrooms-cli --with ' + '"snowflake-connector-python>=4.3.0" ' + "sqlrooms --db-path :memory:" + ), + }, +} + def dependency_diagnostics(self) -> dict[str, Any]: try: available = importlib.util.find_spec("snowflake.connector") is not None except ModuleNotFoundError as exc: - return { - "available": False, - "reason": ( + return { + **_SNOWFLAKE_UNAVAILABLE_DIAGNOSTICS, + "reason": ( f"Failed to inspect dependency via " f"find_spec('snowflake.connector'): {exc}" ), - "error": "Missing Python dependency: snowflake-connector-python", - ... } if available: return {"available": True} - return { - "available": False, - ... - } + return dict(_SNOWFLAKE_UNAVAILABLE_DIAGNOSTICS)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@python/sqlrooms-cli/sqlrooms/web/db_bridge/connectors/snowflake.py` around lines 73 - 116, The duplicated installCommands dict in dependency_diagnostics should be extracted to a single constant or helper (e.g., SNOWFLAKE_INSTALL_COMMANDS or get_snowflake_install_commands()) and reused in both the ModuleNotFoundError return and the unavailable return; update dependency_diagnostics to reference that constant/helper instead of inlining the same dict twice and keep the other returned fields identical (available, error, requiredPackages) while reusing the shared install commands.apps/sqlrooms-cli-ui/src/store.ts (1)
150-155: Extract a shared diagnostics type to avoid schema drift.Line [150] defines a second inline diagnostics shape that already exists (richer) at Line [80]. Keeping both inline increases maintenance risk.
♻️ Proposed refactor
+type ConnectorDriverDiagnostic = { + id: string; + engineId: string; + title: string; + available: boolean; + error?: string; + reason?: string; + requiredPackages?: string[]; + installCommands?: { + uvProject?: string; + uvxRelaunch?: string; + uvxWith?: string; + }; +}; export type RoomState = RoomShellSliceState & AiSliceState & SqlEditorSliceState & AiSettingsSliceState & CellsSliceState & NotebookSliceState & CanvasSliceState & WebContainerSliceState & { - connectorDriverDiagnostics: Array<{ - id: string; - engineId: string; - title: string; - available: boolean; - error?: string; - reason?: string; - requiredPackages?: string[]; - installCommands?: { - uvProject?: string; - uvxRelaunch?: string; - uvxWith?: string; - }; - }>; + connectorDriverDiagnostics: ConnectorDriverDiagnostic[]; ... function getRuntimeBridgeConfig(): | { id: string; connections: Array<{ id: string; engineId: string; title: string; runtimeSupport?: 'browser' | 'server' | 'both'; requiresBridge?: boolean; bridgeId?: string; isCore?: boolean; }>; - diagnostics?: Array<{ - id: string; - engineId: string; - title: string; - available: boolean; - }>; + diagnostics?: ConnectorDriverDiagnostic[]; } | undefined {🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/sqlrooms-cli-ui/src/store.ts` around lines 150 - 155, Replace the duplicated inline diagnostics shape with the shared diagnostics type already declared earlier in this file: remove the inline definition under the diagnostics? property and reference the existing richer Diagnostics type (or the exact exported/interface name used above) so both places use the same type; update the diagnostics?: Array<...> usage to diagnostics?: Diagnostics[] (or the exact identifier) and remove the redundant inline shape to prevent schema drift.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@apps/sqlrooms-cli-ui/src/store.ts`:
- Around line 277-290: The diagnostics map currently keys only by id which can
collide across engines; update construction of diagnosticsById (from
bridgeConfig.diagnostics) to use a composite key combining item.id and
item.engineId (e.g., `${item.id}:${item.engineId}`) and change the lookup when
iterating bridgeConfig.connections to use the same composite key built from
connection.id and connection.engineId so diagnostics lookup matches per-engine
availability; keep the rest of the logic (e.g., skip when diagnostics.available
=== false) unchanged and reference diagnosticsById, bridgeConfig.diagnostics,
bridgeConfig.connections, connection.id, and connection.engineId when making the
change.
In `@python/sqlrooms-cli/sqlrooms/web/db_bridge/connectors/postgres.py`:
- Around line 63-64: Wrap the call to cur.fetchone() used for "SELECT
current_database()" with a defensive check: assign result = cur.fetchone(),
verify result is not None before indexing, and if it is None either raise a
clear exception or set current_db to a safe fallback (e.g. None or an explicit
error message) so the subsequent current_db = result[0] cannot raise a
TypeError; update the code around cur.execute("SELECT current_database()") and
the current_db assignment to perform this check and handle the None case
gracefully.
---
Nitpick comments:
In `@apps/sqlrooms-cli-ui/src/store.ts`:
- Around line 150-155: Replace the duplicated inline diagnostics shape with the
shared diagnostics type already declared earlier in this file: remove the inline
definition under the diagnostics? property and reference the existing richer
Diagnostics type (or the exact exported/interface name used above) so both
places use the same type; update the diagnostics?: Array<...> usage to
diagnostics?: Diagnostics[] (or the exact identifier) and remove the redundant
inline shape to prevent schema drift.
In `@python/sqlrooms-cli/sqlrooms/web/db_bridge/connectors/snowflake.py`:
- Around line 73-116: The duplicated installCommands dict in
dependency_diagnostics should be extracted to a single constant or helper (e.g.,
SNOWFLAKE_INSTALL_COMMANDS or get_snowflake_install_commands()) and reused in
both the ModuleNotFoundError return and the unavailable return; update
dependency_diagnostics to reference that constant/helper instead of inlining the
same dict twice and keep the other returned fields identical (available, error,
requiredPackages) while reusing the shared install commands.
ℹ️ Review info
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
apps/sqlrooms-cli-ui/src/components/ConnectorDriversDialog.tsxapps/sqlrooms-cli-ui/src/runtimeConfig.tsapps/sqlrooms-cli-ui/src/store.tspython/sqlrooms-cli/sqlrooms/web/db_bridge/connectors/base.pypython/sqlrooms-cli/sqlrooms/web/db_bridge/connectors/postgres.pypython/sqlrooms-cli/sqlrooms/web/db_bridge/connectors/snowflake.pypython/sqlrooms-cli/sqlrooms/web/db_bridge/registry.pypython/sqlrooms-cli/tests/test_db_bridge.py
🚧 Files skipped from review as they are similar to previous changes (3)
- apps/sqlrooms-cli-ui/src/runtimeConfig.ts
- apps/sqlrooms-cli-ui/src/components/ConnectorDriversDialog.tsx
- python/sqlrooms-cli/sqlrooms/web/db_bridge/registry.py
Signed-off-by: Ilya Boyandin <[email protected]>
Signed-off-by: Ilya Boyandin <[email protected]>
Signed-off-by: Ilya Boyandin <[email protected]>
There was a problem hiding this comment.
🧹 Nitpick comments (1)
apps/sqlrooms-cli-ui/src/components/ConnectorDriversDialog.tsx (1)
146-150: Consider pluralizing "Required package" when there are multiple packages.The label says "Required package:" but
requiredPackagesis an array that could contain multiple items.📝 Suggested fix
{!diagnostic.available && diagnostic.requiredPackages?.length ? ( <div className="mt-2 text-xs"> - Required package:{' '} + Required package{diagnostic.requiredPackages.length > 1 ? 's' : ''}:{' '} <code>{diagnostic.requiredPackages.join(', ')}</code> </div> ) : null}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/sqlrooms-cli-ui/src/components/ConnectorDriversDialog.tsx` around lines 146 - 150, The label "Required package:" should be pluralized when diagnostic.requiredPackages contains more than one item; update the JSX in ConnectorDriversDialog (the block rendering {!diagnostic.available && diagnostic.requiredPackages?.length}) to choose between "Required package:" and "Required packages:" based on diagnostic.requiredPackages.length (e.g., conditional string or ternary) while keeping the existing <code>{diagnostic.requiredPackages.join(', ')}</code> output.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@apps/sqlrooms-cli-ui/src/components/ConnectorDriversDialog.tsx`:
- Around line 146-150: The label "Required package:" should be pluralized when
diagnostic.requiredPackages contains more than one item; update the JSX in
ConnectorDriversDialog (the block rendering {!diagnostic.available &&
diagnostic.requiredPackages?.length}) to choose between "Required package:" and
"Required packages:" based on diagnostic.requiredPackages.length (e.g.,
conditional string or ternary) while keeping the existing
<code>{diagnostic.requiredPackages.join(', ')}</code> output.
ℹ️ Review info
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
AGENTS.mdapps/sqlrooms-cli-ui/src/components/ConnectorDriversDialog.tsxapps/sqlrooms-cli-ui/src/components/DataSourcesPanel.tsxapps/sqlrooms-cli-ui/src/components/SheetsPanel.tsx
✅ Files skipped from review due to trivial changes (1)
- AGENTS.md
Signed-off-by: Ilya Boyandin <[email protected]>
…ector-load Signed-off-by: Ilya Boyandin <[email protected]>
Signed-off-by: Ilya Boyandin <[email protected]>
Signed-off-by: Ilya Boyandin <[email protected]>
Signed-off-by: Ilya Boyandin <[email protected]>
Signed-off-by: Ilya Boyandin <[email protected]>
Signed-off-by: Ilya Boyandin <[email protected]>
Summary by CodeRabbit
New Features
New Integrations
Refactor
Tests
Documentation