{ } Raw JSON

bundles / papyri 0.0.10 / papyri / cli / upload / upload

function

papyri.cli.upload:upload

source: /papyri/cli/upload.py :152

Signature

def   upload ( paths : Annotated[list[Path], typer.Argument(help='Paths to upload. Each path is a ``.papyri`` artifact (produced by ``papyri pack``), a ``.zip`` file containing exactly one ``.papyri`` artifact, or a DocBundle directory (packed on the fly, output unchanged from ``papyri gen``).')] to : Annotated[str | None, typer.Option('--to', help="Named upload target defined in ~/.papyri/config.toml (e.g. 'staging', 'production'). Overrides $PAPYRI_UPLOAD_URL / $PAPYRI_UPLOAD_TOKEN. Explicit --url / --token flags override --to.")] = None url : Annotated[str | None, typer.Option('--url', '-u', help='URL of the viewer ingest endpoint. Overrides --to and $PAPYRI_UPLOAD_URL. Defaults to $PAPYRI_UPLOAD_URL, then the target set by --to, then http://localhost:4321/api/bundle.')] = None token : Annotated[str | None, typer.Option('--token', '-t', help='Bearer token for /api/bundle authentication. Overrides --to and $PAPYRI_UPLOAD_TOKEN. Defaults to $PAPYRI_UPLOAD_TOKEN, then the target set by --to. Omit when the viewer has no token configured (local dev).')] = None verbose : Annotated[bool, typer.Option('--verbose', '-v', help='Show per-step packing progress when building a bundle on the fly.')] = False force : Annotated[bool, typer.Option('--force', '-f', help='Upload even when the viewer already holds an identical bundle. By default a SHA-256 of the artifact is checked against the server first and matching bundles are skipped.')] = False )  →  None

Summary

Send each .papyri artifact (or pack a DocBundle directory on the fly) to the viewer ingest endpoint.

Extended Summary

Accepted input forms:

  • .papyri file: loaded directly.

  • .zip file: must contain exactly one .papyri member; that member is extracted and uploaded. The zip is validated before the network request is made.

  • DocBundle directory: passed through papyri.pack.make_artifact_from_dir so the bytes on the wire are identical to what papyri pack would produce — same validation, same byte-reproducibility guarantees.

The viewer's /api/bundle endpoint runs the full ingest pipeline server-side; this is the canonical way to ship a bundle into the cross-linked graph.

Named targets (recommended for repeated use)

# ~/.papyri/config.toml
[upload.targets.staging]
url = "https://staging.example.com/api/bundle"
token = "my-token"

[upload.targets.production]
url = "https://docs.example.com/api/bundle"
keychain = true   # token stored in system keychain

Then: papyri upload --to staging mybundle.papyri

For keychain targets, store the token once with

python -m keyring set papyri production

Token resolution order: --token flag > --to target (config file or keychain) > $PAPYRI_UPLOAD_TOKEN env var.

URL resolution order: --url flag > --to target > $PAPYRI_UPLOAD_URL env var > http://localhost:4321/api/bundle.

Deduplication: before each upload the SHA-256 of the artifact is checked against the viewer (a GET to the same endpoint). When the server already holds an identical bundle for that (module, version) the upload is skipped. Pass --force to upload regardless.

Aliases

  • papyri._cmd