pxt CLI ships with the pixeltable package. It covers two surfaces:
- Catalog operations — inspect, query, and manage tables, views, and directories. Backed by a long-lived local daemon so each command takes ~40 ms after the first invocation.
-
Service deployment — turn tables, computed columns, and
@pxt.queryfunctions into HTTP endpoints withpxt serve, and publish them withpxt deploy.pxt serverequires theserveextra (which pulls infastapi[standard]anduvicorn):
pxt auto-spawns a daemon bound to 127.0.0.1:22089. The daemon survives across shells and stays warm for subsequent commands. Override the port with PXT_PORT.
Command structure
pxt <command> --help for per-subcommand flags and examples.
Universal flags
These flags work the same way across the catalog commands that support them and are not repeated in the per-command tables below.Working directory
pxt cd sets a working directory that is prepended to relative paths in later commands, and pxt pwd prints it — the catalog analogue of a shell’s cd/pwd.
/ (e.g. pxt ls /other_dir) resolves from the catalog root, and a pxt://org:db/... URI addresses a hosted catalog. . and .. work in any path and resolve against the working directory; .. at the catalog root keeps the root.
The working directory is scoped to the invoking terminal, not the daemon globally — it is keyed by the shell’s session, sent with every command. So separate terminals have independent working directories, and, crucially, it does not leak into subprocesses or agents you launch: a spawned process runs under its own session with no working directory, so its pxt commands resolve relative paths from the catalog root regardless of what you set interactively.
Because of that isolation, scripts and agents should address the catalog with absolute paths (/... or pxt://...) and ignore the working directory; it is a convenience for interactive terminal use.
Quick reference
Inspection commands
pxt ls
List entries under a directory.
pxt ls -l:
c = has at least one computed column, i = has at least one index.
pxt describe
Show a table’s schema and metadata. The plain form is human-readable; --json returns the full get_metadata() dict.
pxt columns / pxt computed
List columns for one or more tables. pxt computed is shorthand for pxt columns --computed. The path argument may be a single table or a directory; a directory path lists columns for every table beneath it, recursively. A directory path may be a local path or a hosted uri (pxt://org:db/...). With no path, every table in the in-process catalog is listed.
pxt idxs
List indexes. Shows both B-tree and embedding indexes by default; the --embedding flag restricts to embedding indexes. Like pxt columns, the path may be a single table or a directory (walked recursively), a hosted database root (pxt://org:db), or omitted for the whole in-process catalog.
pxt history
Show a table’s version timeline.
pxt status
Daemon and runtime state: pxt version, daemon PID, configured paths, total tables, total errors.
pxt config
Every documented configuration setting with its current value and source (env, file, or unset). Credentials show <redacted> when set; the source column reveals presence even when the value is masked.
Query commands
pxt rows
Show the first N rows of a table. Unstored computed columns are skipped by default (selecting one forces evaluation, which can invoke LLMs or expensive compute); pass them explicitly via --cols to include them.
pxt get
Look up a single row by primary key. A numeric-looking PK token is coerced to int or float; everything else stays a string. There is no quoting escape for a string-typed PK whose value looks numeric — if your PK column is a string but the value is 42, the server will reject the type mismatch. The table must declare a primary key. Unstored computed columns are skipped unless requested explicitly via --cols (consistent with rows).
pxt count
pxt errors
List rows where a stored computed column failed. The table must have a primary key (so each failing row can be identified).
Mutation commands
Every mutation accepts the universal-n/--dry-run and --json flags. The destructive ones (drop, drop-dir, revert) also prompt [y/N] with a TTY and accept -f/--force to skip the prompt; in non-interactive contexts they refuse to proceed without -f. rename and mv don’t prompt: renaming or moving a catalog entry is reversible and doesn’t lose data.
pxt drop
Drop a table or view. Use pxt drop-dir for directories.
pxt drop-dir
Remove a directory. Use pxt drop for tables/views.
pxt rename
Rename in place; the parent directory is preserved. <new_name> must be a single leaf name (no / or .). Takes only universal flags.
pxt mv
Move a table/view/dir under a different directory; the leaf name is preserved. <new_dir> can be '' or / for the root directory. Takes only universal flags.
pxt revert
Undo recent ops on a table. Each revert undoes one op; --steps repeats.
Schema management
The commands above act on one object at a time.pxt schema works differently: you describe the tables you want in a Python file, and the CLI reconciles a catalog directory to that description. Provisioning an empty target and evolving an existing one are the same command, so there is no separate first-time step.
SCHEMA is a path to a Python file. TARGET is a catalog directory or a pxt:// URI; it is created by update if it doesn’t exist.
The schema file
A schema file defines one or more models on apxt.model_base(). Each model becomes one table, named by name=. pxt schema example writes a file covering every construct the schema DSL supports, so you never have to start from a blank page and never have to look a construct up:
pxt schema example --brief writes the minimal version instead:
name: type) declares a stored column; an assignment (name = expr) declares a computed column. A model with base= becomes a view of the model that query selects from.
The daemon imports the file, so it must be readable there. Its own directory is added to sys.path, so it can import modules sitting next to it.
Reviewing and applying
diff prints one line per table, then one per operation:
Applying
update creates missing tables and migrates existing ones, adding and dropping columns and indexes. It takes the same flags as the other mutations, plus one of its own:
--allow-destructive is absent, nothing at all is applied and update exits 3.
Some differences cannot be applied in place: a table declared where a view exists, a changed iterator, or a column whose type or properties changed. Those are reported as UNSUPPORTED, nothing is applied, and update exits 1. Adjust the schema file or the table by hand.
Exit codes
The schema commands report their outcome in the exit status, so a caller never has to parse the output:
A drift check in CI is therefore one command:
Machine-readable plans
pxt schema diff --json emits the whole plan as one object: schema_file, catalog_dir, in_agreement, tables, extras, and a summary with one count per resolution. Each entry in tables carries its path, resolution, whether it is destructive, and its ops:
target is column, index, or table, and its op is add, drop, or alter. name is what it acts on — a column, an index, the differing attribute when the target is a table, or the table path for a drop — and details holds that operation’s operands, such as the type of an added column. severity is additive, destructive, or unsupported; destructive is the boolean form of the middle case. A table’s resolution is up_to_date, create, update_additive, update_destructive, or unsupported, and one with create carries no ops, because the create subsumes them.
These field names and values are the catalog’s own, as returned by TableModel.get_model_diff(), so a plan read from the CLI and a diff read from Python describe a change the same way.
update and prune return the same object with a status on every table and operation:
Every path returns the plan, including the ones that refuse before reaching the daemon, so an
--allow-destructive refusal is as machine-readable as a success: exit 3, with the offending operations marked refused and the rest skipped. prune reports its drops in a top-level ops array, each with target: "table", op: "drop", and the dropped table’s path in name.
Pruning
update only ever touches tables the schema declares, so tables it doesn’t know about accumulate. diff lists them as extras; prune drops them. A full reconcile is update followed by prune.
TARGET are considered, so nothing elsewhere in the catalog is affected, and declared tables are never dropped. A view is dropped before its base. Prune never force-drops: a table that something outside the pruned set depends on is left in place and the drop fails, naming what depends on it.
Interactive shell
For agentic or scripted workloads that issue many commands in sequence,pxt shell amortizes Python startup over the session:
pxt command is available unmodified. Errors from one command don’t kill the session. Use help, exit, quit, or Ctrl-D to leave.
Output and scripting
Most catalog commands accept--json for stable, machine-readable output (exceptions: shell is interactive, health is already JSON):
--json, output is column-aligned text.
The schema commands additionally report drift in their exit status (0 in sync, 2 pending, 3 refused, 1 error), so a CI gate needs no output parsing at all.
Serving
pxt serve turns tables, computed columns, and @pxt.query functions into HTTP endpoints, no application code required. The serve and deploy subcommands import pixeltable directly and require the serve extra (pip install 'pixeltable[serve]'), which pulls in fastapi[standard] and uvicorn.
pxt serve generates a full FastAPI application with auto-generated OpenAPI docs at /docs. For programmatic control over the same endpoints, see the Python serving API using FastAPIRouter.pxt serve subcommands
Quick start
Named service (TOML config)
Define your routes in a TOML file and start everything with one command:Output
Single-endpoint mode
For quick experiments, skip the TOML file and configure one route directly:Serve flags
Everypxt serve subcommand accepts these flags:
When
--json is set, a successful start emits:
--dry-run and --json to validate a config in CI without starting a server:
pxt serve insert
Start a service with a single insert endpoint.
SQL export flags are also available on insert and update routes. See SQL export flags.
pxt serve update
Start a service with a single update endpoint. The table must have a primary key.
pxt serve delete
Start a service with a single delete endpoint.
pxt serve query
Start a service with a single query endpoint.
The dotted path is resolved at startup; the module is imported automatically.
SQL export flags
Insert and update routes can export each successful request as a row in an external SQL database. These flags mirror theexport_sql TOML config:
Serve patterns
Validate a config without starting a server
Output
Override port for local development
File upload endpoint
Background processing for slow pipelines
job_url until status is "done" or "error".
Cloud
pxt db, pxt service, and pxt org manage cloud-hosted databases, services, and organizations. All cloud commands require PIXELTABLE_API_KEY to be configured (see Configuration).
All cloud commands accept --json for machine-readable output.
pixeltable.toml reference
Cloud operations that affect a database’s runtime image or service routes read configuration from pixeltable.toml in the current directory.
[pixeltable.database] — runtime bundle config
Read by pxt db update-runtime. Defines which local files to bundle and, optionally, a custom Pixeltable source branch.
[[pixeltable.service]] — service route config
Read by pxt service create and pxt service update. Each [[pixeltable.service]] block defines one named service; name must match the service name argument passed to pxt service create.
pxt db
Manage cloud-hosted Pixeltable databases. A database is a hosted Pixeltable instance with its own compute, storage, and Python runtime.
Database URIs use the form pxt://org:db. States: PROVISIONING → AVAILABLE ⇄ STOPPED → UPDATING → DELETING.
The URI argument is optional: with it omitted, these commands use db_uri from the Pixeltable config file (see Configuration), so a project that sets it can run pxt db status and friends with no argument.
pxt db create
Provisions a new database. Polls until state is
AVAILABLE.
pxt db list
pxt db status
pxt db start
AVAILABLE.
pxt db stop
pxt db update
Triggers a rolling restart; polls until
AVAILABLE.
pxt db update-runtime
[pixeltable.database] from pixeltable.toml in the current directory, packages the project bundle, uploads it, and triggers a CodeBuild image rebuild. Polls until the build completes or fails. Running services are restarted on the new image automatically.
pxt db delete
pxt service
Manage cloud-hosted services. A service exposes a table in a cloud database as an HTTPS endpoint. Service URIs use the form pxt://org:db/services/<name>.
States: DEPLOYING → AVAILABLE ⇄ STOPPED → UPDATING → FAILED.
pxt service create
Reads route config from the
[[pixeltable.service]] block matching name in pixeltable.toml. Polls until AVAILABLE.
pxt service list
pxt service status
pxt service start
pxt service stop
pxt service update
Re-reads
[[pixeltable.service]] from pixeltable.toml for route config changes. Triggers a rolling restart if routes changed; polls until AVAILABLE.
pxt service delete
pxt org
pxt org list
pxt org status
What’s next
- Working with the Pixeltable CLI: hands-on cookbook for inspect, query, debug, and serve workflows
- HTTP Serving Guide: TOML config reference, Python
FastAPIRouterAPI, decorator routes - Configuration: API keys, storage paths, and environment settings