---
title: Filesystem
description: Python SDK - Filesystem API reference
---

Read, write, and manage files inside a running sandbox. Operations go through the same host-guest channel as command execution: no SSH, no network. See [Filesystem](/sandboxes/filesystem) for usage examples. For bulk file movement, prefer a [volume](/sandboxes/volumes).

<div className="msb-glance">

  <p className="msb-gl"><span className="msb-dot instance"></span>Read<span className="msb-ct">3</span></p>
  <a className="msb-row" href="#fs-read"><span className="msb-rn">fs.read()</span><span className="msb-rg">whole file as bytes</span></a>
  <a className="msb-row" href="#fs-read_text"><span className="msb-rn">fs.read_text()</span><span className="msb-rg">whole file as UTF-8 text</span></a>
  <a className="msb-row" href="#fs-read_stream"><span className="msb-rn">fs.read_stream()</span><span className="msb-rg">stream a large file in chunks</span></a>

  <p className="msb-gl"><span className="msb-dot instance"></span>Write<span className="msb-ct">2</span></p>
  <a className="msb-row" href="#fs-write"><span className="msb-rn">fs.write()</span><span className="msb-rg">overwrite a file with bytes</span></a>
  <a className="msb-row" href="#fs-write_stream"><span className="msb-rn">fs.write_stream()</span><span className="msb-rg">stream a large file in chunks</span></a>

  <p className="msb-gl"><span className="msb-dot instance"></span>Directories &amp; metadata<span className="msb-ct">5</span></p>
  <a className="msb-row" href="#fs-list"><span className="msb-rn">fs.list()</span><span className="msb-rg">directory entries</span></a>
  <a className="msb-row" href="#fs-mkdir"><span className="msb-rn">fs.mkdir()</span><span className="msb-rg">create a directory and parents</span></a>
  <a className="msb-row" href="#fs-stat"><span className="msb-rn">fs.stat()</span><span className="msb-rg">file metadata</span></a>
  <a className="msb-row" href="#fs-exists"><span className="msb-rn">fs.exists()</span><span className="msb-rg">check a path exists</span></a>
  <a className="msb-row" href="#fs-remove_dir"><span className="msb-rn">fs.remove_dir()</span><span className="msb-rg">remove a directory recursively</span></a>

  <p className="msb-gl"><span className="msb-dot instance"></span>Move, copy &amp; remove<span className="msb-ct">5</span></p>
  <a className="msb-row" href="#fs-copy"><span className="msb-rn">fs.copy()</span><span className="msb-rg">copy a file in the sandbox</span></a>
  <a className="msb-row" href="#fs-rename"><span className="msb-rn">fs.rename()</span><span className="msb-rg">rename / move a path</span></a>
  <a className="msb-row" href="#fs-remove"><span className="msb-rn">fs.remove()</span><span className="msb-rg">remove a file</span></a>
  <a className="msb-row" href="#fs-copy_from_host"><span className="msb-rn">fs.copy_from_host()</span><span className="msb-rg">host file into sandbox</span></a>
  <a className="msb-row" href="#fs-copy_to_host"><span className="msb-rn">fs.copy_to_host()</span><span className="msb-rg">sandbox file out to host</span></a>

  <p className="msb-gl"><span className="msb-dot type"></span>Types</p>
  <div className="msb-chiprow">
    <a className="msb-typepill" href="#fsentry">FsEntry</a>
    <a className="msb-typepill" href="#fsentrykind">FsEntryKind</a>
    <a className="msb-typepill" href="#fsmetadata">FsMetadata</a>
    <a className="msb-typepill" href="#fsreadstream">FsReadStream</a>
    <a className="msb-typepill" href="#fswritesink">FsWriteSink</a>
  </div>

</div>

<p className="msb-label" id="typical-flow">Typical flow</p>

```python
from microsandbox import Sandbox

async with await Sandbox.create("api", image="python") as sb:
    fs = sb.fs                                     # 1. grab the handle

    await fs.mkdir("/app")                         # 2. set up
    await fs.write("/app/config.json", b'{"ok": true}')

    data = await fs.read_text("/app/config.json")  # 3. read it back
    print(data)
```

The handle is reached through the `sb.fs` property on a running [`Sandbox`](/sdk/python/sandbox). All methods are coroutines, so `await` each call.

## Methods

---

#### <span className="msb-recv">fs.</span><span className="msb-hn">read()</span>
<div className="msb-tags"><span className="msb-tag is-instance">instance</span><span className="msb-tag is-async">async</span></div>

```python
async def read(path: str) -> bytes
```

Read the entire contents of a file as raw bytes.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path</code><span className="msb-type">str</span></div>
    <div className="msb-param-desc">Absolute path inside the guest, e.g. <code>"/app/config.json"</code>.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><span className="msb-type">bytes</span></div>
    <div className="msb-param-desc">File contents as raw bytes.</div>
  </div>
</div>

<Accordion title="Example">

```python
raw = await sb.fs.read("/app/data.bin")
print(len(raw))
```

</Accordion>

---

#### <span className="msb-recv">fs.</span><span className="msb-hn">read_text()</span>
<div className="msb-tags"><span className="msb-tag is-instance">instance</span><span className="msb-tag is-async">async</span></div>

```python
async def read_text(path: str) -> str
```

Read the entire contents of a file and decode it as UTF-8.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path</code><span className="msb-type">str</span></div>
    <div className="msb-param-desc">Absolute path inside the guest.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><span className="msb-type">str</span></div>
    <div className="msb-param-desc">File contents decoded as UTF-8.</div>
  </div>
</div>

<Accordion title="Example">

```python
config = await sb.fs.read_text("/app/config.json")
```

</Accordion>

---

#### <span className="msb-recv">fs.</span><span className="msb-hn">read_stream()</span>
<div className="msb-tags"><span className="msb-tag is-instance">instance</span><span className="msb-tag is-async">async</span></div>

```python
async def read_stream(path: str) -> FsReadStream
```

Open a streaming reader for a file. Use this for files too large to hold in memory. The returned [`FsReadStream`](#fsreadstream) is an async iterator that yields chunks of bytes, or call its `collect()` to gather everything into one `bytes`.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path</code><span className="msb-type">str</span></div>
    <div className="msb-param-desc">Absolute path inside the guest.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#fsreadstream">FsReadStream</a></div>
    <div className="msb-param-desc">Async iterator yielding chunks of file data.</div>
  </div>
</div>

<Accordion title="Example">

```python
stream = await sb.fs.read_stream("/app/large.log")
async for chunk in stream:
    process(chunk)
```

</Accordion>

---

#### <span className="msb-recv">fs.</span><span className="msb-hn">write()</span>
<div className="msb-tags"><span className="msb-tag is-instance">instance</span><span className="msb-tag is-async">async</span></div>

```python
async def write(path: str, data: bytes) -> None
```

Write content to a file, creating it if it doesn't exist and overwriting it if it does.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path</code><span className="msb-type">str</span></div>
    <div className="msb-param-desc">Absolute path inside the guest.</div>
  </div>
  <div className="msb-param">
    <div className="msb-param-key"><code>data</code><span className="msb-type">bytes</span></div>
    <div className="msb-param-desc">File content.</div>
  </div>
</div>

<Accordion title="Example">

```python
await sb.fs.write("/app/hello.txt", b"hi\n")
```

</Accordion>

---

#### <span className="msb-recv">fs.</span><span className="msb-hn">write_stream()</span>
<div className="msb-tags"><span className="msb-tag is-instance">instance</span><span className="msb-tag is-async">async</span></div>

```python
async def write_stream(path: str) -> FsWriteSink
```

Open a streaming writer for a file. Use this for files too large to hold in memory. The returned [`FsWriteSink`](#fswritesink) supports the async context manager protocol, so `async with` closes and finalizes the file automatically.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path</code><span className="msb-type">str</span></div>
    <div className="msb-param-desc">Absolute path inside the guest.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#fswritesink">FsWriteSink</a></div>
    <div className="msb-param-desc">Async writer that accepts chunks of bytes.</div>
  </div>
</div>

<Accordion title="Example">

```python
async with await sb.fs.write_stream("/app/out.bin") as sink:
    await sink.write(b"chunk one")
    await sink.write(b"chunk two")
```

</Accordion>

---

#### <span className="msb-recv">fs.</span><span className="msb-hn">list()</span>
<div className="msb-tags"><span className="msb-tag is-instance">instance</span><span className="msb-tag is-async">async</span></div>

```python
async def list(path: str) -> list[FsEntry]
```

List the entries in a directory.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path</code><span className="msb-type">str</span></div>
    <div className="msb-param-desc">Absolute directory path inside the guest.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#fsentry">list[FsEntry]</a></div>
    <div className="msb-param-desc">Directory entries.</div>
  </div>
</div>

<Accordion title="Example">

```python
for entry in await sb.fs.list("/app"):
    print(entry.kind, entry.path)
```

</Accordion>

---

#### <span className="msb-recv">fs.</span><span className="msb-hn">mkdir()</span>
<div className="msb-tags"><span className="msb-tag is-instance">instance</span><span className="msb-tag is-async">async</span></div>

```python
async def mkdir(path: str) -> None
```

Create a directory, including any missing parent directories.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path</code><span className="msb-type">str</span></div>
    <div className="msb-param-desc">Absolute directory path inside the guest.</div>
  </div>
</div>

<Accordion title="Example">

```python
await sb.fs.mkdir("/app/data/cache")
```

</Accordion>

---

#### <span className="msb-recv">fs.</span><span className="msb-hn">stat()</span>
<div className="msb-tags"><span className="msb-tag is-instance">instance</span><span className="msb-tag is-async">async</span></div>

```python
async def stat(path: str) -> FsMetadata
```

Get detailed metadata for a file or directory.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path</code><span className="msb-type">str</span></div>
    <div className="msb-param-desc">Absolute path inside the guest.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#fsmetadata">FsMetadata</a></div>
    <div className="msb-param-desc">File metadata.</div>
  </div>
</div>

<Accordion title="Example">

```python
meta = await sb.fs.stat("/app/config.json")
print(meta.kind, meta.size, meta.readonly)
```

</Accordion>

---

#### <span className="msb-recv">fs.</span><span className="msb-hn">exists()</span>
<div className="msb-tags"><span className="msb-tag is-instance">instance</span><span className="msb-tag is-async">async</span></div>

```python
async def exists(path: str) -> bool
```

Check whether a path exists inside the sandbox.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path</code><span className="msb-type">str</span></div>
    <div className="msb-param-desc">Absolute path inside the guest.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><span className="msb-type">bool</span></div>
    <div className="msb-param-desc"><code>True</code> if the path exists.</div>
  </div>
</div>

<Accordion title="Example">

```python
if not await sb.fs.exists("/app/config.json"):
    await sb.fs.write("/app/config.json", b"{}")
```

</Accordion>

---

#### <span className="msb-recv">fs.</span><span className="msb-hn">remove_dir()</span>
<div className="msb-tags"><span className="msb-tag is-instance">instance</span><span className="msb-tag is-async">async</span></div>

```python
async def remove_dir(path: str) -> None
```

Remove a directory and its contents recursively.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path</code><span className="msb-type">str</span></div>
    <div className="msb-param-desc">Absolute directory path inside the guest.</div>
  </div>
</div>

<Accordion title="Example">

```python
await sb.fs.remove_dir("/app/data/cache")
```

</Accordion>

---

#### <span className="msb-recv">fs.</span><span className="msb-hn">copy()</span>
<div className="msb-tags"><span className="msb-tag is-instance">instance</span><span className="msb-tag is-async">async</span></div>

```python
async def copy(src: str, dst: str) -> None
```

Copy a file within the sandbox.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>src</code><span className="msb-type">str</span></div>
    <div className="msb-param-desc">Source path inside the guest.</div>
  </div>
  <div className="msb-param">
    <div className="msb-param-key"><code>dst</code><span className="msb-type">str</span></div>
    <div className="msb-param-desc">Destination path inside the guest.</div>
  </div>
</div>

<Accordion title="Example">

```python
await sb.fs.copy("/app/config.json", "/app/config.bak.json")
```

</Accordion>

---

#### <span className="msb-recv">fs.</span><span className="msb-hn">rename()</span>
<div className="msb-tags"><span className="msb-tag is-instance">instance</span><span className="msb-tag is-async">async</span></div>

```python
async def rename(src: str, dst: str) -> None
```

Rename or move a file or directory within the sandbox.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>src</code><span className="msb-type">str</span></div>
    <div className="msb-param-desc">Current path inside the guest.</div>
  </div>
  <div className="msb-param">
    <div className="msb-param-key"><code>dst</code><span className="msb-type">str</span></div>
    <div className="msb-param-desc">New path inside the guest.</div>
  </div>
</div>

<Accordion title="Example">

```python
await sb.fs.rename("/app/tmp.txt", "/app/final.txt")
```

</Accordion>

---

#### <span className="msb-recv">fs.</span><span className="msb-hn">remove()</span>
<div className="msb-tags"><span className="msb-tag is-instance">instance</span><span className="msb-tag is-async">async</span></div>

```python
async def remove(path: str) -> None
```

Remove a file. Use [`remove_dir()`](#fs-remove_dir) for directories.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path</code><span className="msb-type">str</span></div>
    <div className="msb-param-desc">Absolute file path inside the guest.</div>
  </div>
</div>

<Accordion title="Example">

```python
await sb.fs.remove("/app/config.bak.json")
```

</Accordion>

---

#### <span className="msb-recv">fs.</span><span className="msb-hn">copy_from_host()</span>
<div className="msb-tags"><span className="msb-tag is-instance">instance</span><span className="msb-tag is-async">async</span></div>

```python
async def copy_from_host(host_path: str, guest_path: str) -> None
```

Copy a file from the host machine into the sandbox. For transferring many files, consider a [bind-mounted volume](/sandboxes/volumes) instead.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>host_path</code><span className="msb-type">str</span></div>
    <div className="msb-param-desc">Path on the host filesystem.</div>
  </div>
  <div className="msb-param">
    <div className="msb-param-key"><code>guest_path</code><span className="msb-type">str</span></div>
    <div className="msb-param-desc">Destination path inside the sandbox.</div>
  </div>
</div>

<Accordion title="Example">

```python
await sb.fs.copy_from_host("./local/seed.csv", "/app/seed.csv")
```

</Accordion>

---

#### <span className="msb-recv">fs.</span><span className="msb-hn">copy_to_host()</span>
<div className="msb-tags"><span className="msb-tag is-instance">instance</span><span className="msb-tag is-async">async</span></div>

```python
async def copy_to_host(guest_path: str, host_path: str) -> None
```

Copy a file from the sandbox out to the host machine.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>guest_path</code><span className="msb-type">str</span></div>
    <div className="msb-param-desc">Path inside the sandbox.</div>
  </div>
  <div className="msb-param">
    <div className="msb-param-key"><code>host_path</code><span className="msb-type">str</span></div>
    <div className="msb-param-desc">Destination path on the host.</div>
  </div>
</div>

<Accordion title="Example">

```python
await sb.fs.copy_to_host("/app/report.pdf", "./report.pdf")
```

</Accordion>

---

## Types

### FsEntry

<div className="msb-tags"><span className="msb-tag is-type">class</span></div>

<p className="msb-backref">Returned by <a href="#fs-list">list()</a></p>

Metadata for a single directory entry, returned by [`list()`](#fs-list).

| Property | Type | Description |
|----------|------|-------------|
| path | `str` | Full path of the entry |
| kind | `str` | Entry type: `"file"`, `"directory"`, `"symlink"`, or `"other"` (see [`FsEntryKind`](#fsentrykind)) |
| size | `int` | File size in bytes |
| mode | `int` | Unix permission bits |
| modified | `float \| None` | Last-modified time, milliseconds since the Unix epoch |

### FsEntryKind

<div className="msb-tags"><span className="msb-tag is-type">enum</span></div>

<p className="msb-backref">Describes <a href="#fsentry">FsEntry.kind</a> · <a href="#fsmetadata">FsMetadata.kind</a></p>

String enum ([`StrEnum`](https://docs.python.org/3/library/enum.html#enum.StrEnum)) of filesystem entry types. The `kind` fields on [`FsEntry`](#fsentry) and [`FsMetadata`](#fsmetadata) carry these string values.

| Value | Description |
|-------|-------------|
| `"file"` | Regular file |
| `"directory"` | Directory |
| `"symlink"` | Symbolic link |
| `"other"` | Other entry type |

### FsMetadata

<div className="msb-tags"><span className="msb-tag is-type">class</span></div>

<p className="msb-backref">Returned by <a href="#fs-stat">stat()</a></p>

Detailed file metadata, returned by [`stat()`](#fs-stat).

| Property | Type | Description |
|----------|------|-------------|
| kind | `str` | Entry type: `"file"`, `"directory"`, `"symlink"`, or `"other"` (see [`FsEntryKind`](#fsentrykind)) |
| size | `int` | File size in bytes |
| mode | `int` | Unix permission bits |
| readonly | `bool` | Whether the file is read-only |
| modified | `float \| None` | Last-modified time, milliseconds since the Unix epoch |
| created | `float \| None` | Creation time, milliseconds since the Unix epoch |

### FsReadStream

<div className="msb-tags"><span className="msb-tag is-type">class</span></div>

<p className="msb-backref">Returned by <a href="#fs-read_stream">read_stream()</a></p>

Async stream for reading a file in chunks. Obtained via [`read_stream()`](#fs-read_stream). Iterate it with `async for chunk in stream:`, or call `collect()` to gather everything at once.

| Method / Protocol | Returns | Description |
|-------------------|---------|-------------|
| `__aiter__` / `__anext__` | `bytes` | Async iterator. Use `async for chunk in stream:`. |
| collect() | `bytes` | *(async)* Collect all remaining data into a single `bytes` object |

### FsWriteSink

<div className="msb-tags"><span className="msb-tag is-type">class</span></div>

<p className="msb-backref">Returned by <a href="#fs-write_stream">write_stream()</a></p>

Async writer for streaming data into a file. Obtained via [`write_stream()`](#fs-write_stream). Supports the async context manager protocol, so `async with` closes the sink on exit.

| Method / Protocol | Returns | Description |
|-------------------|---------|-------------|
| write(data) | `None` | *(async)* Write a chunk of `bytes` to the file |
| close() | `None` | *(async)* Send EOF and finalize the file |
| `__aenter__` / `__aexit__` | `FsWriteSink` | *(async)* Use with `async with` for automatic close on exit |
