Skip to main content
The Archil Python SDK is the archil package on PyPI. It’s a pure-Python control-plane client: create disks, list and inspect them, manage who can mount them, run commands against them with Disk.exec, and read and write their contents through an S3-compatible object API.
archil talks to the Archil control plane over HTTPS and has no native dependencies. It requires Python 3.10 or later. Every method works both synchronously and asynchronously from a single implementation: disk.put_object(...) blocks, while disk.put_object.aio(...) returns a coroutine you can await. See Async below.
Looking for the FUSE mount client? That’s the archil CLI, which mounts a disk as a real local filesystem. The Python SDK does not mount disks; it talks to the control plane, runs serverless commands, and reads and writes objects over HTTPS.

Configuration

The recommended pattern is a one-time configure call, then the module-level helpers:
Both options fall back to environment variables (ARCHIL_API_KEY, ARCHIL_REGION) if omitted, so in most environments you can skip configure entirely and let the SDK read the environment. For multi-tenant scripts that need multiple credentials in one process, instantiate Archil directly instead of using the module-level configure:
The API key is an account-level credential and is not the same thing as a disk token. API keys authenticate calls to the control plane (everything in this page); a disk token grants mount access to a single disk. See the disk users concept page.

Managing disks

Per-disk operations are methods on the Disk object itself, not top-level functions:

Executing commands

Disk.exec(command) runs a shell command inside a container with the file system already mounted, and returns stdout, stderr, exit code, and timing. See the Serverless Execution concept page for the full picture.
The disk is the working directory inside the container β€” commands can reference files using relative paths. Billing is based on execute_ms β€” the wall-clock time your command runs β€” in 1ms increments, with a 100ms minimum per call. Queue time is not billed. stdout and stderr are each capped at 128 KiB per invocation β€” pipe larger outputs to a file on the disk instead. For multi-disk execs (mount several disks at once, optionally pinned to a subdirectory or read-only), call archil.exec(...) instead of Disk.exec. Each disk is mounted at its own relative path; pass a Disk, a disk-id string, or an ExecMountSpec for finer control:
See the bash tool for agents guide for an end-to-end example wiring exec into an AI agent loop.

Searching files

Disk.grep(...) searches the files on a disk for lines matching a regular expression, fanning the listing and matching out across many ephemeral containers so the search scales across many machines instead of one. Reach for it instead of exec("grep …") whenever you just want matching lines. See Search Files for the full model.
You control cost and latency with three knobs:
  • max_duration_seconds β€” wall-clock deadline (default 30, capped at 30).
  • concurrency β€” max parallel workers (default 50). More workers scan a large dataset faster, at proportionally more compute.
  • max_results β€” short-circuit once this many matches are collected (default 1000).
Always check stopped_reason β€” it tells you whether the search was exhaustive. When it stops early, the returned matches are a sample of whichever workers reported first, not the lexicographically first N:

Reading and writing objects

A Disk doubles as an S3-compatible bucket: read, write, delete, and list its files by key without mounting it. These methods talk to Archil’s S3 endpoint using your same API key β€” no separate S3 credentials or SigV4 signing on your part.
put_object handles any size with one call: small bodies go through a single request, and larger bodies are uploaded as a multipart upload automatically β€” split into parts, uploaded with bounded concurrency, and assembled, aborting the upload if any part fails so nothing is left half-staged. Tune the switch point and parallelism with keyword options:
For very large objects the part size grows automatically so the upload never exceeds S3’s 10,000-part limit. list_objects auto-paginates by default, returning every matching key. The first argument is a key prefix; a non-recursive listing (the default) returns the immediate level as objects plus subdirectory common_prefixes:
delete_objects removes many keys in one round trip (auto-batched at S3’s 1,000-key limit). Unlike delete_object, per-key failures are returned rather than raised:
append_object appends bytes to an existing object (creating it if absent) β€” handy for log-style writes. Each call may append at most 1 MiB; append in chunks to grow past that:
For manual control over the multipart lifecycle (e.g. uploading parts from separate processes), the raw S3 primitives live in the opt-in d.multipart namespace β€” create, upload_part, complete, abort, list_parts, list_uploads. Most code never needs these; prefer put_object, which runs the lifecycle for you.

Async

Every method on Archil, Disks, Disk, and Tokens has an .aio variant that returns a coroutine. The module-level helpers (configure, create_disk, get_disk, etc.) are synchronous convenience wrappers, so from async code, construct Archil(...) directly and use .aio:

Managing API keys

API keys are account-level, so these helpers live at the top level rather than on a Disk:

Error handling

All SDK errors extend ArchilError, so except ArchilError handles control-plane and S3 failures uniformly. Object-API failures raise ArchilS3Error with status (HTTP status), code (the S3 error code, e.g. "NoSuchKey"), request_id, and the raw body on raw:
get_object on a missing key raises a 404 β€” use head_object / object_exists to probe without catching. Transient failures (HTTP 429 and 5xx, plus network errors) are retried automatically with jittered exponential backoff before surfacing; other 4xx are caller errors and aren’t retried. The two non-idempotent operations β€” complete (multipart) and append_object β€” are not auto-retried, since a retry after a succeeded-but-unacknowledged call would return a spurious NoSuchUpload or duplicate the appended bytes.

Supported regions