# Notebook

> Create a StackQL Jupyter notebook using the pystackql magic commands. Generates a complete notebook with setup, provider pulls, auth, queries, and optional visualizations from a description or provider resource target.

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

---


You are helping the user create a Jupyter notebook that uses StackQL to query cloud and SaaS resources via the `pystackql` magic commands.

Input: `$@`

Follow these steps in order.

## Step 1 - Understand the requirements

Parse the input to determine:
- Which provider(s) and resources are involved
- What the user wants to query or analyze
- Whether `--server` flag is present (use server mode instead of local binary)

If the input is vague, ask:
- Which cloud provider? (google, aws, azure, github, etc.)
- What resources or data do you want to explore?
- Any specific analysis or visualization goals?

## Step 2 - Discover resource schemas

Check if StackQL is installed and the provider is pulled:

```bash
command -v stackql
stackql exec "SHOW PROVIDERS;" --output json
```

If needed, pull the provider:

```bash
stackql exec "REGISTRY PULL <provider>;"
```

Get the resource schema to inform the notebook queries:

```bash
stackql exec "SHOW SERVICES IN <provider>;" --output json
stackql exec "SHOW RESOURCES IN <provider>.<service>;" --output json
stackql exec "DESCRIBE <provider>.<service>.<resource>;" --output json
stackql exec "SHOW METHODS IN <provider>.<service>.<resource>;" --output json
```

Use this to understand what fields are available and what WHERE clause parameters are required.

## Step 3 - Determine the notebook path

Ask the user where to save the notebook, or use a sensible default based on the topic:

```
<descriptive-name>.ipynb
```

## Step 4 - Build the notebook

Create the notebook with cells following this structure. Use the NotebookEdit tool to create and populate the notebook.

### Cell conventions

Follow these rules for all notebook cells:
- One heading per cell, placed at the top
- No horizontal rules (`---`, `***`, `___`) or `<hr/>` tags
- Any cell with `<div>`, `<link>`, `<script>` must use `%md-sandbox` type
- Inline styles only in `%md-sandbox` cells (no classes or `<style>` elements)
- Use spacing and headings to separate sections, not horizontal rules

### Cell 1 - Title (markdown)

```markdown
# <Descriptive Notebook Title>

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

### Cell 2 - Setup (code)

For **local mode** (default):
```python
%load_ext pystackql.magic
```

For **server mode** (`--server` flag):
```python
%load_ext pystackql.magics
```

### Cell 3 - Pull providers (code)

```python
%stackql registry pull <provider>
```

One line per provider if multiple are needed.

### Cell 4 - Variables (code)

Define Python variables for parameterized queries:

```python
project = "your-project-id"
region = "us-central1"
```

Include all required WHERE clause parameters discovered in Step 2. Use sensible placeholder values and add comments telling the user to update them.

### Cell 5+ - Query sections

For each query/analysis, create a pair of cells:

**Markdown cell** with a section heading:
```markdown
## <Section Title>

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

**Code cell** with the StackQL query:

For single-line queries:
```python
%stackql SELECT name, status FROM <provider>.<service>.<resource> WHERE <required_params>
```

For multi-line queries:
```
%%stackql
SELECT
    name,
    status,
    <other_fields>
FROM <provider>.<service>.<resource>
WHERE <required_param> = '$variable'
ORDER BY name
```

### Visualization cells (optional)

Where results are suitable for visualization, add a code cell after the query:

**Simple bar chart:**
```python
stackql_df.plot(kind='bar', x='name', y='count', title='<Chart Title>');
```

**Custom matplotlib:**
```python
import matplotlib.pyplot as plt

fig, ax = plt.subplots(figsize=(10, 6))
ax.bar(stackql_df['<x_col>'], stackql_df['<y_col>'])
ax.set_xlabel('<X Label>')
ax.set_ylabel('<Y Label>')
ax.set_title('<Chart Title>')
plt.xticks(rotation=45, ha='right')
plt.tight_layout()
plt.show()
```

### Final cell - Summary/next steps (markdown)

```markdown
## Next Steps

- Modify the queries above to explore different resources
- Use `/stackql-skills:notebook-cell` to add more queries
- Use `/stackql-skills:query` for ad-hoc queries outside the notebook
```

## Step 5 - Key patterns to follow

### Variable substitution
Use `$variable` in queries where the value comes from a Python variable:
```sql
WHERE project = '$project' AND zone = '$zone'
```

### Dollar sign escaping
When the query needs a literal `$` (e.g., JSON path expressions), use `$$`:
```sql
JSON_EXTRACT(Properties, '$$.BucketName')
```

### Result access
- The last query result is always stored in `stackql_df` (pandas DataFrame)
- The `_` variable also references the last cell output (standard IPython)
- Use `%%stackql --no-display` to run a query without displaying the result
- Use `%%stackql --csv-download` to add a CSV download button

### Registry operations
Providers must be pulled before querying. Use line magic:
```python
%stackql registry pull <provider>
```

### Mutations
For INSERT, DELETE, EXEC, and REGISTRY operations, the magic command routes these automatically to the correct execution method.

## Step 6 - Report

Tell the user:
- The notebook path
- What provider(s) and resources are covered
- Remind them to update the variable values (project IDs, regions, etc.)
- How to run the notebook: `jupyter notebook <path>` or open in VS Code
- Note that `pystackql` must be installed: `pip install pystackql`

