Skip to main content

Pure-Python client for Archil disks

Project description

archil

Python client for Archil disks. Create disks, list and inspect them, manage who can mount them, run commands against them, and read/write their contents through the S3-compatible object API — all from scripts, CI, or notebooks.

archil talks to the Archil control plane over HTTPS and has no native dependencies.

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. This is powered by synchronicity — the same approach Modal uses — so there's one source of truth and no duplicated sync/async logic.

Install

pip install archil

Library

import archil

# Configure once per process — falls back to ARCHIL_API_KEY / ARCHIL_REGION env vars.
archil.configure(api_key="key-...", region="aws-us-east-1")

# Create a disk. `token` here is the disk token — the one-time credential for mounting.
result = archil.create_disk(name="my-disk")
print(f"Created {result.disk.id}, disk token: {result.token}")

# A freshly-created disk starts in "creating"; block until it's usable.
disk = result.disk.wait_until_ready()  # raises on terminal failure / timeout

# List and look up disks
all_disks = archil.list_disks()
d = archil.get_disk(result.disk.id)

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

d = archil.get_disk("dsk-abc123")

# Run a command in a container with the disk mounted
res = d.exec("ls -la /mnt && cat /mnt/config.json")
print(res.stdout, res.stderr, res.exit_code)

# Manage who can mount the disk
from archil import TokenUser
user = d.add_user(TokenUser(nickname="ci"))
d.remove_user("token", user.identifier)

# Delete
d.delete()

Account-level API keys are top-level helpers:

archil.list_api_keys()
archil.create_api_key(name="ci-bot", description="GitHub Actions")
archil.delete_api_key("key-abc123")

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).

import json
d = archil.get_disk("dsk-abc123")
report = {"generated": "2026-01", "rows": 1234}

# Write — accepts str or bytes. content_type is optional. Returns the etag.
result = d.put_object("reports/2026-01/data.json", json.dumps(report), "application/json")

# Read — returns bytes.
data = d.get_object("reports/2026-01/data.json")
text = data.decode("utf-8")

# Metadata / existence without downloading the body
meta = d.head_object("reports/2026-01/data.json")  # None if absent
if d.object_exists("reports/2026-01/data.json"):
    ...

# Delete (idempotent — deleting a missing key succeeds)
d.delete_object("reports/2026-01/data.json")

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:

result = d.list_objects("reports/")                       # one level
all_keys = d.list_objects("reports/", recursive=True)     # whole subtree
first_100 = d.list_objects("reports/", limit=100)         # cap the total

# Stream pages instead of buffering everything (large listings):
for page in d.list_objects_pages("reports/"):
    for obj in page.objects:
        print(obj.key, obj.size, obj.last_modified)

# Or drive pagination yourself:
page = d.list_objects("reports/", single_page=True)
if page.is_truncated:
    nxt = d.list_objects("reports/", single_page=True, continuation_token=page.next_continuation_token)

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. All SDK errors extend ArchilError, so except ArchilError handles control-plane and S3 failures uniformly.

The S3 endpoint is derived from your region automatically. To target a custom environment, pass s3_base_url to Archil(...) (or set the ARCHIL_S3_BASE_URL env var).

Sharing files

share mints a signed, time-limited link to a single file. Anyone with the link can download that file — no API key, no mounting. The link carries a cryptographically signed token (disk + key + expiry); when it expires it stops working.

d = archil.get_disk("dsk-abc123")

# Default lifetime is 24 hours.
link = d.share("reports/2026-01/summary.pdf")
print(link.url)         # https://control.…/api/shared/<token>
print(link.expires_in)  # 86400

# Set the lifetime in seconds (any positive integer, up to 604800 = 7 days):
week_link = d.share("reports/2026-01/summary.pdf", expires_in=604800)

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; from async code, construct Archil(...) directly and use .aio.) Construct the client directly and await:

import asyncio
from archil import Archil

async def main():
    async with Archil(api_key="key-...", region="aws-us-east-1") as client:
        d = await client.disks.get.aio("dsk-abc123")
        await d.put_object.aio("a/b.txt", b"hello")
        data = await d.get_object.aio("a/b.txt")
        async for page in d.list_objects_pages.aio("a/"):
            for obj in page.objects:
                print(obj.key)

asyncio.run(main())

Multiple accounts or regions

For multi-tenant scripts, instantiate Archil directly instead of using the module-level configure:

from archil import Archil

prod = Archil(api_key=prod_key, region="aws-us-east-1")
staging = Archil(api_key=staging_key, region="aws-us-east-1")

prod_disks = prod.disks.list()
staging_disks = staging.disks.list()

Connecting to a disk's data plane

To run a command against a disk, use Disk.exec() — it returns stdout, stderr, and an exit code from an Archil-managed container with the disk pre-mounted. No local filesystem involved.

To mount a disk as a real filesystem on your machine, use the archil CLI — it mounts through the OS kernel via FUSE, so any program can read and write files with standard APIs. Mounting from Python is not supported; use exec() or the S3-compatible object API instead.

Supported regions

Region Provider
aws-us-east-1 AWS
aws-us-west-2 AWS
aws-eu-west-1 AWS
gcp-us-central1 GCP

FAQ

What's the difference between an API key and a disk token?

  • API key — account-level credential for the control plane. You use one whenever you call archil. Create and manage them at console.archil.com. Goes in the ARCHIL_API_KEY env var or the api_key argument.
  • Disk token — per-disk credential that lets a client mount a specific disk. Created automatically when you create_disk(...) (the value is shown once; save it).

Support

Questions, feature requests, or issues? Reach us at support@archil.com.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

archil-0.8.13.tar.gz (37.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

archil-0.8.13-py3-none-any.whl (31.6 kB view details)

Uploaded Python 3

File details

Details for the file archil-0.8.13.tar.gz.

File metadata

  • Download URL: archil-0.8.13.tar.gz
  • Upload date:
  • Size: 37.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for archil-0.8.13.tar.gz
Algorithm Hash digest
SHA256 e822a400f744ada2e3882df063ab99b67abbca4083e461348e33437bfabb6855
MD5 097a7c1681ae003ccddac56a359cdc92
BLAKE2b-256 2a198bc6c06830bfaab915ba1875b492b7d92e683fa50b5a7ee3c0d807713692

See more details on using hashes here.

Provenance

The following attestation bundles were made for archil-0.8.13.tar.gz:

Publisher: release.yml on archil-data/archil

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file archil-0.8.13-py3-none-any.whl.

File metadata

  • Download URL: archil-0.8.13-py3-none-any.whl
  • Upload date:
  • Size: 31.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for archil-0.8.13-py3-none-any.whl
Algorithm Hash digest
SHA256 62275bd9321c8c5df97ed208741ec10b3240e1c7ef0478894fb7caf224f23ba5
MD5 b8cec7902b8aae71b448bf5ddc9d0bf1
BLAKE2b-256 56750790b2cd1e864277eb2a21a3d3ddb607ded28d48f890a8c008357507a0cd

See more details on using hashes here.

Provenance

The following attestation bundles were made for archil-0.8.13-py3-none-any.whl:

Publisher: release.yml on archil-data/archil

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page