Skip to main content
mesa.fs.mount(...) is an async context manager that yields a MesaFileSystem.
from mesa_sdk import Mesa

mesa = Mesa(org="acme")

async with mesa.fs.mount(repos=["app"]) as fs:
    data = await fs.read("/acme/app/README.md")
    print(data.decode())
Under the hood, mount() signs a single short-lived, repo-scoped access token (JWT) locally from your API key and connects to the VCS backend. The token’s repo scope is encoded as full org/repo names, so signing does not resolve repository ids over the network. The mount uses that one token for its whole lifetime: there is no background refresh and no credential hot-swap, so once the token expires the mount stops authenticating. Choose a ttl that covers the mount’s work. No server-side credential is created or revoked.

Options

repos
Sequence[str | RepoConfig]
required
Repositories to mount. Each entry can be a bare repo name such as app, a matching org/repo slug such as acme/app, or a RepoConfig for bookmark/change pinning and read-only control. The sequence must be non-empty.
ttl
int | None
Lifetime of the mount, in seconds. The mount mints one access token with this TTL and uses it until it expires; there is no refresh. Defaults to 3600 (1 hour). Maximum 86400 (24 hours). A value outside 1..86400 raises InvalidOptionsError.
disk_cache
DiskCacheConfig | None
Optional on-disk cache. When omitted, the mount uses in-memory caching only.

RepoConfig

Pin a repository to a bookmark or change at mount time.
from mesa_sdk import RepoConfig

async with mesa.fs.mount(
    repos=[
        RepoConfig(name="app", bookmark="main"),
        RepoConfig(name="docs", change_id="zyxwvutsrqponmlkzyxwvutsrqponmlk"),
    ]
) as fs:
    ...
RepoConfig.name
str
required
Repository name.
RepoConfig.bookmark
str | None
Bookmark to check out.
RepoConfig.change_id
str | None
Change ID to check out.
RepoConfig.read_only
bool
When True, the mesa daemon rejects writes to this repo with an OSError whose errno is errno.EROFS, so a single mount can mix writable and read-only repos.

DiskCacheConfig

from mesa_sdk import DiskCacheConfig

cache = DiskCacheConfig(path="/tmp/mesa-cache", max_size_bytes=500_000_000)
DiskCacheConfig.path
str
required
Directory for the on-disk cache.
DiskCacheConfig.max_size_bytes
int | None
Optional cache size cap. When omitted, the native extension auto-sizes the budget against system resources.

Paths

Mounted filesystem paths include the organization and repository name:
/<org>/<repo>/README.md
/acme/app/src/main.py
Passing repos=["acme/app"] is accepted only when acme matches the resolved client organization. Cross-org mounts are rejected with InvalidOptionsError.

Response

Yields a MesaFileSystem.

MesaFileSystem

The yielded fs object exposes async file I/O, metadata, traversal, mutation, Bash, and mounted-repo version-control helpers.
async with mesa.fs.mount(repos=["app"]) as fs:
    await fs.mkdir("/acme/app/src", recursive=True)
    await fs.write("/acme/app/src/main.py", b"print('hello')\n")
    data = await fs.read("/acme/app/src/main.py")

Byte I/O

read(path)
async -> bytes
Read a file as bytes.
write(path, content)
async -> None
Replace file contents, creating the file if missing. Parent directories must already exist.
append(path, content)
async -> None
Append bytes to a file, creating it if missing.
exists(path)
async -> bool
Return whether a path exists. Follows symlinks.

Metadata and traversal

stat(path)
async -> FsStat
Return metadata for a path, following symlinks.
lstat(path)
async -> FsStat
Return metadata for a path without following symlinks.
readdir(path)
async -> list[str]
Return entry names in a directory. Sort client-side if you need deterministic ordering.
realpath(path)
async -> str
Resolve symlinks and .. segments to a canonical path.
Return the target of a symlink.
resolve_path(base, path)
str
Join and normalize a path against a base path without touching the filesystem.

Mutations

mkdir(path, recursive=None)
async -> None
Create a directory. With recursive=True, create missing parents and do nothing when the path already exists as a directory.
rm(path, recursive=None, force=None)
async -> None
Remove a file or directory. Use recursive=True for non-empty directories and force=True to ignore missing paths.
cp(src, dest, recursive=None)
async -> None
Copy a file or directory. Use recursive=True for directories.
mv(src, dest)
async -> None
Move or rename a file or directory.
chmod(path, mode)
async -> None
Set permission bits, such as 0o755.
Create a symlink. Relative targets are stored verbatim and resolve against the parent of link at read time.
utimes(path, atime_ms, mtime_ms)
async -> None
Set access and modification times. Values are milliseconds since the Unix epoch, not seconds.
Hard links are not supported and this method raises NotImplementedError.

Subscriptions

MesaFS reads and writes are realtime by default. Use subscriptions only when your process needs an event stream that identifies which paths changed, such as to refetch data and rerender a frontend.
subscribe(handler)
MesaFileSystemSubscription
Subscribe to filesystem invalidation events. The handler is called after the changed state is visible through this filesystem instance.
async def on_change(event):
    if not event.recursive:
        content = await fs.read(event.path)
        print(event.path, content.decode())

subscription = fs.subscribe(on_change)
await subscription.unsubscribe()
handler
Callable[[WatchEvent], None | Awaitable[None]]
Callback invoked for each filesystem invalidation.
WatchEvent.path
str
Absolute MesaFS path that changed, such as /acme/app/src/index.py.
WatchEvent.recursive
bool
Whether descendants of path may have changed. Refresh any cached directory or subtree state below path when this is True.
MesaFileSystemSubscription.unsubscribe()
async -> None
Stop receiving events and close the underlying watcher.

FsStat

stat(...) and lstat(...) return FsStat.
is_file
bool
Whether the path is a regular file.
is_directory
bool
Whether the path is a directory.
Whether the path is a symlink. This is False from stat(...) when the target exists because stat follows symlinks.
mode
int
POSIX mode bits.
size
int
Size in bytes.
mtime_ms
float
Modification time in milliseconds since the Unix epoch.
Method namespaceReference
fs.bash(...)fs.bash()
fs.changesfs.changes
fs.bookmarksfs.bookmarks
fs.subscribe(...)Advanced Realtime

Errors

Raises InvalidOptionsError for an empty repo list, a ttl outside 1..86400, invalid mode, or a mismatched org prefix. Token signing or VCS connection failures can raise ApiError subclasses or connection errors.

Multiprocessing

MesaFS is not fork-safe. If you use multiprocessing, set the start method to spawn or forkserver before creating Mesa objects.
import multiprocessing

multiprocessing.set_start_method("spawn")