Repository navigation
feat: add Python cell worksheet blocks - #753
Conversation
|
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:
📝 WalkthroughWalkthroughIntroduces a new Changes
CLI UI app integration
Sequence Diagram(s)sequenceDiagram
participant WorksheetUI
participant PythonCellBlock
participant PythonCellSlice
participant PyodidePythonRuntimeAdapter
participant pyodideWorker
participant createCliPythonRuntimeHost
participant DuckDB
WorksheetUI->>PythonCellBlock: render (blockId, code, readOnly)
PythonCellBlock->>PythonCellSlice: runCell(cellId)
PythonCellSlice->>PyodidePythonRuntimeAdapter: execute(PythonExecutionRequest, host)
PyodidePythonRuntimeAdapter->>pyodideWorker: postMessage execute(executionId, code)
pyodideWorker->>pyodideWorker: loadPyodide, install _sqlrooms_bridge
pyodideWorker->>pyodideWorker: runPythonAsync(code)
pyodideWorker->>PyodidePythonRuntimeAdapter: postMessage hostRequest(sql, SharedArrayBuffer)
PyodidePythonRuntimeAdapter->>createCliPythonRuntimeHost: runReadonlySql(wrappedQuery)
createCliPythonRuntimeHost->>DuckDB: execute wrapped SQL
DuckDB-->>createCliPythonRuntimeHost: Arrow table
createCliPythonRuntimeHost-->>PyodidePythonRuntimeAdapter: {columns, rows, rowCount}
PyodidePythonRuntimeAdapter->>pyodideWorker: writeHostResponse(SharedArrayBuffer) + Atomics.notify
pyodideWorker->>PyodidePythonRuntimeAdapter: postMessage result(outputs, stdout, durationMs)
PyodidePythonRuntimeAdapter-->>PythonCellSlice: PythonExecutionResult
PythonCellSlice->>PythonCellSlice: boundOutput, persist lastResult
PythonCellSlice-->>PythonCellBlock: updated state (result, isRunning=false)
PythonCellBlock-->>WorksheetUI: render outputs (text/table/Vega-Lite/HTML)
Estimated code review effort🎯 5 (Critical) | ⏱️ ~120 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 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 |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 35d71fd489
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| private ensureWorker() { | ||
| if (this.worker) return this.worker; | ||
|
|
||
| const worker = new Worker(new URL('./pyodideWorker.ts', import.meta.url), { |
There was a problem hiding this comment.
Point the worker URL at the emitted JS file
When @sqlrooms/python-cell is built/published, tsc emits dist/pyodideWorker.js but does not rewrite this string, and package.json publishes only dist. Consumers that import the built package instead of the CLI app's source aliases will therefore resolve dist/pyodideWorker.ts, which is not present, so the Pyodide adapter fails when the first cell runs. Use the emitted .js worker URL or otherwise include/rewrite the worker asset for the package output.
Useful? React with 👍 / 👎.
| markdown: truncate(output.markdown, DEFAULT_MAX_STDIO_BYTES), | ||
| }; | ||
| } | ||
| return output; |
There was a problem hiding this comment.
Bound JSON results before persisting them
For cells that assign a large JSON-serializable result (for example a big list or table preview), this path returns the JSON output unchanged, and runCell then stores it in pythonCells.config.cells[cellId].lastResult. Unlike stdout, text, and markdown, JSON results have no size cap here, so one run can write megabytes into the persisted room state and make saves/reloads or rendering very slow. Please persist a bounded preview/summary for JSON outputs as well.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c2ed3c33e3
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| activeExecutionId = request.executionId; | ||
| try { | ||
| const lastExpressionResult = await pyodide.runPythonAsync(request.code, { | ||
| filename: `<sqlrooms-python-cell:${request.blockId}>`, |
There was a problem hiding this comment.
Bind declared inputs before running user code
When a cell is created with inputs through worksheet.add-python-cell-block or patchCell, the worker proceeds directly to runPythonAsync(request.code) without ever reading request.inputs; named literal, sql, tableRef, or schema inputs therefore are not bound in Python (and table/sql inputs are not fetched), so code that relies on the declared input API fails with NameError or has to bypass the API with manual queries. Please resolve and bind the declared inputs before executing the cell.
Useful? React with 👍 / 👎.
| const packageNames = new Set( | ||
| (request.requirements ?? []) | ||
| .filter((requirement) => requirement.source !== 'host') | ||
| .map((requirement) => requirement.name), | ||
| ); | ||
| if (usesSqlroomsBridge(request.code)) { | ||
| packageNames.add('pandas'); | ||
| } | ||
| if (packageNames.size) { | ||
| await pyodide.loadPackage([...packageNames]); |
There was a problem hiding this comment.
Install micropip requirements with micropip
When a requirement is declared with source: 'micropip' (which the new PythonRequirementSpec and command input allow), this path groups it with Pyodide packages and calls pyodide.loadPackage, so PyPI-only packages fail during setup before user code runs. Split requirements by source and invoke micropip.install for micropip entries instead of passing them to loadPackage.
Useful? React with 👍 / 👎.
| const handleRun = useCallback(() => { | ||
| if (!blockId || runtime?.status === 'running') return; | ||
| void runCell(blockId, {artifactId}); |
There was a problem hiding this comment.
Block execution when the cell is read-only
In read-only worksheet/document renders, the editor prevents code edits but handleRun still calls runCell, and the run button is enabled whenever the cell has code. Because runCell writes lastResult back into persisted room state, a viewer of a read-only artifact can mutate it by clicking Run or pressing Mod-Enter; include readOnly in this guard and the run button disabled state.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (5)
packages/python-cell/src/PythonCellSlice.ts (1)
150-156: 💤 Low value
patchCelltriggers two state updates.Calling
ensureCelltwice (line 151 and 152-155) causes two separate Zustand state updates. This can be consolidated into a single update.♻️ Proposed consolidation
patchCell(cellId, patch) { - const existing = get().pythonCells.ensureCell(cellId); - get().pythonCells.ensureCell(cellId, { - ...existing, - ...patch, - }); + const existing = get().pythonCells.config.cells[cellId]; + get().pythonCells.ensureCell(cellId, { + ...(existing ?? {}), + ...patch, + }); },🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/python-cell/src/PythonCellSlice.ts` around lines 150 - 156, The patchCell method is calling ensureCell twice (once to retrieve the existing cell and once to update it), which triggers two separate Zustand state updates. Consolidate this into a single call by retrieving the existing cell, merging it with the patch object, and updating the state in one operation. This will reduce unnecessary re-renders and improve performance.packages/python-cell/src/pyodideWorker.ts (1)
256-262: ⚖️ Poor tradeoffImport detection regex may have false positives.
The regex patterns for
usesSqlroomsBridgeandusesAltaircan match inside string literals or comments (e.g.,# import sqlrooms). Consider using Python AST parsing for more accurate detection, or accept this as a known limitation.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/python-cell/src/pyodideWorker.ts` around lines 256 - 262, The regex patterns in the `usesSqlroomsBridge` and `usesAltair` functions can produce false positives by matching import statements inside string literals or comments. Either implement Python AST parsing to accurately detect actual import statements, or add a clear code comment documenting this regex-based approach as a known limitation with acceptable false positives for performance reasons.packages/python-cell/src/PythonCellBlock.tsx (1)
38-48: ⚡ Quick winAdd TSDoc for exported props/types and component declarations.
These exported declarations are part of the package API and should have TSDoc to satisfy the package documentation contract.
As per coding guidelines, "
**/*.{ts,tsx}: Add tsdoc to exported types and functions`."Also applies to: 213-219
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/python-cell/src/PythonCellBlock.tsx` around lines 38 - 48, Add TSDoc comments to all exported type declarations and component declarations in the file to satisfy the package documentation contract. Specifically, add TSDoc documentation above the PythonCellBlockRenderProps type definition, the PythonCellBlockProps type definition, and the PythonCellBlock component declaration to provide clear documentation for consumers of these exported API elements. The TSDoc comments should describe the purpose and usage of each exported declaration, including any relevant parameters or properties. Also apply the same TSDoc documentation to the other exported declarations mentioned at lines 213-219.Source: Coding guidelines
packages/python-cell/src/PythonCellCommands.ts (1)
15-40: ⚡ Quick winAdd TSDoc to exported command constants and types.
The exported API declarations in this range should be documented for consumer-facing discoverability and generated docs quality.
As per coding guidelines, "
**/*.{ts,tsx}: Add tsdoc to exported types and functions`."🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/python-cell/src/PythonCellCommands.ts` around lines 15 - 40, Add TSDoc comments to all exported declarations in the range. Document the PYTHON_CELL_BLOCK_TYPE constant, PYTHON_CELL_COMMAND_SUFFIXES array, PythonCellCommandSuffix type alias, and CreatePythonCellCommandsOptions type with clear, descriptive JSDoc comments that explain the purpose and usage of each exported symbol. These comments should appear immediately before each declaration to ensure proper API documentation generation for consumers.Source: Coding guidelines
apps/sqlrooms-cli-ui/src/store-types.ts (1)
44-57: ⚡ Quick winAdd TSDoc on exported
RoomState.This export was modified, but it still has no TSDoc summary.
Proposed change
+/** + * Aggregated room store state for the CLI UI application. + */ export type RoomState = RoomShellSliceState & ArtifactsSliceState & ArtifactAiSliceState &As per coding guidelines,
**/*.{ts,tsx}: Add tsdoc to exported types and functions.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/sqlrooms-cli-ui/src/store-types.ts` around lines 44 - 57, Add TSDoc documentation to the exported RoomState type in the store-types.ts file. This type currently has no documentation comment, but according to coding guidelines, all exported types must include TSDoc. Place a TSDoc comment block above the RoomState type definition that provides a clear summary of what this type represents - it is an intersection type that combines multiple slice states for the application state management. Use the standard TSDoc format with a brief description of the type's purpose.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@apps/sqlrooms-cli-ui/src/store.ts`:
- Around line 270-293: The readTable method directly interpolates the tableName
parameter into a SQL query without escaping or validation, creating a SQL
injection vulnerability. Modify the readTable method to escape or validate the
tableName before passing it to runReadonlyPythonSql. Ensure the table identifier
is properly quoted or sanitized following your database connector's SQL escaping
conventions so that malicious table names cannot alter the query structure.
In `@packages/python-cell/src/PyodidePythonRuntimeAdapter.ts`:
- Around line 122-128: The dispose() method clears the pending map without
rejecting the stored promises, causing any code awaiting execute() calls to hang
indefinitely. Before calling this.pending.clear() in the dispose() method,
iterate through all entries in this.pending and reject each promise with an
appropriate error message indicating that the runtime has been disposed. After
rejecting all pending promises, then proceed to clear the map as currently done.
In `@packages/python-cell/src/PythonCellCommands.ts`:
- Around line 54-58: The index field in the PythonCellCommands schema currently
accepts negative integers which causes unintended behavior when passed to
insertBlocks. Add a constraint to the index field's Zod validation schema to
restrict it to non-negative values only. Modify the number validator chain for
the index field by adding a non-negativity constraint (such as .min(0) or
.nonnegative()) after the .int() call and before .optional() to ensure only zero
or positive integers are accepted.
In `@packages/python-cell/src/PythonCellSlice.ts`:
- Around line 358-362: The truncate function checks byte size using Blob but
then truncates by character index with slice, which is incompatible for
multi-byte UTF-8 characters and can exceed the maxBytes limit or slice
mid-character. Replace the character-based slicing approach with TextEncoder to
encode the string to bytes, truncate at the proper byte boundary, and then
decode the result back to a string. This ensures the returned value never
exceeds maxBytes and maintains valid UTF-8 encoding.
---
Nitpick comments:
In `@apps/sqlrooms-cli-ui/src/store-types.ts`:
- Around line 44-57: Add TSDoc documentation to the exported RoomState type in
the store-types.ts file. This type currently has no documentation comment, but
according to coding guidelines, all exported types must include TSDoc. Place a
TSDoc comment block above the RoomState type definition that provides a clear
summary of what this type represents - it is an intersection type that combines
multiple slice states for the application state management. Use the standard
TSDoc format with a brief description of the type's purpose.
In `@packages/python-cell/src/pyodideWorker.ts`:
- Around line 256-262: The regex patterns in the `usesSqlroomsBridge` and
`usesAltair` functions can produce false positives by matching import statements
inside string literals or comments. Either implement Python AST parsing to
accurately detect actual import statements, or add a clear code comment
documenting this regex-based approach as a known limitation with acceptable
false positives for performance reasons.
In `@packages/python-cell/src/PythonCellBlock.tsx`:
- Around line 38-48: Add TSDoc comments to all exported type declarations and
component declarations in the file to satisfy the package documentation
contract. Specifically, add TSDoc documentation above the
PythonCellBlockRenderProps type definition, the PythonCellBlockProps type
definition, and the PythonCellBlock component declaration to provide clear
documentation for consumers of these exported API elements. The TSDoc comments
should describe the purpose and usage of each exported declaration, including
any relevant parameters or properties. Also apply the same TSDoc documentation
to the other exported declarations mentioned at lines 213-219.
In `@packages/python-cell/src/PythonCellCommands.ts`:
- Around line 15-40: Add TSDoc comments to all exported declarations in the
range. Document the PYTHON_CELL_BLOCK_TYPE constant,
PYTHON_CELL_COMMAND_SUFFIXES array, PythonCellCommandSuffix type alias, and
CreatePythonCellCommandsOptions type with clear, descriptive JSDoc comments that
explain the purpose and usage of each exported symbol. These comments should
appear immediately before each declaration to ensure proper API documentation
generation for consumers.
In `@packages/python-cell/src/PythonCellSlice.ts`:
- Around line 150-156: The patchCell method is calling ensureCell twice (once to
retrieve the existing cell and once to update it), which triggers two separate
Zustand state updates. Consolidate this into a single call by retrieving the
existing cell, merging it with the patch object, and updating the state in one
operation. This will reduce unnecessary re-renders and improve performance.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 3c0749c8-3f00-458d-81ef-9ed25aa3d42e
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (18)
apps/sqlrooms-cli-ui/package.jsonapps/sqlrooms-cli-ui/src/statefulBlockArtifactConfigs.tsapps/sqlrooms-cli-ui/src/store-types.tsapps/sqlrooms-cli-ui/src/store.tsapps/sqlrooms-cli-ui/src/workspace/WorksheetArtifact.tsxpackages/python-cell/README.mdpackages/python-cell/eslint.config.jspackages/python-cell/package.jsonpackages/python-cell/src/PyodidePythonRuntimeAdapter.tspackages/python-cell/src/PythonCellBlock.tsxpackages/python-cell/src/PythonCellCommands.tspackages/python-cell/src/PythonCellSlice.tspackages/python-cell/src/index.tspackages/python-cell/src/pyodideWorker.tspackages/python-cell/src/types.tspackages/python-cell/src/useStoreWithPythonCells.tspackages/python-cell/tsconfig.jsonpackages/python-cell/typedoc.js
There was a problem hiding this comment.
🧹 Nitpick comments (2)
packages/python-cell/src/pyodideWorker.ts (2)
44-71: ⚡ Quick winConsider extracting shared host-bridge types to avoid drift.
PyodideHostRequestandPyodideHostResponseare duplicated between this worker file andPyodidePythonRuntimeAdapter.ts. While duplication across worker/main-thread boundaries is sometimes necessary, these wire-format types must stay exactly in sync. Consider extracting them into a shared module (e.g.,pyodideWorkerTypes.ts) that both files import, reducing the risk of silent contract mismatches.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/python-cell/src/pyodideWorker.ts` around lines 44 - 71, Extract the duplicate type definitions `PyodideHostRequest` and `PyodideHostResponse` from the pyodideWorker.ts file into a new shared module called pyodideWorkerTypes.ts. Move both type definitions to this new shared module, then update pyodideWorker.ts to import these types from the new shared module. Additionally, locate the `PyodidePythonRuntimeAdapter.ts` file and update it to import the same types from the shared module instead of having its own duplicate definitions. This ensures both files maintain a single source of truth for these wire-format types and prevents silent contract mismatches.
349-382: 💤 Low value
quoteSqlIdentifieris duplicated instore.ts.This helper also exists in
apps/sqlrooms-cli-ui/src/store.ts(line 379-381). Consider extracting it to a shared utility module to avoid divergence.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/python-cell/src/pyodideWorker.ts` around lines 349 - 382, The quoteSqlIdentifier function is duplicated in both pyodideWorker.ts and store.ts (line 379-381), which can lead to maintenance issues if the logic needs to be updated in one place but not the other. Extract the quoteSqlIdentifier function to a shared utility module (consider creating a common utilities file or adding it to an existing shared utilities module), then import and use it in both pyodideWorker.ts and store.ts to ensure consistency and reduce code duplication.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@packages/python-cell/src/pyodideWorker.ts`:
- Around line 44-71: Extract the duplicate type definitions `PyodideHostRequest`
and `PyodideHostResponse` from the pyodideWorker.ts file into a new shared
module called pyodideWorkerTypes.ts. Move both type definitions to this new
shared module, then update pyodideWorker.ts to import these types from the new
shared module. Additionally, locate the `PyodidePythonRuntimeAdapter.ts` file
and update it to import the same types from the shared module instead of having
its own duplicate definitions. This ensures both files maintain a single source
of truth for these wire-format types and prevents silent contract mismatches.
- Around line 349-382: The quoteSqlIdentifier function is duplicated in both
pyodideWorker.ts and store.ts (line 379-381), which can lead to maintenance
issues if the logic needs to be updated in one place but not the other. Extract
the quoteSqlIdentifier function to a shared utility module (consider creating a
common utilities file or adding it to an existing shared utilities module), then
import and use it in both pyodideWorker.ts and store.ts to ensure consistency
and reduce code duplication.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 15ce099f-d99f-4ebd-9624-510a571b14a7
📒 Files selected for processing (6)
apps/sqlrooms-cli-ui/src/store.tspackages/python-cell/src/PyodidePythonRuntimeAdapter.tspackages/python-cell/src/PythonCellBlock.tsxpackages/python-cell/src/PythonCellCommands.tspackages/python-cell/src/PythonCellSlice.tspackages/python-cell/src/pyodideWorker.ts
🚧 Files skipped from review as they are similar to previous changes (5)
- packages/python-cell/src/PythonCellBlock.tsx
- packages/python-cell/src/PyodidePythonRuntimeAdapter.ts
- apps/sqlrooms-cli-ui/src/store.ts
- packages/python-cell/src/PythonCellCommands.ts
- packages/python-cell/src/PythonCellSlice.ts
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 30e60c4aaa
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| activeExecutionId = undefined; | ||
| } | ||
|
|
||
| const outputs = readResultOutput(pyodide); |
There was a problem hiding this comment.
Honor declared output names during execution
When a cell is created with an outputs declaration through worksheet.add-python-cell-block, the request carries those declarations but the worker ignores request.outputDeclarations here and only reads the special global result. For example, code that assigns foo = 42 with an output declaration {type: 'json', name: 'foo'} reports no outputs, and declared table/image outputs are never materialized. Please collect the declared output names from globals and route table/asset outputs through the host where applicable instead of relying solely on result.
Useful? React with 👍 / 👎.
| runReadonlyPythonSql( | ||
| `SELECT * FROM ${quoteSqlIdentifier(tableName)}`, | ||
| maxRows, | ||
| ), | ||
| runReadonlySql: ({query, maxRows}) => runReadonlyPythonSql(query, maxRows), |
There was a problem hiding this comment.
Provide schema bridge for schema inputs
Cells that declare a schema input fail in the CLI because bindInputs sends a schema host request and PyodidePythonRuntimeAdapter requires host.readSchema, but this host only wires table/query access. In that scenario the run errors with SQLRooms Python schema bridge is not configured before user code executes, even though schema inputs are accepted by the command/schema API. Please implement readSchema here or reject schema inputs for the CLI runtime.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ba77a3141e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| pyodide.globals.set( | ||
| input.name, | ||
| requestHostQuery(input.query, input.maxRows), | ||
| ); |
There was a problem hiding this comment.
Convert declared input payloads before binding
When a declared sql input is used, this writes the raw JS host response into the Python global. Pyodide exposes JS objects as JsProxy unless converted, while the sqlrooms.query() helper explicitly calls .to_py(); cells that pass the input to pandas or return it as result therefore receive/prolong a proxy instead of a native {columns, rows, rowCount} dict. Convert the response with pyodide.toPy(...) (and do the same for table/schema inputs) before binding.
Useful? React with 👍 / 👎.
| if (nextCell) { | ||
| nextCell.lastResult = result; | ||
| nextCell.updatedAt = Date.now(); | ||
| } | ||
| delete draft.pythonCells.runtimeByCellId[cellId]; |
There was a problem hiding this comment.
Preserve active runs when an older execution finishes
When runCell is invoked twice for the same cell through the command/direct API, the second call overwrites runtimeByCellId[cellId] with its execution id. When the first completion reaches this block, it still writes lastResult and deletes the runtime entry, making the UI/API report idle while the second run is queued or running; with non-serial adapters it can also persist a stale result. Check the current execution id before clearing or writing completion state.
Useful? React with 👍 / 👎.
|
|
||
| return {"type": "json", "name": name, "value": value} | ||
|
|
||
| __sqlrooms_json.dumps([__sqlrooms_output_for("result", result)], default=str) |
There was a problem hiding this comment.
Emit valid JSON for non-finite Python numbers
For outputs containing non-finite floats (result = float('nan'), pandas/NumPy data, or Vega specs with NaN), Python's json.dumps emits NaN/Infinity by default, which is not valid JSON for the subsequent JSON.parse. A successful cell is then reported as an execution error while reading outputs. Normalize or replace non-finite values with a JSON-compatible representation before parsing.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c7aebc2938
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| pyodide.globals.set( | ||
| input.name, | ||
| requestHostQuery( | ||
| `SELECT * FROM ${quoteSqlIdentifier(input.tableName)}`, |
There was a problem hiding this comment.
Handle qualified table references
When a declared tableRef uses the canonical SQLRooms table id produced elsewhere in the app, such as main.events or "main"."events", this quotes the whole string as one identifier ("main.events" / """main"".""events""") instead of preserving the qualified parts. That makes Python cells fail to bind schema-qualified or attached-database tables even though those are the table references agents and table tools hand around; use the existing qualified table-reference quoting/parsing behavior rather than single-identifier quoting here.
Useful? React with 👍 / 👎.
| pyodide.setStdout({batched: (output) => stdout.push(output)}); | ||
| pyodide.setStderr({batched: (output) => stderr.push(output)}); |
There was a problem hiding this comment.
Cap stdout while collecting it
For cells that print a lot of data, this buffers every stdout/stderr chunk in memory and only applies the persisted-size truncation later in PythonCellSlice, while request.limits?.maxStdoutBytes is never enforced in the worker. A single print loop can therefore allocate very large strings/arrays and freeze or crash the browser before the bounded result summary is created; drop or truncate output as it is appended.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 03434da5df
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| activeExecutionId = request.executionId; | ||
| try { | ||
| bindInputs(pyodide, request.inputs); | ||
| const lastExpressionResult = await pyodide.runPythonAsync(request.code, { |
There was a problem hiding this comment.
Enforce timeoutMs during Python execution
When a host supplies limits.timeoutMs or a user runs CPU-bound code such as while True: pass, this await has no timeout or interrupt path. Because the worker is serial, that promise never settles, runtimeByCellId stays running, and all later Python-cell executions queue behind the hung run until the worker/page is reset.
Useful? React with 👍 / 👎.
| __sqlrooms_seen_output_names = set() | ||
| for __sqlrooms_declaration in __sqlrooms_output_declarations: | ||
| __sqlrooms_name = __sqlrooms_declaration.get("name") | ||
| if __sqlrooms_name in globals(): |
There was a problem hiding this comment.
Clear declared outputs before reading globals
When a cell has a declared output and a previous run created that global, a later successful run that no longer assigns it still passes this globals() check because the Pyodide interpreter is reused and only result is cleared before execution. In that scenario the persisted lastResult shows stale output from an earlier run, which can corrupt worksheet results after code edits.
Useful? React with 👍 / 👎.
| requestHostQuery( | ||
| `SELECT * FROM ${quoteSqlTableReference(input.tableName)}`, | ||
| input.maxRows, |
There was a problem hiding this comment.
Route tableRef inputs through readTable
PythonRuntimeHost.readTable is the required table-input hook, while runReadonlySql is optional; however a tableRef input is converted into a SQL host request here, and the adapter rejects that request when runReadonlySql is not implemented. Package consumers that implement the documented readTable contract therefore cannot run table-ref inputs unless they also provide the optional SQL bridge.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0187576597
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const arrowTable = await connector.query( | ||
| wrapPythonReadonlyQuery(query, maxRows), | ||
| ); | ||
| const rows = arrowTableToJson(arrowTable); |
There was a problem hiding this comment.
Preserve SQL value types for Python rows
When a Python cell uses sqlrooms.query()/query_df() or a tableRef input over data containing NULL or booleans, this bridge serializes rows with arrowTableToJson; that helper stringifies every non-number/non-BigInt value, so NULL becomes "null" and booleans become "true"/"false". Pandas and downstream Python analysis then operate on corrupted strings rather than the database values, so this path should use a conversion that preserves JSON primitives for Python bridge rows.
Useful? React with 👍 / 👎.
| if (input.kind === 'literal') { | ||
| pyodide.globals.set(input.name, input.value); | ||
| continue; |
There was a problem hiding this comment.
Convert literal inputs before binding
When a command declares a literal input whose value is an object or array, this branch stores the raw JS value directly in Pyodide. Pyodide exposes that as a JsProxy, unlike the SQL/table/schema paths below that call bindPythonGlobal and .to_py(), so Python code expecting a normal dict/list or returning that value as result gets a proxy/stringified object instead; route literal values through the same conversion path.
Useful? React with 👍 / 👎.
| this.pending.delete(request.executionId); | ||
| this.worker?.terminate(); | ||
| this.worker = undefined; |
There was a problem hiding this comment.
Reject pending runs when terminating the worker
With per-request limits.timeoutMs, a timeout terminates the shared worker but only deletes and rejects the timed-out entry. Any other execution already posted to that worker, such as a queued run for another cell with no timeout or a longer timeout, can no longer receive a result and remains in pending/running state until an external reset; clear and reject all pending requests whenever the worker is terminated.
Useful? React with 👍 / 👎.
…odex/python-cell-blocks
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4b8f1c82d2
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const timeoutId = request.limits?.timeoutMs | ||
| ? setTimeout(() => { |
There was a problem hiding this comment.
Start execution timeouts when work starts
When timeoutMs is configured and multiple cells are run, this timer starts as soon as execute() posts the request, but pyodideWorker serializes requests behind executionQueue. A queued cell spends part of its execution budget waiting for earlier cells; for example, if the first run takes 55s with a 60s limit, the second cell is killed after only about 5s of actual Python and the shared worker is terminated. Start the timeout when the worker begins that request, or track queue wait separately.
Useful? React with 👍 / 👎.
| const qualifiedTableName = | ||
| schemaName === 'main' | ||
| ? currentTableName | ||
| : `${schemaName}.${currentTableName}`; |
There was a problem hiding this comment.
Preserve catalog names in schema summaries
For schema inputs without a tableName, this key uses only schema/table and even drops the main schema. In workspaces with attached DuckDB databases, information_schema.columns can return the same table_schema/table_name from different table_catalogs, so their columns are merged under one table and Python cells or agents receive an invalid schema. Include table_catalog in the query/key, or use the existing qualified table-name helpers before grouping.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3aee0b8924
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
|
||
| const signal = new SharedArrayBuffer(4); | ||
| const response = new SharedArrayBuffer(4 + HOST_RESPONSE_BUFFER_BYTES); | ||
| const normalizedMaxRows = normalizeMaxRows(maxRows); |
There was a problem hiding this comment.
Apply the row preview limit to bridge queries
When a caller configures limits.maxRowsPreview, cells that omit an explicit maxRows—for example sqlrooms.query("select * from big_table") or a tableRef input without maxRows—still send an unbounded host request because this path only normalizes the explicit argument and maxRowsPreview is otherwise never read. The CLI host then applies no LIMIT and tries to JSON-copy the full result through the 16 MiB bridge buffer, so large tables can fail with SQLRoomsBridgeResponseTooLarge or consume excessive memory before user code runs; fall back to the request preview limit when maxRows is absent, and apply the same behavior to table requests.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9e73d3c2dd
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
|
||
| def __sqlrooms_output_for(name, value, declared_type=None): | ||
| if declared_type == "text": | ||
| return {"type": "text", "name": name, "text": str(value)} |
There was a problem hiding this comment.
Bound declared text outputs before serialization
When a block declares a text/markdown/html output, this branch converts the full Python value to a string and the worker later JSON-serializes/posts it before PythonSlice truncates persisted summaries. A cell with a declared summary output and summary = 'x' * 10_000_000 can still allocate and send megabytes through the worker/main-thread boundary despite the persisted-size caps; apply the same bounded-string budget here and in the adjacent markdown/html branches before returning the output.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 03d02a3987
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const trimmedQuery = query.trim().replace(/;+$/, ''); | ||
| const limit = | ||
| maxRows === undefined ? '' : ` LIMIT ${Math.max(0, Math.floor(maxRows))}`; | ||
| return `SELECT * FROM (${trimmedQuery}) AS sqlrooms_python_query${limit}`; |
There was a problem hiding this comment.
Reject stacked statements in readonly Python SQL
When a Python block calls sqlrooms.query() with SQL that closes the derived table and appends another statement, for example SELECT 1); DROP TABLE t; --, this wrapper produces SELECT * FROM (SELECT 1); DROP TABLE t; --) .... In the CLI path that string is forwarded to DuckDB via con.query(sql) in python/sqlrooms-server/sqlrooms/server/query.py:72, which can execute the stacked statement, so the supposedly readonly bridge can mutate or drop workspace tables. Parse/enforce a single SELECT before forwarding, or route through the existing select-only policy.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: fd3c48bae0
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| function bindInputs(pyodide: PyodideAPI, inputs: PythonInput[]) { | ||
| for (const input of inputs) { | ||
| if (input.kind === 'literal') { | ||
| bindPythonGlobal(pyodide, input.name, input.value); |
There was a problem hiding this comment.
Clear stale input globals before binding
When a block's inputs are removed or renamed after a successful run, this loop only writes the current declarations and never deletes names bound on earlier executions. Because the Pyodide interpreter is reused, Python code can keep reading the old global (for example customers after that input was removed) and persist results from stale data instead of failing or using the new declarations; track and clear previously bound input names before binding the current set.
Useful? React with 👍 / 👎.
| if (value instanceof Date) { | ||
| return value.getTime(); |
There was a problem hiding this comment.
Preserve temporal SQL values for Python rows
When a DuckDB/Arrow DATE or TIMESTAMP reaches this converter as a JS Date, this turns it into an epoch-millisecond number before the rows are handed to Pyodide. sqlrooms.query_df() then builds pandas columns of integers instead of dates/timestamps, so time-based filters, grouping, and charts operate on corrupted types; preserve temporal values with type-aware conversion rather than dropping them to raw milliseconds.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5b8dd03faf
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const arrowTable = await connector.query(` | ||
| SELECT table_catalog, table_schema, table_name, column_name, data_type | ||
| FROM information_schema.columns | ||
| WHERE table_schema NOT IN ('pg_catalog', 'information_schema') |
There was a problem hiding this comment.
Filter internal tables from schema inputs
When a schema input omits tableName, this query enumerates every non-pg_catalog/information_schema column, but the CLI's DuckDB schema UI later applies defaultLoadSchemaCatalogFilter and an explicit mosaic-schema filter. In workspaces with SQLRooms persistence tables, the temp catalog, or the mosaic preaggregation cache, Python cells/agents receive hidden internal tables in their schema context and can treat them as user data; apply the same catalog/table filters before grouping the schema summary.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 90feeee4b6
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| } | ||
| const limit = | ||
| maxRows === undefined ? '' : ` LIMIT ${Math.max(0, Math.floor(maxRows))}`; | ||
| return `SELECT * FROM (${trimmedQuery}) AS sqlrooms_python_query${limit}`; |
There was a problem hiding this comment.
Preserve trailing line comments when wrapping queries
When a Python bridge query is a valid SELECT that ends with a -- line comment, e.g. sqlrooms.query("SELECT 1 -- note"), this appends the closing ) AS sqlrooms_python_query on the same line, so DuckDB treats the wrapper as part of the comment and sees an unterminated subquery. Add a newline or otherwise terminate trailing line comments before appending the wrapper so commented SELECTs still run.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 11fdb1a38c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| sandbox="allow-scripts" | ||
| referrerPolicy="no-referrer" | ||
| className="bg-background h-96 w-full rounded-sm border" | ||
| srcDoc={html} |
There was a problem hiding this comment.
Block scripts in arbitrary HTML outputs
When a persisted html output is rendered, including in a read-only or shared worksheet, this iframe executes whatever scripts are embedded in srcDoc because the sandbox explicitly includes allow-scripts and arbitrary HTML is not wrapped with a restrictive CSP. A stored result such as <script>fetch('https://attacker.example')</script> runs as soon as the viewer opens the worksheet, without pressing Run; either omit script execution for user HTML or apply an allowlisted CSP like the generated Vega-Lite renderer does.
Useful? React with 👍 / 👎.
| const lastExpressionResult = await pyodide.runPythonAsync(request.code, { | ||
| filename: `<sqlrooms-python-block:${request.blockId}>`, | ||
| }); |
There was a problem hiding this comment.
Isolate each Python execution from prior globals
If a user reruns a block after removing an assignment, or runs another Python block in the same worker, globals left by previous executions are still visible here because this executes in Pyodide's shared global namespace while only result, declared outputs, and input names are cleared. For example, after one run defines threshold = 10, a later block containing only result = threshold succeeds with stale state instead of reflecting its declared inputs and code, making results order-dependent; run code with a fresh/per-block globals dict or clear user globals before execution.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4a31701ce0
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (typeof SharedArrayBuffer === 'undefined') { | ||
| throw new Error( | ||
| 'Pyodide Python execution requires SharedArrayBuffer for SQLRooms host bridge calls.', | ||
| ); |
There was a problem hiding this comment.
Allow pure Python without SharedArrayBuffer
In non-cross-origin-isolated hosts where SharedArrayBuffer is undefined, this guard rejects every Pyodide execution before looking at whether the request will use the SQLRooms bridge. Blocks that only run local Python, such as result = 1, do not need the synchronous query/table/schema bridge, so package consumers or embedded/static renderers without COOP/COEP cannot run even pure Python. Defer this requirement until a host bridge call is actually needed, or provide a non-bridge execution path.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 32df68606b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| document: WorksheetMarkdownDocumentBlockRenderer, | ||
| 'sql-query': WorksheetSqlQueryBlockRenderer, | ||
| 'html-app': WorksheetHtmlAppBlockRenderer, | ||
| python: WorksheetPythonBlockRenderer, |
There was a problem hiding this comment.
Gate Python blocks behind experimental mode
When a worksheet already contains a python stateful block and the CLI is opened without --experimental, this renderer remains active because createWorksheetStatefulBlockRenderers(false) spreads this map and only replaces pivot/document/sql/html-app with the experimental placeholder. That bypasses the stability: 'experimental' setting for Python and still lets non-experimental users view/edit/run the new Python surface; add python: ExperimentalStatefulBlockPlaceholder to the non-experimental branch as well.
Useful? React with 👍 / 👎.
| message: | ||
| error instanceof Error ? error.message : 'Python execution failed.', | ||
| traceback: error instanceof Error ? error.stack : undefined, |
There was a problem hiding this comment.
Bound worker-side error summaries
If Python raises an exception with a very large message, this worker still copies the raw error.message and stack into the result that is posted back to the main thread; although the slice now truncates before persisting, the fresh evidence is that this worker-side summary remains unbounded before that truncation. A cell like raise Exception('x' * 10_000_000) can still allocate and transfer megabytes across the worker boundary, so apply the same byte cap here before returning the summary.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ab3e6ba14c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| return value | ||
| if isinstance(value, str): | ||
| return __sqlrooms_bounded_string(value, budget) if budget is not None else value | ||
| if isinstance(value, dict): |
There was a problem hiding this comment.
Protect output serialization from shadowed builtins
Because this serializer runs in the same globals dict as the user's cell, unqualified builtin names here resolve to user variables first. If a valid cell defines a common name such as dict = {} or list = [] and then returns a JSON/dict/list result, checks like isinstance(value, dict) throw during output collection, so the run is reported as an execution error after the user code succeeded; use builtins aliases or a separate helper namespace for these type checks.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a2cb127faa
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| bindInputs(pyodide, globals, request.inputs); | ||
| // The adapter starts timeoutMs when it receives this worker's "started" | ||
| // message and terminates the worker if execution exceeds that budget. | ||
| const lastExpressionResult = await pyodide.runPythonAsync(request.code, { |
There was a problem hiding this comment.
Destroy returned PyProxy values after capturing expressions
When a cell's final expression produces a Python object, such as a DataFrame or list, runPythonAsync returns a JS-owned PyProxy. This path stores that object into the execution globals when result was not assigned, but never destroys the returned proxy; destroying the globals dict later does not release the JS proxy itself, so repeated runs that end in large Python objects can leak worker memory. Destroy the proxy after transferring/reading it, similar to the toPy binding path.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f28fbf68cc
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| ...createPythonSlice({ | ||
| runtimeAdapter: createPyodidePythonRuntimeAdapter(), | ||
| host: createCliPythonRuntimeHost(), | ||
| })(set, get, store), |
There was a problem hiding this comment.
Pass a timeout to the CLI Python slice
Even though the worker now supports execution timeouts, this CLI wiring leaves request.limits?.timeoutMs undefined for every worksheet Python run. In the shipped UI a cell such as while True: pass therefore never trips the adapter timeout and the shared Pyodide worker keeps all later Python runs queued behind it until the page/runtime is reset; provide a sane CLI limits.timeoutMs when creating the slice.
Useful? React with 👍 / 👎.
Summary
@sqlrooms/python-cellpackage with persisted Python cell schemas, runtime adapter/host contracts, a Zustand slice, a worksheet block renderer, and command-backed operations.run: falseas an opt-out.Cmd/Ctrl+Enterexecution parity with SQL blocks, and in-editorTab/Shift-Tabindentation without moving focus out of the editor.sqlroomsPython bridge for read-only DuckDB queries, including dataframe/raw/records helpers, declared input binding, schema input support in the CLI host, and qualified table-reference handling.Validation
http://localhost:4175/: verified the app mounted with no browser console errors after starting the local dev server.pnpm --filter @sqlrooms/python-cell typecheckpnpm --filter sqlrooms-cli-app typecheckpnpm --filter @sqlrooms/python-cell buildpnpm --filter sqlrooms-cli-app buildknip,turbo typecheck,turbo testNotes
The CLI Pyodide runtime supports read-only SQL/schema bridge operations. Declared scalar/rich outputs are collected by name; declared table/image output materialization is still explicit future work because the CLI host does not yet provide a concrete write-table/write-asset path.
Summary by CodeRabbit
python-cellblocks in the worksheet UI, including run/clear controls, read-only mode, and rich result rendering (text, tables, images, HTML, JSON, Vega-Lite).sqlrooms.query*usage guidance.