Use the CLI
VGI ships two command-line tools so you can exercise a worker without writing any Python:
vgi-client invokes functions and drives catalog operations against a worker, and vgi-serve runs
any worker over stdio or HTTP. This page covers the everyday commands; for the full subcommand and
flag surface see the CLI reference.
Install
Section titled “Install”Both commands install with the package:
pip install vgi-python
# For the bundled example worker (vgi-fixture-worker) used in the examples below:
pip install vgi-python[fixtures]
vgi-client and vgi-serve are registered as console scripts. The examples here use
vgi-fixture-worker, the built-in demo worker, as the target.
Call a function
Section titled “Call a function”Use --function to invoke a function on a worker. Table functions generate data and need no input;
table-in-out and scalar functions read a Parquet file via --input.
# Table function: generate a sequence of 10 integers
vgi-client --function sequence --args '[10]' --worker vgi-fixture-worker
# Table-in-out function: transform a Parquet file
vgi-client --input data.parquet --function echo --worker vgi-fixture-worker
# Scalar function: per-row transform, single output column
vgi-client --input data.parquet --function upper_case --type scalar --worker vgi-fixture-worker
Arguments are passed as a JSON array with --args (e.g. '[100]', '["price", 2]'). Named
arguments use --named-arg key=value. The default worker is vgi-fixture-worker, so --worker can
be omitted when targeting it.
--schema names the catalog schema that declares the function, defaulting to main. You only need
it when a worker registers the same function name in more than one schema — since 0.18.0 resolution
is keyed on (schema, name), so the pair is what identifies an implementation:
vgi-client --function transform --schema analytics --args '[10]'
Choose an output format
Section titled “Choose an output format”vgi-client writes JSON Lines to stdout by default. Use --format for CSV, Parquet, or Arrow IPC,
and --output / -o to write to a file (- means stdout).
# Default: JSON Lines on stdout
vgi-client --function sequence --args '[3]'
# CSV
vgi-client --function sequence --args '[3]' --format csv
# Parquet to a file
vgi-client --function sequence --args '[1000]' --format parquet --output data.parquet
See Output formats for the full list,
including arrow-ipc for debugging.
Inspect a catalog
Section titled “Inspect a catalog”Catalog operations live under the catalog subcommand. List catalogs, then attach to one to drive
schema, table, view, and transaction commands. Stateless catalogs accept --catalog <name> for
auto-attach; stateful catalogs should capture an attach ID.
# List catalogs exposed by a worker
vgi-client catalog list --worker ./worker.py
# Auto-attach by name and list schemas
vgi-client catalog schema list --catalog mydb --worker ./worker.py
# Explicit attach for stateful catalogs
ATTACH_ID=$(vgi-client catalog attach mydb --worker ./worker.py | jq -r '.attach_opaque_data')
vgi-client catalog schema list --attach-opaque-data $ATTACH_ID --worker ./worker.py
vgi-client catalog detach $ATTACH_ID --worker ./worker.py
The full catalog, schema, table, column, view, and transaction subcommands are documented in the CLI reference.
Serve a worker
Section titled “Serve a worker”vgi-serve loads any worker by module reference or file path and serves it — stdio by default (for
subprocess use by vgi-client or DuckDB), or --http for cloud deployment.
# Stdio (default) — pipe transport
vgi-serve my_worker.py
vgi-serve my_app.workers:ProductionWorker
# HTTP
vgi-serve my_worker.py --http --host 0.0.0.0 --port 8080
# HTTP on granian (Rust I/O, off the GIL) with four forked workers
vgi-serve my_worker.py --http --server granian --http-workers 4
# Raw Arrow IPC over TCP — no auth, no encryption: trusted networks only
vgi-serve my_worker.py --tcp 127.0.0.1:9000
A worker reference can be module:Class, a bare module (auto-discovers the single Worker
subclass), or a ./file.py path with an optional :ClassName suffix. --tcp is mutually exclusive
with --http and --unix, and --http-workers applies only to granian. Production flags —
response-size caps, the shared signing key every multi-process deployment needs, proxy
introspection — are covered in Serve over HTTP.
Control worker logging
Section titled “Control worker logging”Every worker started with vgi-serve (and vgi-fixture-worker) accepts logging flags. Logs are
written to stderr.
# Enable DEBUG logging on all vgi + vgi_rpc loggers
vgi-serve my_worker.py --debug
# Set WARNING level only
vgi-serve my_worker.py --log-level WARNING
# Target a specific logger at DEBUG
vgi-serve my_worker.py --log-level DEBUG --log-logger vgi.worker
# JSON-formatted logs for structured pipelines
vgi-serve my_worker.py --log-format json
--debug overrides --log-level when both are set. For the list of named loggers, environment
variables, and OpenTelemetry configuration, see Worker
logging in the reference.
Ask the engine what a worker offers
Section titled “Ask the engine what a worker offers”Once a catalog is attached, the extension exposes table functions that report what it advertised. These answer “did my declaration actually land?” without reading any Python:
| Function | Reports |
|---|---|
vgi_function_arguments() | Every function’s arguments — types, defaults, doc strings, and the declared constraints (choices, ranges, patterns). |
vgi_copy_formats() | Custom COPY formats, each with its direction and option schema. |
vgi_global_functions() | Global functions currently published, who owns each name, and whether it is still live. |
SELECT * FROM vgi_copy_formats();
SELECT * FROM vgi_function_arguments() WHERE function_name = 'geo_encode';
An HTTP worker also serves a browsable landing page at its root that reads the catalog over the
protocol — schemas, functions, macros, and argument types. Disable it with --no-describe.
Next steps
Section titled “Next steps”- CLI reference — every command, flag, environment variable, and the bundled fixture functions.
- Function patterns — writing the functions you invoke here.