> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pixeltable.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Working with the Pixeltable CLI

<a href="https://kaggle.com/kernels/welcome?src=https://github.com/pixeltable/pixeltable/blob/release/docs/release/howto/cookbooks/core/working-with-cli.ipynb" id="openKaggle" target="_blank" rel="noopener noreferrer"><img src="https://kaggle.com/static/images/open-in-kaggle.svg" alt="Open in Kaggle" style={{ display: 'inline', margin: '0px' }} noZoom /></a>  <a href="https://colab.research.google.com/github/pixeltable/pixeltable/blob/release/docs/release/howto/cookbooks/core/working-with-cli.ipynb" id="openColab" target="_blank" rel="noopener noreferrer"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open in Colab" style={{ display: 'inline', margin: '0px' }} noZoom /></a>  <a href="https://raw.githubusercontent.com/pixeltable/pixeltable/refs/tags/release/docs/release/howto/cookbooks/core/working-with-cli.ipynb" id="downloadNotebook" target="_blank" rel="noopener noreferrer"><img src="https://img.shields.io/badge/%E2%AC%87-Download%20Notebook-blue" alt="Download Notebook" style={{ display: 'inline', margin: '0px' }} noZoom /></a>

<Tip>This documentation page is also available as an interactive notebook. You can launch the notebook in
Kaggle or Colab, or download it for use with an IDE or local Jupyter installation, by clicking one of the
above links.</Tip>

## Problem

You defined a multimodal pipeline in Python and now need to inspect
tables, debug computed columns, roll back changes, and expose HTTP
endpoints without writing more application code. Jumping into a REPL or
building a custom admin UI for every project does not scale, especially
when AI agents need stable, machine-readable output.

## Solution

**What’s in this recipe:**

* Inspect catalogs with `pxt ls`, `describe`, `columns`, and `idxs`
* Query and debug rows with `pxt rows`, `count`, `get`, and `errors`
* Manage versions with `pxt history` and `pxt revert`
* Script and automate with `--json`, `-f`, and `pxt shell`
* Validate declarative HTTP serving with `pxt serve --dry-run`

The `pxt` CLI ships with Pixeltable (v0.6.5+). Catalog commands talk to
a local daemon (\~40 ms per call after the first invocation). Use Python
to define schema once, then operate the catalog from the terminal.

See the [CLI reference](/platform/cli) for
every flag.

### Setup

```python theme={"theme":{"light":"light-plus","dark":"dark-plus"}}
%pip install -qU 'pixeltable[serve]'
```

<pre style={{ 'margin': '-20px 20px 0px 20px', 'padding': '0px', 'background-color': 'transparent', 'color': 'black' }}>
  Note: you may need to restart the kernel to use updated packages.
</pre>

```python theme={"theme":{"light":"light-plus","dark":"dark-plus"}}
import json
import pixeltable as pxt
import subprocess
from pixeltable.functions.video import frame_iterator


def pxt_json(*args: str) -> object:
    """Run pxt with --json and parse stdout."""
    return json.loads(subprocess.check_output(['pxt', *args], text=True))
```

```python theme={"theme":{"light":"light-plus","dark":"dark-plus"}}
SAMPLE_VIDEO = 'https://raw.githubusercontent.com/pixeltable/pixeltable/release/docs/resources/bangkok.mp4'

pxt.drop_dir('cli_demo', force=True)
pxt.create_dir('cli_demo')

videos = pxt.create_table(
    'cli_demo/videos', {'video': pxt.Video, 'title': pxt.String}
)
frames = pxt.create_view(
    'cli_demo/frames',
    videos,
    iterator=frame_iterator(videos.video, fps=1),
)
frames.add_computed_column(thumb=frames.frame.thumbnail((320, 180)))

videos.insert([{'video': SAMPLE_VIDEO, 'title': 'Bangkok'}])
```

<pre style={{ 'margin': '-20px 20px 0px 20px', 'padding': '0px', 'background-color': 'transparent', 'color': 'black' }}>
  Connected to Pixeltable database at: postgresql+psycopg://postgres:@/pixeltable?host=/private/var/folders/s4/0zdx499s6sv3\_0jll6ccdbh00000gn/T/tmp.8rYgq6oxHN/.pxt-home/pgdata
  Created directory 'cli\_demo'.
  Created table 'videos'.
  Added 0 column values with 0 errors in 0.00 s
  Inserted 20 rows with 0 errors in 0.89 s (22.39 rows/s)
  20 rows inserted.
</pre>

<h3 id="inspect-the-catalog">
  1. Inspect the catalog
</h3>

List directories and tables, then drill into schema and computed
columns. Flag letters in `pxt ls -l`: `c` = computed column, `i` =
index.

```python theme={"theme":{"light":"light-plus","dark":"dark-plus"}}
!pxt ls -l cli_demo
!pxt describe cli_demo/videos
!pxt columns cli_demo/frames --computed
!pxt idxs cli_demo/frames
```

<pre style={{ 'margin': '-20px 20px 0px 20px', 'padding': '0px', 'background-color': 'transparent', 'color': 'black' }}>
  path             kind   cols  version  flags
  cli\_demo/frames  view      6        2  c
  cli\_demo/videos  table     2        1  i
  table 'cli\_demo/videos'

  ##  Column Name    Type  Source Computed With Comment

         video   Video  videos                      
         title  String  videos                      
  cli\_demo/frames thumb   Required\[Image] computed    frame.thumbnail(\[320, 180])
</pre>

<h3 id="query-rows">
  2. Query rows
</h3>

Peek at stored data from the terminal. Pass computed columns explicitly
with `--cols`; unstored computed columns are skipped by default.
Thumbnails may take a moment to compute after insert.

```python theme={"theme":{"light":"light-plus","dark":"dark-plus"}}
!pxt count cli_demo/frames
!pxt rows cli_demo/frames -n 1 --cols pos,thumb
```

<pre style={{ 'margin': '-20px 20px 0px 20px', 'padding': '0px', 'background-color': 'transparent', 'color': 'black' }}>
  19
  pos thumb
  0   \<Image 320x180 RGB>
</pre>

<h3 id="debug-computed-column-failures">
  3. Debug computed-column failures
</h3>

When a stored computed column fails, `pxt errors` lists the failing rows
by primary key.

```python theme={"theme":{"light":"light-plus","dark":"dark-plus"}}
@pxt.udf
def boom_if_zero(x: int) -> int:
    if x == 0:
        raise ValueError('boom')
    return x


failures = pxt.create_table(
    'cli_demo/failures', {'k': pxt.Required[pxt.Int]}, primary_key='k'
)
failures.add_computed_column(
    result=boom_if_zero(failures.k), on_error='ignore'
)
failures.insert([{'k': 0}, {'k': 1}], on_error='ignore')

!pxt errors cli_demo/failures
```

<pre style={{ 'margin': '-20px 20px 0px 20px', 'padding': '0px', 'background-color': 'transparent', 'color': 'black' }}>
  Created table 'failures'.
  Added 0 column values with 0 errors in 0.01 s
  Inserted 2 rows with 2 errors across 2 columns (failures.result, failures.None) in 0.00 s (400.31 rows/s)
  \{k: 0}  result  ValueError  boom
</pre>

<h3 id="version-control">
  4. Version control
</h3>

Every insert and schema change creates a new table version. Inspect the
timeline, then roll back if needed. See [Track changes and
revert](../../../howto/cookbooks/core/version-control-history) for the
Python API.

```python theme={"theme":{"light":"light-plus","dark":"dark-plus"}}
videos.add_computed_column(label=videos.title.upper())

!pxt history cli_demo/videos -n 5
!pxt revert cli_demo/videos -f
!pxt history cli_demo/videos -n 3
```

<pre style={{ 'margin': '-20px 20px 0px 20px', 'padding': '0px', 'background-color': 'transparent', 'color': 'black' }}>
  Added 1 column value with 0 errors in 0.02 s (51.20 rows/s)
  version created\_at  change\_type inserts updates deletes errors  schema\_change
  2   2026-06-12T23:39:11.848683Z schema  0   1   0   0   Added: label
  1   2026-06-12T23:39:08.810158Z data    20  0   0   0   
  0   2026-06-12T23:39:08.490587Z schema  0   0   0   0   Initial Version
  reverted cli\_demo/videos: v2 -> v1
  version created\_at  change\_type inserts updates deletes errors  schema\_change
  1   2026-06-12T23:39:08.810158Z data    20  0   0   0   
  0   2026-06-12T23:39:08.490587Z schema  0   0   0   0   Initial Version
</pre>

<h3 id="agent-friendly-scripting">
  5. Agent-friendly scripting
</h3>

Most catalog commands accept `--json` for stable, machine-readable
output. Use `-f` to skip confirmation prompts in non-interactive
contexts.

For many commands in one session, `pxt shell` keeps the daemon warm:

```bash theme={"theme":{"light":"light-plus","dark":"dark-plus"}}
pxt shell
pxt> ls cli_demo
pxt> count cli_demo/frames
pxt> exit
```

```python theme={"theme":{"light":"light-plus","dark":"dark-plus"}}
tables = [
    e['path']
    for e in pxt_json('ls', 'cli_demo', '--json')['entries']
    if e['kind'] == 'table'
]
print('tables:', tables)
print(
    'frame count:',
    pxt_json('count', 'cli_demo/frames', '--json')['count'],
)
```

<pre style={{ 'margin': '-20px 20px 0px 20px', 'padding': '0px', 'background-color': 'transparent', 'color': 'black' }}>
  tables: \['cli\_demo/failures', 'cli\_demo/videos']
  frame count: 0
</pre>

<h3 id="config-and-health">
  6. Config and health
</h3>

Check daemon health, runtime status, and resolved configuration (API
keys show as `<redacted>` when set). See [Configure API
keys](../../../howto/cookbooks/core/workflow-api-keys) for credential
setup.

```python theme={"theme":{"light":"light-plus","dark":"dark-plus"}}
!pxt health
!pxt status
!pxt config --section openai
```

<pre style={{ 'margin': '-20px 20px 0px 20px', 'padding': '0px', 'background-color': 'transparent', 'color': 'black' }}>
  \{
    "ok": true,
    "service": "pxt",
    "pxt\_version": "0.6.5",
    "pid": 52061,
    "started\_at": "2026-06-12T23:09:23.075920+00:00",
    "pxt\_install\_dir": "/opt/miniconda3/envs/pxt/lib/python3.10/site-packages/pixeltable",
    "python\_executable": "/opt/miniconda3/envs/pxt/bin/python",
    "pixeltable\_home": "/private/var/folders/s4/0zdx499s6sv3\_0jll6ccdbh00000gn/T/tmp.8rYgq6oxHN/.pxt-home",
    "pixeltable\_pgdata": "/private/var/folders/s4/0zdx499s6sv3\_0jll6ccdbh00000gn/T/tmp.8rYgq6oxHN/.pxt-home/pgdata",
    "pixeltable\_config\_file": "/private/var/folders/s4/0zdx499s6sv3\_0jll6ccdbh00000gn/T/tmp.8rYgq6oxHN/.pxt-home/config.toml",
    "pixeltable\_env": \{
      "PIXELTABLE\_HOME": "/var/folders/s4/0zdx499s6sv3\_0jll6ccdbh00000gn/T/tmp.8rYgq6oxHN/.pxt-home"
    }
  }
  pxt\_version     0.6.5.dev24+8a39208c
  daemon\_pid      52061
  daemon\_started  2026-06-12T23:09:23.075920+00:00
  home            /var/folders/s4/0zdx499s6sv3\_0jll6ccdbh00000gn/T/tmp.8rYgq6oxHN/.pxt-home
  db\_url          postgresql+psycopg://postgres:\*\*\*@/pixeltable?host=%2Fprivate%2Fvar%2Ffolders%2Fs4%2F0zdx499s6sv3\_0jll6ccdbh00000gn%2FT%2Ftmp.8rYgq6oxHN%2F.pxt-home%2Fpgdata
  media\_dir       /var/folders/s4/0zdx499s6sv3\_0jll6ccdbh00000gn/T/tmp.8rYgq6oxHN/.pxt-home/media
  file\_cache\_dir  /var/folders/s4/0zdx499s6sv3\_0jll6ccdbh00000gn/T/tmp.8rYgq6oxHN/.pxt-home/file\_cache
  total\_tables    7
  total\_errors    2
  config\_file  /var/folders/s4/0zdx499s6sv3\_0jll6ccdbh00000gn/T/tmp.8rYgq6oxHN/.pxt-home/config.toml
  not set: openai.api\_key, openai.base\_url, openai.api\_version, openai.rate\_limits, openai.max\_connections, openai.max\_keepalive\_connections, openai.read\_timeout, openai.write\_timeout
</pre>

<h3 id="serve-without-application-code">
  7. Serve without application code
</h3>

Validate an insert endpoint with `--dry-run --json` (no server started).
For production, declare routes in `pyproject.toml` — see [HTTP
Serving](/howto/deployment/serving).

Full live flow:

```bash theme={"theme":{"light":"light-plus","dark":"dark-plus"}}
pxt serve insert --table cli_demo/videos --path /videos --inputs video title --outputs title
curl -X POST localhost:8000/videos -H 'Content-Type: application/json' \
  -d '{"video": "https://raw.githubusercontent.com/pixeltable/pixeltable/release/docs/resources/bangkok.mp4", "title": "Bangkok"}'
pxt rows cli_demo/frames -n 1 --cols pos,thumb
```

```python theme={"theme":{"light":"light-plus","dark":"dark-plus"}}
!pxt serve insert --table cli_demo/videos --path /videos --inputs video title --outputs title --dry-run --json
```

<pre style={{ 'margin': '-20px 20px 0px 20px', 'padding': '0px', 'background-color': 'transparent', 'color': 'black' }}>
  \{
    "name": "pxt-serve",
    "prefix": "",
    "host": "0.0.0.0",
    "port": 8000,
    "routes": \[
      \{
        "path": "/videos",
        "background": false,
        "type": "insert",
        "table": "cli\_demo/videos",
        "inputs": \[
          "video",
          "title"
        ],
        "uploadfile\_inputs": null,
        "outputs": \[
          "title"
        ],
        "return\_fileresponse": false,
        "export\_sql": null
      }
    ]
  }
</pre>

### Next steps

* [CLI reference](/platform/cli): every
  command and flag
* [Dashboard](/platform/dashboard): browse
  tables and preview media in the browser
* [HTTP Serving](/howto/deployment/serving):
  production TOML and `FastAPIRouter`
* [Building with
  LLMs](/overview/building-pixeltable-with-llms):
  agent skills, MCP, and `pxt --json` workflows
