Metadata-Version: 2.4
Name: toolkami
Version: 0.1.4
Summary: Python gRPC client for the local toolkami daemon
Author-email: Aperoc <aperoc@users.noreply.github.com>
License-Expression: MIT
Project-URL: Homepage, https://github.com/aperoc/toolkami
Project-URL: Source, https://github.com/aperoc/toolkami
Project-URL: Issues, https://github.com/aperoc/toolkami/issues
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: grpcio==1.78.0
Requires-Dist: protobuf==6.33.0
Provides-Extra: dev
Requires-Dist: grpcio-tools==1.78.0; extra == "dev"
Requires-Dist: pytest==8.4.2; extra == "dev"
Requires-Dist: build==1.3.0; extra == "dev"
Dynamic: license-file

# toolkami

Python gRPC client for the local `toolkami` daemon.

## Install

```bash
pip install toolkami
```

The packaged distribution downloads the matching Linux x64 daemon and guest-agent from the GitHub release for the package version on first client start. Repository checkouts use the local Cargo debug binary.

## Usage

```python
from toolkami import Client

client = Client.open(tcp_address="127.0.0.1:50061")
print(client.get_version().version)
print(client.ping("python").message)
client.close()
```

## Daemon Launch and NBD Permissions

The daemon now requires read/write access to NBD block devices (`/dev/nbd*`).

- Default behavior: `Client.open(...)` reuses an existing daemon at `tcp_address`; if not found, it auto-launches one.
- If your user lacks NBD permissions, auto-launch fails with an actionable error.
- To disable auto-launch and only connect to an already-running daemon:

```python
client = Client.open(tcp_address="127.0.0.1:50061", auto_launch=False)
```

- To explicitly opt into privileged launch:

```python
client = Client.open(tcp_address="127.0.0.1:50061", use_sudo=True)
```

## Spawn/Restore with Folder Mounts

```python
from toolkami import Client
from toolkami.v1.image_pb2 import BuildRequest
from toolkami.v1.instance_pb2 import FolderMount, RestoreRequest, SpawnRequest
from toolkami.v1.snapshot_pb2 import SnapshotRequest

client = Client.open(tcp_address="127.0.0.1:50061")

image = client.build(
    BuildRequest(
        dockerfile_text="FROM ubuntu:24.04\nWORKDIR /workspace",
        dockerfile_bytes_max=64_000,
    )
)
spawned = client.spawn(
    SpawnRequest(
        image_id=image.image_id,
        mounts=[
            FolderMount(
                source_host_path="/abs/path/to/repo",
                target_path="/workspace/repo",
                # access_mode defaults to read-only when omitted
            )
        ],
    )
)
snap = client.snapshot(SnapshotRequest(instance_id=spawned.instance_id))
restored = client.restore(
    RestoreRequest(
        snapshot_id=snap.snapshot_id,
        mounts=[
            FolderMount(
                source_host_path="/abs/path/to/repo",
                target_path="/workspace/repo",
            )
        ],
    )
)
print(restored.instance_id)
client.close()
```

## Development

```bash
make proto-generate
make test
make release-build
make integration-smoke-local
```
