modal.NetworkFileSystem

class NetworkFileSystem(modal.object.Object)

A shared, writable file system accessible by one or more Modal functions.

By attaching this file system as a mount to one or more functions, they can share and persist data with each other.

Usage

import modal

volume = modal.NetworkFileSystem.new()
stub = modal.Stub()

@stub.function(network_file_systems={"/root/foo": volume})
def f():
    pass

@stub.function(network_file_systems={"/root/goo": volume})
def g():
    pass

It is often the case that you would want to persist a network file system object separately from the currently attached app. Refer to the persistence guide section to see how to persist this object across app runs.

Also see the CLI methods for accessing network file systems:

modal nfs --help

A NetworkFileSystem can also be useful for some local scripting scenarios, e.g.:

vol = modal.NetworkFileSystem.lookup("my-network-file-system")
for chunk in vol.read_file("my_db_dump.csv"):
    ...
def __init__(self, *args, **kwargs):

from_id

@classmethod
def from_id(cls: Type[O], object_id: str, client: Optional[_Client] = None) -> O:

Retrieve an object from its unique ID (accessed through obj.object_id).

persist

def persist(
    self,
    label: str,
    namespace=api_pb2.DEPLOYMENT_NAMESPACE_WORKSPACE,
    environment_name: Optional[str] = None,
    cloud: Optional[str] = None,
):

NetworkFileSystem().persist("my-volume") is deprecated. Use NetworkFileSystem.persisted("my-volume") instead.

from_name

@classmethod
def from_name(
    cls: Type[O],
    app_name: str,
    tag: Optional[str] = None,
    namespace=api_pb2.DEPLOYMENT_NAMESPACE_WORKSPACE,
    environment_name: Optional[str] = None,
) -> O:

Retrieve an object with a given name and tag.

Useful for referencing secrets, as well as calling a function from a different app. Use this when attaching the object to a stub or function.

Examples

# Retrieve a secret
stub.my_secret = Secret.from_name("my-secret")

# Retrieve a function from a different app
stub.other_function = Function.from_name("other-app", "function")

# Retrieve a persisted Volume, Queue, or Dict
stub.my_volume = Volume.from_name("my-volume")
stub.my_queue = Queue.from_name("my-queue")
stub.my_dict = Dict.from_name("my-dict")

lookup

@classmethod
def lookup(
    cls: Type[O],
    app_name: str,
    tag: Optional[str] = None,
    namespace=api_pb2.DEPLOYMENT_NAMESPACE_WORKSPACE,
    client: Optional[_Client] = None,
    environment_name: Optional[str] = None,
) -> O:

Lookup an object with a given name and tag.

This is a general-purpose method for objects like functions, network file systems, and secrets. It gives a reference to the object in a running app.

Examples

# Lookup a secret
my_secret = Secret.lookup("my-secret")

# Lookup a function from a different app
other_function = Function.lookup("other-app", "function")

# Lookup a persisted Volume, Queue, or Dict
my_volume = Volume.lookup("my-volume")
my_queue = Queue.lookup("my-queue")
my_dict = Dict.lookup("my-dict")

new

@typechecked
@staticmethod
def new(cloud: Optional[str] = None) -> "_NetworkFileSystem":

Construct a new network file system, which is empty by default.

persisted

@staticmethod
def persisted(
    label: str,
    namespace=api_pb2.DEPLOYMENT_NAMESPACE_WORKSPACE,
    environment_name: Optional[str] = None,
    cloud: Optional[str] = None,
) -> "_NetworkFileSystem":

Deploy a Modal app containing this object.

The deployed object can then be imported from other apps, or by calling NetworkFileSystem.from_name(label) from that same app.

Examples

# In one app:
volume = NetworkFileSystem.persisted("my-volume")

# Later, in another app or Python file:
volume = NetworkFileSystem.from_name("my-volume")

@stub.function(network_file_systems={"/vol": volume})
def f():
    pass

write_file

@live_method
def write_file(self, remote_path: str, fp: BinaryIO) -> int:

Write from a file object to a path on the network file system, atomically.

Will create any needed parent directories automatically.

If remote_path ends with / it’s assumed to be a directory and the file will be uploaded with its current name to that directory.

read_file

@live_method_gen
def read_file(self, path: str) -> AsyncIterator[bytes]:

Read a file from the network file system

iterdir

@live_method_gen
def iterdir(self, path: str) -> AsyncIterator[api_pb2.SharedVolumeListFilesEntry]:

Iterate over all files in a directory in the network file system.

  • Passing a directory path lists all files in the directory (names are relative to the directory)
  • Passing a file path returns a list containing only that file’s listing description
  • Passing a glob path (including at least one * or ** sequence) returns all files matching that glob path (using absolute paths)

add_local_file

@live_method
def add_local_file(
    self, local_path: Union[Path, str], remote_path: Optional[Union[str, PurePosixPath, None]] = None
):

add_local_dir

@live_method
def add_local_dir(
    self,
    local_path: Union[Path, str],
    remote_path: Optional[Union[str, PurePosixPath, None]] = None,
):

listdir

@live_method
def listdir(self, path: str) -> List[api_pb2.SharedVolumeListFilesEntry]:

List all files in a directory in the network file system.

  • Passing a directory path lists all files in the directory (names are relative to the directory)
  • Passing a file path returns a list containing only that file’s listing description
  • Passing a glob path (including at least one * or ** sequence) returns all files matching that glob path (using absolute paths)

remove_file

@live_method
def remove_file(self, path: str, recursive=False):

Remove a file in a network file system.