File Access
If you want to pass data in and out of the Sandbox during execution, you can use our filesystem API to easily read and write files. The API supports reading files up to 100 MiB and writes up to 16 MiB in size.
import modal
app = modal.App.lookup("sandbox-fs-demo", create_if_missing=True)
sb = modal.Sandbox.create(app=app)
with sb.open("test.txt", "w") as f:
f.write("Hello World\n")
f = sb.open("test.txt", "rb")
print(f.read())
f.close()
The filesystem API is similar to Python’s built-in io.FileIO and supports many of the same methods, including read
, readline
, readlines
, write
, flush
, seek
, and close
.
In addition, we also provide the special methods replace_bytes
and delete_bytes
, which may be useful for LLM-generated code.
from modal.file_io import delete_bytes, replace_bytes
with sb.open("example.txt", "w") as f:
f.write("The quick brown fox jumps over the lazy dog")
with sb.open("example.txt", "r+") as f:
# The quick brown fox jumps over the lazy dog
print(f.read())
# The slow brown fox jumps over the lazy dog
replace_bytes(f, b"slow", start=4, end=9)
# The slow red fox jumps over the lazy dog
replace_bytes(f, b"red", start=9, end=14)
# The slow red fox jumps over the dog
delete_bytes(f, start=32, end=37)
f.seek(0)
print(f.read())
sb.terminate()
Syncing files outside the Sandbox
Modal Volumes or
CloudBucketMounts can also be attached to
Sandboxes for file syncing outside the Sandbox. If you want to give the caller
access to files written by the Sandbox, you could create an ephemeral Volume
that will be garbage collected when the App finishes:
with modal.Volume.ephemeral() as vol:
sb = modal.Sandbox.create(
volumes={"/cache": vol},
app=my_app,
)
p = sb.exec("bash", "-c", "echo foo > /cache/a.txt")
p.wait()
sb.terminate()
for data in vol.read_file("a.txt"):
print(data)
Alternatively, if you want to persist files between Sandbox invocations (useful
if you’re building a stateful code interpreter, for example), you can use create
a persisted Volume
with a dynamically assigned label:
session_id = "example-session-id-123abc"
vol = modal.Volume.from_name(f"vol-{session_id}", create_if_missing=True)
sb = modal.Sandbox.create(
volumes={"/cache": vol},
app=my_app,
)
p = sb.exec("bash", "-c", "echo foo > /cache/a.txt")
p.wait()
sb.terminate()
for data in vol.read_file("a.txt"):
print(data)
File syncing behavior differs between Volumes and CloudBucketMounts. For Volumes, files are only synced back to the Volume when the Sandbox terminates. For CloudBucketMounts, files are synced automatically.