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.
Overview
Pixeltable can expose table operations and queries as HTTP endpoints viapixeltable.serving.FastAPIRouter. You can configure endpoints either
programmatically in Python or declaratively with a TOML service file.
FastAPI and uvicorn are optional dependencies. Install them before using
pxt serve or the Python serving API:
Quickstart (TOML)
Add a[tool.pixeltable] section to your pyproject.toml:
You can also use a standalone TOML file (
pxt serve my-service --config service.toml) with the same route syntax but [[service]] and [[service.routes]] as top-level keys. The pyproject.toml format is preferred for new projects.http://localhost:8000 with auto-generated
OpenAPI docs at /docs.
Quickstart (Python)
Quickstart (single-endpoint CLI)
For quick experiments and one-off endpoints, you can skip the TOML file and configure a single route directly on the command line:[[service.routes]]
TOML entry. It is meant for development and ad-hoc serving; for anything
beyond that use the TOML file (it is the only way to expose more than one
endpoint).
Decorator-style routes
add_insert_route() / add_update_route() build a response model automatically
from the column schema. When you need a different response shape — e.g. a
richer API envelope, derived fields, or a stripped-down payload — use the
@router.insert_route / @router.update_route decorators. The decorated
function receives the requested output columns as keyword arguments and returns
a pydantic.BaseModel subclass that defines the HTTP response body.
- Every parameter must be keyword-only and have a type annotation.
- Every parameter name must appear in
outputs, and everyoutputsentry must be a parameter. - Parameter annotations must match the column types (strict nullability: a
nullable column requires
T | None). Media columns are delivered as URL strings, so annotate them asstr. - The return annotation must be a
pydantic.BaseModelsubclass.
background=True flag as the non-decorator
forms; when enabled, the decorated function’s return value is delivered as the
background-job result.
The decorator forms are Python-only — there is no equivalent in the TOML
service file.
Exporting rows to an external database
Insert and update routes can export each successful request as a row in an external SQL database. Configure it via the Python API, the TOML service file, or the CLI; all three forms route through the sameSqlExport specification.
Each request performs the Pixeltable insert/update first; only if it succeeds
does the row get written to the external table.
Python API. Pass an export_sql=SqlExport(...) argument to
add_insert_route, add_update_route, or the decorator forms.
[routes.export_sql] table under any insert or update
route. The same fields apply.
--export-sql-*
flags on pxt serve insert and pxt serve update.
outputs, with media-typed columns rendered as URL strings (so the
corresponding target columns must be string-typed). Schema compatibility is
validated once at registration; the target table must already exist or
registration fails. The engine and connection pool are cached per
db_connect, so multiple routes pointing at the same database share one pool.
SqlExport.method controls how each row is written:
'insert'(default): append the row viaINSERT ... VALUES. The target acts as an audit log — replaying the same request produces a duplicate.'update': update the row by primary-key match. The target is treated as a current-state view keyed on its primary key. The response columns must include all primary-key columns of the target plus at least one non-PK column to set; the target table itself must declare a primary key. This is a strict update, not an upsert — if no row matches, the request fails with HTTP 500.'merge'(upsert): not yet supported.
add_insert_route and method='update', a Pixeltable insert
triggers a target-side update. This is intentional: it supports the pattern
where the Pixeltable table is append-only (e.g. an event log) but the target
is a deduplicated, current-state view.
If the external write fails after the Pixeltable insert/update has already
committed, the request returns HTTP 500; no rollback is performed.
export_sql= is mutually exclusive with return_fileresponse=True and is
compatible with background=True (the SQL write runs in the worker thread).
See SqlExport
for the full target specification.
TOML Service File Reference
[service] (optional)
Top-level settings for the FastAPI application and server.
| Field | Type | Default | Description |
|---|---|---|---|
title | string | "Pixeltable" | Title shown in the OpenAPI docs |
prefix | string | "" | URL prefix prepended to all route paths (must be empty or start with /) |
host | string | "0.0.0.0" | Server bind address |
port | integer | 8000 | Server bind port |
modules (optional)
A list of additional Python modules to import at startup, for their
registration side effects. The module that hosts a query route’s dotted
path is imported automatically, so this is only needed when you depend
on @pxt.query / @pxt.udf definitions in other modules that wouldn’t
otherwise be loaded.
[[service.routes]]
Each [[service.routes]] entry defines one HTTP endpoint. The type field determines
the route kind and which additional fields are valid.
Common fields
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
type | "insert" / "update" / "delete" / "query" | yes | — | Route kind |
path | string | yes | — | URL path (e.g., "/generate") |
background | bool | no | false | Run the operation in a background thread and return a job handle |
background = true, the endpoint returns immediately with:
job_url until status is "done" or "error".
Insert routes
Insert a single row into a table and return the resulting column values.| Field | Type | Required | Default | Description |
|---|---|---|---|---|
table | string | yes | — | Pixeltable table path |
inputs | list of strings | no | all non-computed columns | Columns to accept as request fields |
uploadfile_inputs | list of strings | no | — | Columns to accept as file uploads (multipart) |
outputs | list of strings | no | all columns | Columns to include in the response |
return_fileresponse | bool | no | false | Return the single media-typed output as a raw file download |
export_sql | nested table | no | — | Export each request as a row into an external SQL database. See Exporting rows to an external database. |
uploadfile_inputs is set, the request uses multipart/form-data
instead of JSON. All other inputs become form fields.
Update routes
Update a single row identified by its primary key values, and return the updated columns (including any computed columns that depend on them).| Field | Type | Required | Default | Description |
|---|---|---|---|---|
table | string | yes | — | Pixeltable table path (must have a primary key) |
inputs | list of strings | no | all non-PK, non-computed, non-media columns | Columns to update (PK columns are always in the request body but cannot appear here) |
outputs | list of strings | no | all columns | Columns to include in the response |
return_fileresponse | bool | no | false | Return the single media-typed output as a raw file download |
export_sql | nested table | no | — | Export each request as a row into an external SQL database. See Exporting rows to an external database. |
Media-typed columns (image, video, audio, document) cannot currently be
updated. To replace a media value, delete the row and insert a new one.
Delete routes use HTTP POST, not the HTTP DELETE method. Update client-side fetch calls accordingly.
Delete routes
Delete rows matching the given column values and return the count of rows affected.| Field | Type | Required | Default | Description |
|---|---|---|---|---|
table | string | yes | — | Pixeltable table path |
match_columns | list of strings | no | primary key columns | Columns to match on (AND-ed equality) |
Media columns (
pxt.Image, pxt.Video, pxt.Audio, pxt.Document) serialize as URL strings (e.g., /media/path/to/file.pdf). The client receives a string, not binary data.Query routes
Execute a@pxt.query or retrieval_udf function and return the results.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
query | string | yes | — | Dotted Python path to a @pxt.query or retrieval_udf function |
inputs | list of strings | no | all query parameters | Parameters to accept as request fields |
uploadfile_inputs | list of strings | no | — | Parameters to accept as file uploads (not supported with method = "get") |
one_row | bool | no | false | Expect exactly one result row (404 on 0, 409 on >1) |
return_fileresponse | bool | no | false | Return the single media-typed result as a raw file |
method | "get" / "post" | no | "post" | HTTP method for the endpoint |
query field is a dotted Python path (e.g., "myapp.queries.search_docs");
the module portion is imported automatically when the route is resolved.
Multi-row response (default):
one_row = true):
Full example
Reading Back Computed Columns After Insert
Usereturn_rows=True to get all column values (including computed columns)
directly from insert(), update(), or batch_update() without a follow-up
query.
status.rows is a list of plain dicts. For typed access, use Pydantic’s
model_validate() with extra="ignore" (row dicts contain every column;
ignore the ones you don’t need):
return_rows=True— any time you insert a row with computed columns and need the results backto_pydantic()— when reading from aResultSet(after.collect())model_validate()— when reading fromstatus.rows(plain dicts fromreturn_rows=True)
Background jobs
Any route can setbackground = true. The endpoint returns immediately with a
job handle:
background is mutually exclusive with return_fileresponse.
CLI Reference
For the fullpxt command-line reference (all subcommands, flags, and usage patterns), see the dedicated CLI Reference page.
Quick examples: