modal.shared_volume

modal.shared_volume.SharedVolume

class SharedVolume(modal.object.Provider)

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.SharedVolume()
stub = modal.Stub()

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

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

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

def __init__(self, cloud: Optional[str] = None) -> None:

Construct a new shared volume, which is empty by default.

persist

@typechecked
def persist(self, label: str, namespace=api_pb2.DEPLOYMENT_NAMESPACE_WORKSPACE):

Deploy a Modal app containing this object. This object can then be imported from other apps using the returned reference, or by calling modal.SharedVolume.from_name(label) (or the equivalent method on respective class).

Example Usage

import modal

volume = modal.SharedVolume().persist("my-volume")

stub = modal.Stub()

# Volume refers to the same object, even across instances of `stub`.
@stub.function(shared_volumes={"/vol": volume})
def f():
    pass

from_name

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

Returns a reference to an Modal object of any type

Useful for referring to already created/deployed objects, e.g., Secrets

import modal

stub = modal.Stub()

@stub.function(secret=modal.Secret.from_name("my-secret-name"))
def some_function():
    pass

lookup

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

General purpose method to retrieve Modal objects such as functions, shared volumes, and secrets.

import modal
square = modal.Function.lookup("my-shared-app", "square")
assert square(3) == 9
vol = modal.SharedVolume.lookup("my-shared-volume")
for chunk in vol.read_file("my_db_dump.csv"):
    ...

modal.shared_volume.SharedVolumeHandle

class SharedVolumeHandle(modal.object.Handle)

Handle to a SharedVolume object.

Should typically not be used directly in a Modal function, and instead referenced through the file system, see modal.SharedVolume.

Also see the CLI methods for accessing shared volumes:

modal volume --help

A SharedVolumeHandle can however be useful for some local scripting scenarios, e.g.:

vol = modal.lookup("my-shared-volume")
for chunk in vol.read_file("my_db_dump.csv"):
    ...
def __init__(self):

is_hydrated

def is_hydrated(self) -> bool:
    # A hydrated Handle is fully functional and linked to a live object in an app
    # To hydrate Handles, run an app using stub.run() or look up the object from a running app using <HandleClass>.lookup()

from_id

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

Get an object of this type from a unique object id (retrieved from obj.object_id)

object_id

@property
def object_id(self) -> str:

A unique object id for this instance. Can be used to retrieve the object using .from_id()

from_app

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

Returns a handle to a tagged object in a deployment on Modal.

write_file

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

Write from a file object to a path on the shared volume, 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

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

Read a file from the shared volume

iterdir

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

Iterate over all files in a directory in the shared volume.

  • 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

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

add_local_dir

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

listdir

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

List all files in a directory in the shared volume.

  • 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

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

Remove a file in a shared volume.