# Notebook Cell

> Generate and insert StackQL query cells into an existing Jupyter notebook. Creates a markdown heading cell and a %%stackql query cell, with optional visualization. Works with the pystackql magic extension.

- Skill: `stackql/notebook-cell` (Agent Skill)
- Install (CLI): `npx skillmds@latest add stackql/notebook-cell`
- Raw SKILL.md: https://api.skillmd.com/api/skills/stackql/notebook-cell/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Docs & Writing
- Author: stackql (https://skillmd.com/u/stackql)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/stackql/notebook-cell

---


You are helping the user add StackQL query cells to an existing Jupyter notebook that uses the pystackql magic extension.

Input: `$@`

Follow these steps in order.

## Step 1 - Find the target notebook

Look for open or recently modified `.ipynb` files:

```bash
find . -name "*.ipynb" -not -path '*/.git/*' -not -path '*/.ipynb_checkpoints/*' 2>/dev/null
```

If multiple notebooks exist, check which ones already use pystackql:

```bash
grep -l "pystackql" *.ipynb 2>/dev/null
```

If there are multiple candidates, ask the user which notebook to add cells to.

If no notebook exists, suggest using `/stackql-skills:notebook` to create one first.

## Step 2 - Read the existing notebook

Read the notebook to understand:
- Which magic extension is loaded (`pystackql.magic` or `pystackql.magics`)
- What providers have been pulled
- What Python variables are defined (these can be used in queries via `$variable`)
- How many cells exist (to determine insert position)
- What queries already exist (to avoid duplication)

## Step 3 - Parse the request

Determine what the user wants:
- **Raw SQL**: the user provided a StackQL query directly
- **Natural language**: the user described what they want to query - generate the SQL
- **`--viz`** flag: what visualization to add (`bar`, `line`, `table`, or auto-detect)
- **`--no-display`**: suppress query output display

If the input is natural language, use the existing notebook context (pulled providers, variables) to generate the appropriate query. If needed, discover the schema:

```bash
stackql exec "DESCRIBE <provider>.<service>.<resource>;" --output json
```

## Step 4 - Generate the cells

### Cell conventions

Follow these rules for all notebook cells:
- One heading per cell, placed at the top
- No horizontal rules (`---`, `***`, `___`) or `<hr/>` tags
- Use spacing and headings to separate sections, not horizontal rules

Create 2-3 cells to insert:

### Markdown cell

```markdown
## <Section Title>

<Brief description of what this query does.>
```

### Query cell

For single-line queries:
```python
%stackql <QUERY>
```

For multi-line queries:
```
%%stackql
SELECT
    <fields>
FROM <provider>.<service>.<resource>
WHERE <params>
```

Options:
- Add `--no-display` to the `%%stackql` line if the flag was passed
- Add `--csv-download` if the user wants export capability

Use `$variable` substitution for any values that match Python variables already defined in the notebook.

Use `$$` to escape literal dollar signs in JSON path expressions.

### Visualization cell (if --viz or auto-detected)

**Bar chart (`--viz bar`):**
```python
stackql_df.plot(kind='bar', x='<x_col>', y='<y_col>', title='<Title>');
```

**Line chart (`--viz line`):**
```python
stackql_df.plot(kind='line', x='<x_col>', y='<y_col>', title='<Title>');
```

**Table (`--viz table`):**
```python
stackql_df
```

**Auto-detect**: If the result likely has a categorical column and a numeric column, suggest a bar chart. If it has a date/time column and a numeric column, suggest a line chart. Otherwise, just display as a table.

## Step 5 - Insert the cells

Use the NotebookEdit tool to insert the cells at the end of the notebook (or at a user-specified position).

## Step 6 - Report

Briefly confirm what was added:
- The query that was inserted
- The visualization type (if any)
- Remind the user to run the cells in order
- Note that `stackql_df` will contain the query results as a pandas DataFrame

