Storage
Manage object storage (buckets) and NFS volumes using the Podstack SDK.
Object Storage (Buckets)
Create Bucket
from podstack import Client
client = Client()
bucket = client.buckets.create(
name="my-datasets",
visibility="private" # or "public"
)
print(f"Bucket: {bucket.name}")
print(f"Endpoint: {bucket.endpoint}")
List Buckets
buckets = client.buckets.list()
for bucket in buckets:
print(f"{bucket.name}: {bucket.visibility} ({bucket.size_gb:.2f} GB)")
Get Bucket Details
bucket = client.buckets.get("bucket-id")
print(f"Name: {bucket.name}")
print(f"Visibility: {bucket.visibility}")
print(f"Size: {bucket.size_gb} GB")
print(f"Object Count: {bucket.object_count}")
print(f"Endpoint: {bucket.endpoint}")
Upload Files
# Upload single file
client.buckets.upload(
bucket_id="bucket-id",
local_path="./data.csv",
remote_key="datasets/data.csv"
)
# Upload with progress
def progress(transferred, total):
pct = (transferred / total) * 100
print(f"Uploading: {pct:.1f}%")
client.buckets.upload(
bucket_id="bucket-id",
local_path="./large_model.pt",
remote_key="models/model.pt",
progress=progress
)
# Upload directory
client.buckets.upload(
bucket_id="bucket-id",
local_path="./training_data/",
remote_key="data/",
recursive=True
)
Download Files
# Download single file
client.buckets.download(
bucket_id="bucket-id",
remote_key="models/model.pt",
local_path="./model.pt"
)
# Download directory
client.buckets.download(
bucket_id="bucket-id",
remote_key="results/",
local_path="./results/",
recursive=True
)
List Objects
# List all objects
objects = client.buckets.list_objects("bucket-id")
for obj in objects:
print(f"{obj.key}: {obj.size_bytes} bytes")
# List with prefix
objects = client.buckets.list_objects(
bucket_id="bucket-id",
prefix="datasets/"
)
# Paginated listing
objects = client.buckets.list_objects(
bucket_id="bucket-id",
max_keys=100,
continuation_token=None
)
Delete Objects
# Delete single object
client.buckets.delete_object("bucket-id", "path/to/file.txt")
# Delete multiple objects
client.buckets.delete_objects("bucket-id", [
"file1.txt",
"file2.txt",
"folder/file3.txt"
])
Generate Presigned URLs
# Upload URL (for external uploads)
upload_url = client.buckets.presigned_upload_url(
bucket_id="bucket-id",
key="uploads/user-file.txt",
expires_in=3600 # 1 hour
)
# Download URL (for external downloads)
download_url = client.buckets.presigned_download_url(
bucket_id="bucket-id",
key="datasets/data.csv",
expires_in=86400 # 24 hours
)
S3 Compatible Access
# Get S3 credentials
creds = client.buckets.get_credentials("bucket-id")
print(f"Access Key: {creds.access_key}")
print(f"Secret Key: {creds.secret_key}")
print(f"Endpoint: {creds.endpoint}")
print(f"Region: {creds.region}")
# Use with boto3
import boto3
s3 = boto3.client(
's3',
endpoint_url=creds.endpoint,
aws_access_key_id=creds.access_key,
aws_secret_access_key=creds.secret_key
)
s3.upload_file("local.txt", bucket.name, "remote.txt")
Delete Bucket
# Delete empty bucket
client.buckets.delete("bucket-id")
# Force delete (removes all objects first)
client.buckets.delete("bucket-id", force=True)
NFS Volumes
Create Volume
volume = client.volumes.create(
name="shared-data",
quota_gb=100,
project_id="project-id"
)
print(f"Volume ID: {volume.id}")
print(f"NFS Path: {volume.nfs_path}")
print(f"Server: {volume.nfs_server}")
List Volumes
volumes = client.volumes.list()
for vol in volumes:
print(f"{vol.name}: {vol.used_gb:.1f}/{vol.quota_gb} GB")
Get Volume Details
volume = client.volumes.get("volume-id")
print(f"Name: {volume.name}")
print(f"Quota: {volume.quota_gb} GB")
print(f"Used: {volume.used_gb} GB")
print(f"NFS Server: {volume.nfs_server}")
print(f"NFS Path: {volume.nfs_path}")
print(f"Mount Command: mount -t nfs {volume.nfs_server}:{volume.nfs_path} /mnt/data")
Resize Volume
# Increase quota (can only increase, not decrease)
client.volumes.resize("volume-id", quota_gb=200)
Mount in Pod
# Create pod with volume mount
pod = client.pods.create(
name="training-pod",
image="pytorch/pytorch:latest",
gpu_type="A100",
volumes=[
{
"volume_id": "volume-id",
"mount_path": "/data"
}
]
)
Delete Volume
# Delete empty volume
client.volumes.delete("volume-id")
# Force delete (removes all data)
client.volumes.delete("volume-id", force=True)
Storage Best Practices
Large File Uploads
# Use multipart upload for files > 100MB
client.buckets.upload(
bucket_id="bucket-id",
local_path="./large_dataset.tar.gz",
remote_key="datasets/large_dataset.tar.gz",
multipart=True,
part_size_mb=100 # 100MB parts
)
Sync Directories
# Sync local to bucket (upload new/changed files)
client.buckets.sync(
bucket_id="bucket-id",
local_path="./data/",
remote_prefix="data/",
direction="upload"
)
# Sync bucket to local
client.buckets.sync(
bucket_id="bucket-id",
local_path="./data/",
remote_prefix="data/",
direction="download"
)
Copy Between Buckets
client.buckets.copy(
source_bucket="bucket-1",
source_key="data.csv",
dest_bucket="bucket-2",
dest_key="backup/data.csv"
)
Next Steps
- Pods - Container management
- Virtual Machines - VM operations
- Error Handling - Handle exceptions