S3 API Usage
ZSoftly object storage is S3-compatible. Any tool or SDK that supports S3 works with it.
Endpoints:
| Region | Endpoint |
|---|---|
| YUL (Montreal) | https://objects.yul.zcp.zsoftly.ca |
| YOW (Ottawa) | https://objects.yow.zcp.zsoftly.ca |
Examples below use the YUL endpoint. Substitute YOW if your bucket is in Ottawa.
Find your bucket name
Section titled “Find your bucket name”Before you write an endpoint URL, confirm the bucket’s real name. The platform appends a numeric
suffix to the name you asked for when the bucket is created. A bucket you requested as my-bucket
exists as something like my-bucket-001024. That suffixed value is the name the S3 API answers to.
Using the name you typed gives NoSuchBucket even though the bucket exists.
zcp object-storage bucket list <storage-slug> --region os-yul --project <project-slug>SLUG NAME OBJECTS SIZE (GB) STATUSmy-bucket-001024 my-bucket-001024 0 InactiveUse that value everywhere below in place of my-bucket. A bucket showing Inactive with zero
objects is normal until something is written to it.
Connect and list buckets
Section titled “Connect and list buckets”Configure your client with the regional endpoint and your access keys, then list your buckets. Pick your language:
# Store your credentials onceaws configure set aws_access_key_id <access-key>aws configure set aws_secret_access_key <secret-key>
# List bucketsaws s3 ls --endpoint-url https://objects.yul.zcp.zsoftly.caimport boto3
s3 = boto3.client( "s3", endpoint_url="https://objects.yul.zcp.zsoftly.ca", aws_access_key_id="<access-key>", aws_secret_access_key="<secret-key>",)
for bucket in s3.list_buckets()["Buckets"]: print(bucket["Name"])import { S3Client, ListBucketsCommand } from '@aws-sdk/client-s3';
const client = new S3Client({ endpoint: 'https://objects.yul.zcp.zsoftly.ca', region: 'us-east-1', credentials: { accessKeyId: '<access-key>', secretAccessKey: '<secret-key>' }, forcePathStyle: true,});
const { Buckets } = await client.send(new ListBucketsCommand({}));for (const b of Buckets ?? []) console.log(b.Name);import { S3Client, ListBucketsCommand, type Bucket } from '@aws-sdk/client-s3';
const client = new S3Client({ endpoint: 'https://objects.yul.zcp.zsoftly.ca', region: 'us-east-1', credentials: { accessKeyId: '<access-key>', secretAccessKey: '<secret-key>' }, forcePathStyle: true,});
const { Buckets } = await client.send(new ListBucketsCommand({}));Buckets?.forEach((b: Bucket) => console.log(b.Name));package main
import ( "context" "fmt"
"github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/credentials" "github.com/aws/aws-sdk-go-v2/service/s3")
func main() { client := s3.New(s3.Options{ BaseEndpoint: aws.String("https://objects.yul.zcp.zsoftly.ca"), Region: "us-east-1", Credentials: credentials.NewStaticCredentialsProvider("<access-key>", "<secret-key>", ""), UsePathStyle: true, })
out, err := client.ListBuckets(context.TODO(), &s3.ListBucketsInput{}) if err != nil { panic(err) } for _, b := range out.Buckets { fmt.Println(*b.Name) }}using Amazon.S3;
var config = new AmazonS3Config{ ServiceURL = "https://objects.yul.zcp.zsoftly.ca", ForcePathStyle = true,};using var client = new AmazonS3Client("<access-key>", "<secret-key>", config);
var response = await client.ListBucketsAsync();foreach (var bucket in response.Buckets){ Console.WriteLine(bucket.BucketName);}import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;import software.amazon.awssdk.regions.Region;import software.amazon.awssdk.services.s3.S3Client;import software.amazon.awssdk.services.s3.S3Configuration;
import java.net.URI;
public class ListBuckets { public static void main(String[] args) { S3Client s3 = S3Client.builder() .endpointOverride(URI.create("https://objects.yul.zcp.zsoftly.ca")) .region(Region.US_EAST_1) .credentialsProvider(StaticCredentialsProvider.create( AwsBasicCredentials.create("<access-key>", "<secret-key>"))) .serviceConfiguration(S3Configuration.builder() .pathStyleAccessEnabled(true).build()) .build();
s3.listBuckets().buckets().forEach(b -> System.out.println(b.name())); }}require "aws-sdk-s3"
s3 = Aws::S3::Client.new( endpoint: "https://objects.yul.zcp.zsoftly.ca", region: "us-east-1", access_key_id: "<access-key>", secret_access_key: "<secret-key>", force_path_style: true)
s3.list_buckets.buckets.each { |b| puts b.name }<?phprequire "vendor/autoload.php";
use Aws\S3\S3Client;
$s3 = new S3Client([ "version" => "latest", "region" => "us-east-1", "endpoint" => "https://objects.yul.zcp.zsoftly.ca", "use_path_style_endpoint" => true, "credentials" => [ "key" => "<access-key>", "secret" => "<secret-key>", ],]);
foreach ($s3->listBuckets()["Buckets"] as $bucket) { echo $bucket["Name"] . "\n";}Common operations
Section titled “Common operations”Once your client (or the AWS CLI) is configured, all standard S3 operations work. Using the AWS CLI:
# Create a bucketaws s3 mb s3://my-bucket --endpoint-url https://objects.yul.zcp.zsoftly.ca
# Upload a fileaws s3 cp ./file.txt s3://my-bucket/ --endpoint-url https://objects.yul.zcp.zsoftly.ca
# Download a fileaws s3 cp s3://my-bucket/file.txt ./file.txt --endpoint-url https://objects.yul.zcp.zsoftly.ca
# List objects in a bucketaws s3 ls s3://my-bucket/ --endpoint-url https://objects.yul.zcp.zsoftly.ca
# Delete an objectaws s3 rm s3://my-bucket/file.txt --endpoint-url https://objects.yul.zcp.zsoftly.cas3cmd is a standalone command-line client for S3-compatible storage.
Install it, then create ~/.s3cfg:
[default]access_key = <access-key>secret_key = <secret-key>host_base = objects.yul.zcp.zsoftly.cahost_bucket = objects.yul.zcp.zsoftly.cause_https = TrueThis file holds your secret key, so restrict its permissions:
chmod 600 ~/.s3cfgSetting host_bucket to the same value as host_base, with no bucket placeholder, forces the
path-style addressing the service requires. For a bucket in Ottawa, use
objects.yow.zcp.zsoftly.ca.
Run the common commands:
s3cmd ls # list your bucketss3cmd mb s3://my-bucket # create a buckets3cmd put ./file.txt s3://my-bucket/ # upload a files3cmd get s3://my-bucket/file.txt . # download a files3cmd sync ./local-dir/ s3://my-bucket/dir/ # sync a folders3cmd rm s3://my-bucket/file.txt # delete an objectSee also: Access Keys, Create Bucket