Skip to main content
A volume is an OuterProduct resource that maps a name to a location in object storage. The volume stores metadata about that location; the data and objects remain in the backing object store. Volumes have two storage types:
  • OuterProduct-managed storage: OuterProduct allocates and manages the backing object-store location. This is the default when creating a volume.
  • External storage: The volume references an existing S3 bucket or Google Cloud Storage bucket. OuterProduct does not copy the existing objects.
Both types use the same Python API and can be mounted as files in a function’s runtime environment.

Creating a managed volume

client.create_volume() creates a volume and returns a VolumeHandle. OuterProduct manages the underlying object storage by default when the provider argument is omitted. Each volume has a name consisting of volumes/ followed by the string provided at creation time.
Volume names are case-insensitive and must be unique within a workspace. Creating a volume with an existing name raises an already_exists error.

Creating a volume based on an external object store

OuterProduct Volumes can also be created from existing S3 buckets and Google Cloud Storage buckets without copying their contents. To connect to an external store, cloud credentials should first be stored as OuterProduct Secrets.
An S3 volume specifies a bucket and a stored AWS credential:
With this prefix, training.csv in the volume corresponds to s3://my-bucket/datasets/training.csv. If no prefix is specified, paths will be relative to the bucket’s root.

Managing volume resources

client.list_volumes() returns accessible Volume metadata, while client.get_volume() takes a volume name (with or without the volumes/ prefix) and returns a handle to an existing volume. Use update_volume() to rename a volume or change its description without changing its identity. client.delete_volume() removes the volume resource and its metadata. Deleting an OuterProduct-managed volume also deletes its stored files. For a volume backed by your own object store, the files are retained.

Reading and writing data

VolumeHandle provides methods for reading and writing objects through obstore.
put() accepts bytes, local files, and streams. get() returns a result whose contents can be read into memory with .bytes() or consumed as a stream. When using these methods, object paths should be specified relative to the volume’s root. The handle also supports other standard methods for interacting with an object store, including listing objects, inspecting metadata, copying, renaming, and deleting data.
volume_handle.list(prefix) is an async iterator that yields batches of object metadata under the prefix. It is used with async for and has no synchronous form. See Async usage.

Mounting a volume

The volumes argument to client.run() is a dictionary mapping filesystem paths to volume handles, volume names, or UUIDs. At runtime, the volume’s contents are mounted at the specified path:
Volume mounts are not inherited by child calls, so each child call must declare its own mounts. Mounting requires both read and write access to the volume. See Policies for more information on permissions in OuterProduct. Mounted volumes support reading files and sequential writes to new files. They do not support in-place edits, appending, or atomic renames.
Volume mounts use temporary credentials and stop working an hour after an Attempt starts. Set timeout=3600 or less on client.run() for Calls that mount volumes; client.run() warns otherwise. Calls that need longer should read and write the volume through VolumeHandle methods such as get() and put(), which refresh their credentials as needed.