> ## Documentation Index
> Fetch the complete documentation index at: https://docs.anonalabs.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Files

> Read, write, list and watch files; upload and download with signed URLs.

The `files` API reads and writes the sandbox filesystem as the sandbox user. Paths are absolute, or relative to `/home/user`.

```python files.py theme={null}
from anona import Sandbox

with Sandbox.create("base") as sbx:
    sbx.files.make_dir("/home/user/project")
    sbx.files.write("/home/user/project/notes.txt", "first line\n")
    sbx.files.write("/home/user/project/blob.bin", bytes(range(256)))

    print(sbx.files.read("/home/user/project/notes.txt"))
    print(len(sbx.files.read("/home/user/project/blob.bin", format="bytes")))

    for entry in sbx.files.list("/home/user/project"):
        print(entry.type, entry.name, entry.size)

    sbx.files.rename("/home/user/project/notes.txt", "/home/user/project/README.txt")
    print(sbx.files.exists("/home/user/project/notes.txt"), sbx.files.get_info("/home/user/project/README.txt").size)
    sbx.files.remove("/home/user/project/blob.bin")
```

```typescript files.ts theme={null}
import { Sandbox } from "@anona/sdk";

const sbx = await Sandbox.create("base");
await sbx.files.makeDir("/home/user/project");
await sbx.files.write("/home/user/project/notes.txt", "first line\n");
console.log(await sbx.files.read("/home/user/project/notes.txt"));

for (const entry of await sbx.files.list("/home/user/project")) console.log(entry.type, entry.name);

await sbx.files.rename("/home/user/project/notes.txt", "/home/user/project/README.txt");
console.log(await sbx.files.exists("/home/user/project/notes.txt"));
await sbx.kill();
```

## Watch a directory

```python watch.py theme={null}
import time
from anona import Sandbox

with Sandbox.create("base") as sbx:
    sbx.files.make_dir("/tmp/inbox")
    handle = sbx.files.watch_dir("/tmp/inbox")
    sbx.files.write("/tmp/inbox/job.json", "{}")
    time.sleep(1)
    print([(e.type.name, e.name) for e in handle.get_new_events()])
    handle.stop()
```

## Signed upload and download URLs

Hand a URL to a browser or another service so it can move a file without your API key. The URL is signed for one path and expires.

```python signed_urls.py theme={null}
import httpx
from anona import Sandbox

with Sandbox.create("base", secure=True) as sbx:
    up = sbx.upload_url("/home/user/report.csv", use_signature_expiration=300)
    httpx.post(up, files={"file": ("report.csv", b"a,b\n1,2\n")}).raise_for_status()

    down = sbx.download_url("/home/user/report.csv", use_signature_expiration=300)
    print(httpx.get(down).text)
```

## Copy files with the CLI

Over SSH (see [SSH](https://docs.anonalabs.com/compute/guides/ssh.md)):

```bash scp.sh theme={null}
echo "local data" > data.txt
anona-compute scp "$SANDBOX_ID" ./data.txt :/home/user/
anona-compute scp "$SANDBOX_ID" :/home/user/data.txt ./copy.txt
cat copy.txt
```

**Coming soon:** `anona-compute push`, which copies a git working tree into a sandbox.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.