docs/sdk/python/filesystem.mdx
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 for usage examples. For bulk file movement, prefer a volume.
<p className="msb-label" id="typical-flow">Typical flow</p>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. All methods are coroutines, so await each call.
async def read(path: str) -> bytes
raw = await sb.fs.read("/app/data.bin")
print(len(raw))
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>async def read_text(path: str) -> str
config = await sb.fs.read_text("/app/config.json")
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>async def read_stream(path: str) -> FsReadStream
stream = await sb.fs.read_stream("/app/large.log")
async for chunk in stream:
process(chunk)
Open a streaming reader for a file. Use this for files too large to hold in memory. The returned FsReadStream is an async iterator that yields chunks of bytes, or call its collect() to gather everything into one bytes.
async def write(path: str, data: bytes) -> None
await sb.fs.write("/app/hello.txt", b"hi\n")
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>async def write_stream(path: str) -> FsWriteSink
async with await sb.fs.write_stream("/app/out.bin") as sink:
await sink.write(b"chunk one")
await sink.write(b"chunk two")
Open a streaming writer for a file. Use this for files too large to hold in memory. The returned FsWriteSink supports the async context manager protocol, so async with closes and finalizes the file automatically.
async def list(path: str) -> list[FsEntry]
for entry in await sb.fs.list("/app"):
print(entry.kind, entry.path)
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>async def mkdir(path: str) -> None
await sb.fs.mkdir("/app/data/cache")
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>async def stat(path: str) -> FsMetadata
meta = await sb.fs.stat("/app/config.json")
print(meta.kind, meta.size, meta.readonly)
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>async def exists(path: str) -> bool
if not await sb.fs.exists("/app/config.json"):
await sb.fs.write("/app/config.json", b"{}")
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>async def remove_dir(path: str) -> None
await sb.fs.remove_dir("/app/data/cache")
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>async def copy(src: str, dst: str) -> None
await sb.fs.copy("/app/config.json", "/app/config.bak.json")
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>async def rename(src: str, dst: str) -> None
await sb.fs.rename("/app/tmp.txt", "/app/final.txt")
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>async def remove(path: str) -> None
await sb.fs.remove("/app/config.bak.json")
Remove a file. Use remove_dir() for directories.
async def copy_from_host(host_path: str, guest_path: str) -> None
await sb.fs.copy_from_host("./local/seed.csv", "/app/seed.csv")
Copy a file from the host machine into the sandbox. For transferring many files, consider a bind-mounted volume 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>async def copy_to_host(guest_path: str, host_path: str) -> None
await sb.fs.copy_to_host("/app/report.pdf", "./report.pdf")
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>Metadata for a single directory entry, returned by list().
| Property | Type | Description |
|---|---|---|
| path | str | Full path of the entry |
| kind | str | Entry type: "file", "directory", "symlink", or "other" (see FsEntryKind) |
| size | int | File size in bytes |
| mode | int | Unix permission bits |
| modified | float | None | Last-modified time, milliseconds since the Unix epoch |
String enum (StrEnum) of filesystem entry types. The kind fields on FsEntry and FsMetadata carry these string values.
| Value | Description |
|---|---|
"file" | Regular file |
"directory" | Directory |
"symlink" | Symbolic link |
"other" | Other entry type |
Detailed file metadata, returned by stat().
| Property | Type | Description |
|---|---|---|
| kind | str | Entry type: "file", "directory", "symlink", or "other" (see 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 |
Async stream for reading a file in chunks. Obtained via 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 |
Async writer for streaming data into a file. Obtained via 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 |