Notebooks
Cells, outputs, dependency-driven execution, layout, and live notebook authoring.
A notebook holds the cells and layout for an Explore. Its conversations stay with that Explore.
Cells and outputs
Each cell has an ID, Python source, configuration, and execution state. In the app, you can add Python, SQL, Markdown, and input cells. SQL and Markdown editors produce Python calls to cee.sql() and cee.md().
| Part | Contract |
|---|---|
| Source | The code defining the cell. Edited text has not necessarily run or been saved. |
| Output | The displayed result, such as a table, chart, Markdown, text, or error. The last expression normally supplies the output; some helpers also display results. |
| Console | Printed output and diagnostics, separate from the cell's displayed result. |
| Configuration | Settings such as layout placement, code visibility, and disabled execution. |
An earlier result may remain visible while you edit source or wait for a run. Use Run in the editor to submit the current source, then inspect the new result and any errors.
Saved source and stored outputs are separate from live Python variables. Reopened work may need execution again. See Environments, sessions and runs for runtime readiness and session lifetime.
Dependencies and execution order
Querio finds dependencies from the names cells define and use. Execution follows those dependencies, even when a dependent cell appears above its input. Moving a cell changes its position, not its references.
- Define each public variable in one cell. Defining it again in another cell causes a multiple-definition error; give downstream results new names.
- Names beginning with a single underscore are local to their cell. Use public names for values other cells need.
- Dependency cycles and wildcard imports such as
from package import *are not allowed. - Running a cell also runs affected dependent cells. Put reusable calculations upstream of presentation cells.
- Define a widget in one cell and read its
.valuein another. Changing its value can then rerun dependent calculations or queries.
If an upstream cell fails, its dependents may be cancelled. Fix the failed cell and check the results again. Reactive execution cannot tell you whether the query or business definition is right.
UI elements and filters
UI elements let readers filter data and change inputs without editing code. Add a control through Add input cell, ask the agent to create it, or use cee.ui in a Python cell. Place the control's cell in Layout to make it available on a board. See Build a board for the workflow.
| Helper | Value available to downstream cells |
|---|---|
cee.ui.dropdown(...), cee.ui.radio(...) | The selected option. Dictionary options can map labels to values. |
cee.ui.multiselect(...) | A list of selected options. |
cee.ui.date_picker(...) | A datetime.date; use two controls for a date range. |
cee.ui.number_input(...), cee.ui.slider(...) | The selected number. |
cee.ui.text_input(...) | The entered text. |
cee.ui.checkbox(...) | A boolean. |
Define a control in one cell and read its .value in another. This connects the calculation or query to the selection.
Example: connect a region filter to a total
Add and run these two Python cells in a notebook where these names are unused.
First cell:
import code_execution_environment as cee
board_region = cee.ui.dropdown(
["All regions", "East", "West"], value="All regions", label="Region"
)
board_regionSecond cell:
_region_totals = {"East": 24, "West": 32}
board_filtered_total = (
sum(_region_totals.values())
if board_region.value == "All regions"
else _region_totals[board_region.value]
)
board_filtered_totalExpected totals: 56 for All regions, 24 for East and 32 for West. Changing the dropdown reruns the dependent total. Charts that use that total can depend on it in turn. The example uses made-up data and needs no database connection.
For database-backed filters, read the control's value in the downstream query cell. Treat an all-results option explicitly, and use appropriate value escaping rather than inserting arbitrary text into SQL. Each query follows the reader's datasource access. Live controls do not make saved public links interactive.
Use help(cee.ui.<widget>) in the active runtime for arguments and examples, including SQL filters. cee.ui.table(...) also provides an interactive table; its selection options are described by help(cee.ui.table).
Notebook helpers
In cell source, import notebook helpers with import code_execution_environment as cee.
| Helper | Behavior |
|---|---|
cee.sql(query, datasource="warehouse") | Runs a nonempty query and returns a pandas dataframe. Displays it by default; output=False suppresses automatic display. Replace warehouse with your datasource slug. |
cee.md(text) | Returns rendered Markdown. Make it the last expression to display it; Python f-strings can include upstream values. |
cee.ui.<widget>(...) | Creates an interactive control or table. Display the returned object and read its value from downstream cells. |
cee.hstack([...]), cee.vstack([...]) | Combine several objects horizontally or vertically within one cell output. |
See UI elements and filters for control values and a reactive example. Check SQL arguments in the active runtime with help(cee.sql).
Selecting a datasource does not grant query access. A query needs datasource permission and exactly one authorized credential. See Datasources and credentials for the access rules and Context files for workspace guidance.
Layout
Layout places selected notebook outputs on a board grid. It does not copy the cells or change their dependencies. Removing a cell from Layout leaves its source in the notebook for dependent cells to use. Follow Edit a notebook to arrange outputs in the app.
Code Mode placements use (cell_id, x, y, width, height) in grid units. The grid has 24 columns, 40px rows, and 10px gaps. x and y must be nonnegative integers; width and height must be positive integers; x + width must be at most 24. Placements cannot overlap.
Code visibility and layout placement do not control access. Editing source or layout requires Explore edit permission. A View session can inspect and run existing cells and use controls, but cannot edit the source notebook's cells. See Explores for access and separate work.
To refer to the current notebook in a question, use cell mentions and Tag in chat. To develop independent work from a board result, follow Explore from a board.
For a lost connection or restarted runtime, check Disconnect, timeout, and close before retrying.
Saving, status, and errors
Check which cells ran and whether the changes saved. Stored outputs and live Python values can differ from the current source. See Environments, sessions and runs for runtime recovery and saving behavior.
Execution status values and Code Mode errors
| Status | Meaning |
|---|---|
stale | Nonempty source has not run, changed since execution, or depends on changed state. |
queued, running | Execution is pending or in progress. |
idle | A successful recorded execution, which need not produce output. It does not confirm saving or that a later request ran. |
exception, querio-error | Execution failed or was prevented. Inspect the cell's .errors. |
cancelled | An ancestor failed; fix that ancestor first. |
interrupted | Execution was interrupted; completed side effects can remain. |
disabled | Execution is disabled. Descendants of disabled cells are also excluded from execution, though they can retain older results. |
None | An empty cell with no execution result. |
After a Code Mode block, inspect ctx.result.succeeded, .errors, and .run_cell_ids, then the intended cells' status and output. Success with no executed cells does not verify a new result. If an ancestor is disabled, a dependent can retain an earlier idle status, value, and output even after the ancestor's source changes. Check ancestor configuration before using that result.
Common validation failures include syntax, duplicate definitions, cycles, undefined references, and invalid or overlapping layout.
StaleCellError means you need to read current cell source before replacing it. StaleNotebookError means the notebook changed while your block was open; inspect current state and prepare a new change. Synchronous with code_mode.get_context() raises TypeError; use async with.
Advanced notebook authoring
Code Mode operations and CLI example
Code Mode reads and changes the active notebook. Plain Python in querio code exec is a scratchpad: it gets a shallow copy of notebook globals, so new bindings and rebindings do not create or change cells. In-place changes to shared objects can persist. Use Code Mode to author cells.
Use code_mode.get_context() for read-only inspection. For changes, use async with code_mode.get_context() as ctx:. Call mutation methods directly inside the block; do not await them or wrap the block in asyncio.run().
For full signatures, use help(code_mode) or querio code skill --reference notebook-authoring. See CLI reference.
| Operation | Contract |
|---|---|
ctx.cells | Ordered cell views, indexed by ID or position. Inspect .code, .config, .status, .errors, .output, and .console_outputs. |
ctx.graph | Inspect dependencies through .ancestors(cell_id) and .descendants(cell_id). |
ctx.globals | Read current live notebook values. Check execution success before using them. |
ctx.create_cell(code, ...) | Adds a cell and returns its ID. Keep that ID or find it in ctx.cells. Defaults to hidden code; pass hide_code=False to show it. |
ctx.edit_cell(id, code, ...) | Replaces full cell source. Read ctx.cells[id].code first to protect against stale writes. Configuration-only changes need no source read. |
ctx.delete_cell(id) | Removes a cell. A Code Mode change that leaves affected references undefined is rejected. |
ctx.move_cell(id, before=other_id) | Changes document order. after=other_id is the alternative. |
ctx.run_cell(id) | Requests execution of that cell and affected dependents. Creation and edits can also trigger execution at commit. |
ctx.set_layout(placements, clear_unlisted=False) | Sets (cell_id, x, y, width, height) placements. With clear_unlisted=True, unlisted cells are hidden and lose layout placement, but remain in the notebook. |
ctx.set_ui_value(element, value) | Updates a Querio control through its reactive path. |
Queued changes apply when the block exits normally. An exception inside the block discards them; structural validation failure rejects the proposed notebook. A runtime error after validation can leave authored cells in place. Execution failure or interruption can leave completed side effects.
Example: change an upstream value
Use an empty editable notebook session; Get started with CLI covers setup. Run this once. Replaying the creation block would redefine its public variables.
querio code exec --json <<'PY'
from code_execution_environment import code_mode
async with code_mode.get_context() as ctx:
price_id = ctx.create_cell("unit_price = 6", hide_code=False)
total_id = ctx.create_cell(
"order_total = unit_price * 7\norder_total", hide_code=False
)
ctx.run_cell(str(price_id))
assert ctx.result.succeeded, ctx.result.errors
assert ctx.globals["order_total"] == 42
async with code_mode.get_context() as ctx:
_ = ctx.cells[str(price_id)].code
ctx.edit_cell(str(price_id), "unit_price = 8")
ctx.run_cell(str(price_id))
assert ctx.result.succeeded, ctx.result.errors
assert ctx.globals["order_total"] == 56
print(ctx.globals["order_total"])
PYExpected result: two cells, price 8, and total 56. The second block runs the price cell and updates the dependent total. Check the assertions after each block exits; ctx remains available for inspection.
Successful editable querio code exec waits for notebook saving. If saving fails after execution, keep the session open, inspect existing cells, and resolve the error without replaying creation code.
Large agent tool results
An agent's long Bash or workspace file-tool reply may be shortened before it reaches the conversation. The reply marks truncation. Bash previews keep the end; file-tool previews keep the beginning. Expand a completed Bash step in chat to see its returned preview. A preview cannot establish full row count, earlier errors, or whether filters covered all data.
If the reply says Full output and provides a temporary path, ask the agent to inspect that file with Bash while the environment is available. Check the beginning, end, counts, errors, and any result you plan to use. For a workspace file accepted by the file tool, use offset and limit to inspect successive portions; they do not bypass the original file's size limit. Partial output means the saved file is incomplete; not saved means there is no full temporary copy.
Tool-output files are outside the workspace file collection. Later tool calls can evict them, and closing the environment removes them. Their paths are not saved notebook output or durable workspace files. See Workspace files and versions for persistence and Environments, sessions and runs for runtime lifetime.
Last updated on October 27, 2026