Metadata-Version: 2.4
Name: instavm
Version: 0.15.0
Summary: Official Python SDK and CLI for InstaVM APIs
Author-email: InstaVM <hello@instavm.io>
License: MIT
Project-URL: Documentation, https://instavm.io/docs/sdks/python/overview
Project-URL: Changelog, https://instavm.io/docs/sdks/python/changelog
Project-URL: Support, https://instavm.io/support
Project-URL: Source, https://github.com/BandarLabs/sandbox_client
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Operating System :: OS Independent
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: requests
Dynamic: license-file

# InstaVM Python SDK + CLI

Official Python SDK and installed CLI for [InstaVM](https://instavm.io). Use it to manage VMs, snapshots, shares, volumes, desktops, account settings, and code execution from Python or your shell.

## Installation

```bash
pip install instavm
```

**Requirements:** Python 3.8+

## CLI

`pip install instavm` installs the `instavm` command in the active Python environment.

```bash
instavm --help
python -m instavm.cli --help
```

The CLI stores defaults in `~/.instavm/config.json`, checks `INSTAVM_API_KEY` when no key is stored, and also respects `INSTAVM_BASE_URL` and `INSTAVM_SSH_HOST`.

### Auth & Config

```bash
instavm auth set-key
instavm auth status
printf '%s' "$INSTAVM_API_KEY" | instavm auth set-key
```

### Common Commands

```bash
instavm whoami
instavm ls
instavm create --type computer-use --memory 4096
instavm connect vm_123
instavm snapshot ls
instavm volume ls
instavm volume files upload <volume_id> ./README.md --path docs/README.md
instavm share create vm_123 3000 --public
instavm share set-private <share_id>
instavm ssh-key list
instavm desktop viewer <session_id>
instavm doc
instavm billing
```

### Command Reference

- `auth`: `set-key`, `status`, `logout`
- `whoami`: show account details and SSH keys
- `create`/`new`, `ls`/`list`, `rm`/`delete`, `clone`, `connect`: core VM workflows
- `snapshot`: `ls`, `create`, `build`, `get`, `rm`
- `desktop`: `status`, `start`, `stop`, `viewer`
- `volume`: `ls`, `get`, `create`, `update`, `rm`, `checkpoint`, `files`
- `share`: `create`, `set-public`, `set-private`, `revoke`
- `ssh-key`: `list`, `add`, `remove`
- `doc`/`docs`, `billing`: docs and billing links

All leaf commands support `--json`. Share visibility updates use `share_id`, which matches the public API.

## Library Quick Start

```python
import os
from instavm import InstaVM

client = InstaVM(
    api_key=os.environ.get("INSTAVM_API_KEY"),
    auto_start_session=False,
)

me = client.get_current_user()
vms = client.vms.list()

print(me["email"])
print(len(vms))
```

## Table of Contents

- [CLI](#cli)
  - [Auth & Config](#auth--config)
  - [Common Commands](#common-commands)
  - [Command Reference](#command-reference)
- [Library Quick Start](#library-quick-start)
- [Code Execution](#code-execution)
  - [Sessions & Configuration](#sessions--configuration)
  - [File Operations](#file-operations)
  - [Async Execution](#async-execution)
- [Sessions & Sandboxes](#sessions--sandboxes)
- [VMs & Snapshots](#vms--snapshots)
- [Volumes](#volumes)
  - [Volume CRUD & Files](#volume-crud--files)
  - [VM Volume Attachments](#vm-volume-attachments)
- [Networking](#networking)
  - [Egress, Shares, SSH](#egress-shares-ssh)
- [Browser Automation](#browser-automation)
  - [Basic Browser Flow](#basic-browser-flow)
  - [Content Extraction](#content-extraction)
- [Computer Use](#computer-use)
- [Platform APIs](#platform-apis)
- [Error Handling](#error-handling)
- [Development & Testing](#development--testing)
- [Further Reading](#further-reading)
- [Changelog](#changelog)

---

## Code Execution

### Sessions & Configuration

```python
from instavm import InstaVM

client = InstaVM(
    api_key="your_api_key",
    cpu_count=2,
    memory_mb=1024,
    env={"APP_ENV": "dev"},
    metadata={"team": "platform"},
)

result = client.execute("print('session id:', 'ok')")
print(result)
print(client.session_id)
```

### File Operations

```python
client = InstaVM(api_key="your_api_key")

client.upload_file("local_script.py", "/app/local_script.py")
client.execute("python /app/local_script.py", language="bash")
client.download_file("output.json", local_path="./output.json")
```

### Async Execution

```python
client = InstaVM(api_key="your_api_key")

task = client.execute_async("sleep 5 && echo 'done'", language="bash")
result = client.get_task_result(task["task_id"], poll_interval=2, timeout=60)
print(result)
```

---

## Sessions & Sandboxes

```python
client = InstaVM(api_key="your_api_key")

# Get the publicly-reachable app URL (optionally for a specific port)
app_url = client.get_session_app_url(port=8080)
print(app_url.get("app_url"))

# List sandbox records with optional metadata filter and limit
sandboxes = client.list_sandboxes(metadata={"env": "production"}, limit=50)
print(len(sandboxes))
```

---

## VMs & Snapshots

```python
client = InstaVM(api_key="your_api_key")

# Create a basic VM
vm = client.vms.create(wait=True, metadata={"purpose": "dev"})

# Create a VM with pre-attached volumes
vm_with_vols = client.vms.create(
    wait=True,
    volumes=[{"volume_id": "vol_abc", "mount_path": "/data", "mode": "rw"}],
)

# List VMs
vms = client.vms.list()                 # GET /v1/vms  (running)
all_records = client.vms.list_all_records()  # GET /v1/vms/ (all records)

# Snapshot a running VM
snap_from_vm = client.vms.snapshot(vm_id=vm["vm_id"], wait=True, name="dev-base")

# Build a snapshot from an OCI image
snap_from_oci = client.snapshots.create(
    oci_image="docker.io/library/python:3.11-slim",
    name="python-3-11-dev",
    vcpu_count=2,
    memory_mb=1024,
    snapshot_type="user",
    build_args={
        "git_clone_url": "https://github.com/example/repo.git",
        "git_clone_branch": "main",
        "envs": {"PIP_INDEX_URL": "https://pypi.org/simple"},
    },
)

user_snaps = client.snapshots.list(snapshot_type="user")
```

---

## Volumes

### Volume CRUD & Files

```python
client = InstaVM(api_key="your_api_key")

# Create
volume = client.volumes.create(name="project-data", quota_bytes=10 * 1024 * 1024 * 1024)
volume_id = volume["id"]

# Read / Update
client.volumes.list(refresh_usage=True)
client.volumes.get(volume_id, refresh_usage=True)
client.volumes.update(volume_id, name="project-data-v2", quota_bytes=20 * 1024 * 1024 * 1024)

# File operations
client.volumes.upload_file(volume_id, file_path="./README.md", path="docs/README.md", overwrite=True)
files = client.volumes.list_files(volume_id, prefix="docs/", recursive=True, limit=1000)
download = client.volumes.download_file(volume_id, path="docs/README.md")
client.volumes.delete_file(volume_id, path="docs/README.md")

# Checkpoints
checkpoint = client.volumes.create_checkpoint(volume_id, name="pre-release")
client.volumes.list_checkpoints(volume_id)
client.volumes.delete_checkpoint(volume_id, checkpoint["id"])

# Cleanup
client.volumes.delete(volume_id)
```

### VM Volume Attachments

```python
vm = client.vms.create(wait=True)
vm_id = vm["vm_id"]

client.vms.mount_volume(vm_id, volume_id, mount_path="/data", mode="rw", wait=True)
client.vms.list_volumes(vm_id)
client.vms.unmount_volume(vm_id, volume_id, mount_path="/data", wait=True)
```

---

## Networking

### Egress, Shares, SSH

```python
client = InstaVM(api_key="your_api_key")

# Egress policy
policy = client.set_session_egress(
    allow_package_managers=True,
    allow_http=False,
    allow_https=True,
    allowed_domains=["pypi.org", "files.pythonhosted.org"],
)

# Public/private share links
share = client.shares.create(port=3000, is_public=False)
client.shares.update(share_id=share["share_id"], is_public=True)

# SSH key registration
key = client.add_ssh_key("ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA... user@host")
```

---

## Browser Automation

### Basic Browser Flow

```python
client = InstaVM(api_key="your_api_key")

session = client.browser.create_session(viewport_width=1366, viewport_height=768)
session.navigate("https://example.com")
links = session.extract_elements("a", ["text", "href"])
shot_b64 = session.screenshot(full_page=True)
session.close()
```

### Content Extraction

LLM-friendly extraction with optional interactive-element and anchor discovery:

```python
client = InstaVM(api_key="your_api_key")

content = client.browser.extract_content(
    url="https://example.com/docs",
    include_interactive=True,
    include_anchors=True,
    max_anchors=30,
)

print(content["readable_content"].get("title"))
for anchor in (content.get("content_anchors") or [])[:5]:
    print(anchor.get("text"), anchor.get("selector"))
```

---

## Computer Use

Control a full desktop environment inside a VM session:

```python
client = InstaVM(api_key="your_api_key")

session_id = client.session_id

# Viewer URL and state
viewer = client.computer_use.viewer_url(session_id)
state = client.computer_use.get(session_id, "/state")

# Proxy methods (GET, POST, HEAD)
head_resp = client.computer_use.head(session_id, "/state")

# VNC websockify URL for remote desktop streaming
vnc = client.computer_use.vnc_websockify(session_id)
```

---

## Platform APIs

API keys, audit logs, and webhooks:

```python
client = InstaVM(api_key="your_api_key")

# API Keys
api_key = client.api_keys.create(description="ci key")

# Audit log
audit_page = client.audit.events(limit=25, status="success")

# Webhooks
endpoint = client.webhooks.create_endpoint(
    url="https://example.com/instavm/webhook",
    event_patterns=["vm.*", "snapshot.*"],
)

deliveries = client.webhooks.list_deliveries(limit=10)
```

---

## Error Handling

All SDK errors extend a typed hierarchy for precise `except` handling:

```python
from instavm import (
    InstaVM,
    AuthenticationError,
    ExecutionError,
    NetworkError,
    RateLimitError,
    SessionError,
)

client = InstaVM(api_key="your_api_key")

try:
    client.execute("raise Exception('boom')")
except AuthenticationError:
    print("Invalid API key")
except RateLimitError:
    print("Rate limited")
except SessionError as exc:
    print(f"Session issue: {exc}")
except ExecutionError as exc:
    print(f"Execution failed: {exc}")
except NetworkError as exc:
    print(f"Network issue: {exc}")
```

---

## Development & Testing

```bash
pip install -e .                              # Install for development
python3 -m pytest tests/test_api_client.py -v # Unit tests
```

---

## Further Reading

- [Python SDK Overview](https://instavm.io/docs/sdks/python/overview)
- [VM Management](https://instavm.io/docs/sdks/python/vm-management)
- [Snapshots](https://instavm.io/docs/sdks/python/snapshots)
- [Egress and Networking](https://instavm.io/docs/sdks/python/egress-and-networking)
- [Platform APIs](https://instavm.io/docs/sdks/python/platform-apis)
- [Browser Automation](https://instavm.io/docs/sdks/python/browser-automation)
- [Error Handling](https://instavm.io/docs/sdks/python/error-handling)

---

## Changelog

Current package version: **0.15.0**

### 0.15.0

- Installed `instavm` CLI for `pip install instavm`, including `python -m instavm.cli`
- Stored CLI auth/config in `~/.instavm/config.json` with `INSTAVM_API_KEY` fallback
- Added [`get_current_user()`](#library-quick-start) and [`get_session_status(session_id=None)`](#computer-use) helpers for account and desktop workflows

### 0.13.0

- [`get_session_app_url(session_id?, port?)`](#sessions--sandboxes) — session app URL with optional port
- [`list_sandboxes(metadata?, limit?)`](#sessions--sandboxes) — list sandbox records with metadata filtering
- [`computer_use.head(session_id, path)`](#computer-use) — HEAD proxy method for computer-use sessions
- [`computer_use.vnc_websockify(session_id)`](#computer-use) — VNC websockify URL for remote desktop streaming
- VM creation now accepts [`volumes`](#vms--snapshots) for pre-attached volume mounts

### 0.12.0

- Manager-based APIs across VMs, volumes, snapshots, shares, custom domains, computer use, API keys, audit, and webhooks
- Snapshot build args support for env vars and Git clone inputs
- Distinct VM list helpers for `/v1/vms` and `/v1/vms/`

For detailed history, see repository tags and PR history.
