Skip to content

CLI

pip install "scriva[cli]" adds the scriva command. It exposes the top-level library APIs without the Python boilerplate, and is the right shape for cron jobs, CI checks, and ad-hoc one-shots.

Terminal window
scriva --help
scriva read Read text from an image or PDF
scriva extract Extract structured data against a schema or preset
scriva classify Guess the document kind
scriva batch Run extraction over many files
scriva watch Watch a folder and extract new files as they arrive
scriva eval Score a recipe against ground-truth annotations
scriva annotate Interactive annotation loop (primary + oracle Workers)
scriva serve Start a small HTTP service exposing the same commands
scriva cache Inspect / prune the Worker cache
scriva samples Inspect / export a sample store
scriva version Print version and installed extras

Internally every subcommand calls into the same pillars the Python API uses — scriva extract resolves a preset into an Orchestrator recipe, scriva read wires a Worker into a minimal recipe, and so on.

Global flags work on every subcommand:

FlagDefaultNotes
--log-levelinfodebug, info, warning, error
--log-formattexttext, json (one record per line)
--cache.scriva_cachePath or none
--quiet / --verboseShortcuts over --log-level
--no-colorForce monochrome
--config./scriva.tomlTOML config file (see Config file)

Exit codes: 0 success, 1 configuration error, 2 engine error, 3 validation error, 4 budget exceeded, 5 timeout, 130 interrupted.

Terminal window
scriva read scan.png
scriva read scan.pdf --to out.txt
scriva read scan.png --as json
scriva read scan.png --as dataframe --to out.csv
scriva read scan.png --worker anthropic --model claude-opus-4-7

Output formats: text (default), json, markdown, dataframe (CSV when written to a file). --to writes; without it, prints to stdout. --worker picks the engine factory (openai, anthropic, bedrock, tesseract, paddle, azure).

Terminal window
scriva extract acme.pdf --schema invoice
scriva extract acme.pdf --schema scriva.schemas.Invoice -o invoice.json
scriva extract acme.pdf --preset invoice
scriva extract acme.pdf --schema my_pkg.MyInvoice # any importable BaseModel
scriva extract acme.pdf # auto-classify

--schema accepts:

  • A registered preset name (invoice, receipt, …) — same as --preset.
  • A fully-qualified Python path (scriva.schemas.Invoice, my_pkg.Foo).
  • A path to a .py file containing a top-level Schema class.
  • A path to a JSON-Schema .json file.

Options:

FlagNotes
-o, --outOutput file. - for stdout (default).
--formatjson (default), yaml, toml, csv (for schemas with line_items).
--modelOverride the Worker engine model.
--localeen, ja, auto, …
--timeoutSeconds. Default unlimited.
--max-costUSD cap. Default unlimited.
--return-resultEmit the full DocumentResult JSON, not just .fields.
--show-eventsPrint SSE-style events to stderr.
Terminal window
scriva classify unknown.pdf
# -> invoice (confidence 0.91)
scriva classify unknown.pdf --json
# -> {"kind": "invoice", "confidence": 0.91, "runner_up": "purchase_order"}
scriva classify unknown.pdf --candidates invoice,purchase_order,quote

Useful in shell pipelines as a router:

Terminal window
KIND=$(scriva classify "$1" --format raw)
case "$KIND" in
invoice) scriva extract "$1" --preset invoice -o "$1.json" ;;
receipt) scriva extract "$1" --preset receipt -o "$1.json" ;;
*) echo "unsupported kind: $KIND"; exit 1 ;;
esac
Terminal window
scriva batch ./incoming/*.pdf --schema invoice --out ./extracted/
FlagNotes
--schema/--presetAs scriva extract.
--outDestination directory; files are written as <stem>.json.
--concurrencyDefault 4.
--on-errorraise, continue (default), collect.
--resumeLedger file (default .scriva_batch.json).
--max-costTotal USD cap across the batch.
--progressForce progress bar on/off.
--dry-runPlan only, no Worker calls.

A failed batch writes a summary to --resume so re-running picks up where it left off; combine with --on-error=continue for resilient overnight ingest.

Terminal window
scriva watch ./incoming --to ./extracted --schema invoice
scriva watch ./incoming --to s3://my-bucket/out/ --schema invoice
scriva watch ./incoming --to https://api.example.com/extract --schema invoice --webhook-token "$TOKEN"

The --to target can be:

  • A directory path (writes one JSON per source).
  • An s3:// URL (uses boto3; needs scriva[s3]).
  • An https:// URL (POSTs each result; --webhook-token adds an Authorization header).
  • sqlite:///path/to.db or postgres://... for DB sinks.
  • gsheets://<sheet-id>/<tab> (needs scriva[gsheets]).

Other flags:

FlagNotes
--patternGlob filter, e.g. "*.pdf". Default "*".
--move-on-successMove source to <to>/.done/. Default false.
--move-on-errorMove source to a quarantine folder. Default false.
--poll-intervalSeconds; only used when inotify is unavailable.
--max-costPer-file cap.
--workersPer-folder concurrency.

Send SIGTERM for graceful drain: in-flight extractions finish, the ledger is flushed, and the process exits 0.

Terminal window
scriva eval ./recipe.py --ground-truth ./annotations/
scriva eval --preset invoice --ground-truth ./annotations/invoices/

Loads each ground-truth JSON alongside its matching source file, runs the recipe, and reports field-level precision / recall / F1 plus calibration plots. --report emits Markdown; --report-html emits a self-contained HTML page with confusion tables.

The first positional may be a Python file with a top-level recipe (or pipeline for backwards compat) attribute, an importable Python path (my_pkg.recipes:invoice), or omitted in favour of --preset.

CI-gate flags:

FlagNotes
--min-f1Exit non-zero if F1 falls below this.
--min-precisionSame for precision.
--min-recallSame for recall.

See Evaluation for the ground-truth schema.

Terminal window
scriva annotate ./training/ \
--primary openai:gpt-4o \
--oracle bedrock:qwen.qwen3-vl-235b-a22b \
--store pgvector://localhost/scriva \
--top-k 20

Wires the annotation domain pack against a sample store. --primary and --oracle each name a Worker engine factory and model. See domains.annotation.

Terminal window
scriva serve --port 8000

Boots a small ASGI service exposing:

  • POST /v1/extract (multipart upload, schema form field, JSON response)
  • POST /v1/classify
  • POST /v1/batch
  • GET /v1/events/{job_id} (SSE)
  • POST /v1/cancel/{job_id}

Intended for internal ops, not as a hosted product. --auth bearer adds a static-token check; for multi-tenant production, embed scriva in your own FastAPI app (see Cookbook › ocr-agent).

Terminal window
scriva cache info # size, entry count, oldest/newest
scriva cache prune --older 30d # drop entries older than 30 days
scriva cache clear # drop everything (confirm prompt)
scriva cache export out.tar.gz # ship to another machine

The cache is the same one Worker.cache(...) writes — see Caching.

Terminal window
scriva samples list --store .scriva_samples
scriva samples export --store .scriva_samples --to training.parquet
scriva samples train --store .scriva_samples --head lightgbm -o models/cells.joblib

samples train runs classify.embedding.train(...) against the store and writes a joblib for embedding.load(...).

scriva.toml in the working directory (or --config <path>) is read by every command. Anything you’d pass as a CLI flag can live here:

log_level = "info"
cache = ".scriva_cache"
[extract]
model = "gpt-4o"
locale = "auto"
max_cost = 0.50
[batch]
concurrency = 8
on_error = "continue"
[reliability]
retries.attempts = 4
retries.backoff = "exponential"
rate_limit.rps = 20
[telemetry]
sink = "otel"
otel.endpoint = "https://otel.internal:4317"

CLI flags override the config; the config overrides built-in defaults.