Skip to content

Quick start

This starts a server on your machine, creates a bucket, and stores and reads an object with three common clients.

Start the server

leblob serve --data-dir ./data

From a source checkout, prefix the commands on this page with uv run. The server listens on http://127.0.0.1:9000. The first start creates the data directory and an access key, and prints the key once:

Created the first access key; the secret isn't shown again:
  access key: ...
  secret key: ...

Keep both values. If you lose the secret, create another key with leblob key create --data-dir ./data, and delete the old one with leblob key delete.

leblob serve --help lists the options: the address and port, the number of worker processes, TLS, and a base domain for virtual-hosted addressing.

Store and read an object

Any region name works when signing. The examples use us-east-1.

import boto3
from botocore.config import Config

s3 = boto3.client(
    "s3",
    endpoint_url="http://127.0.0.1:9000",
    aws_access_key_id="...",
    aws_secret_access_key="...",
    region_name="us-east-1",
    config=Config(signature_version="s3v4"),
)
s3.create_bucket(Bucket="my-bucket")
s3.put_object(Bucket="my-bucket", Key="hello.txt", Body=b"hello")
print(s3.get_object(Bucket="my-bucket", Key="hello.txt")["Body"].read())
export AWS_ACCESS_KEY_ID=...
export AWS_SECRET_ACCESS_KEY=...
export AWS_REGION=us-east-1

aws --endpoint-url http://127.0.0.1:9000 s3 mb s3://my-bucket
echo hello > hello.txt
aws --endpoint-url http://127.0.0.1:9000 s3 cp hello.txt s3://my-bucket/
aws --endpoint-url http://127.0.0.1:9000 s3 ls s3://my-bucket/

In ~/.config/rclone/rclone.conf:

[leblob]
type = s3
provider = Other
endpoint = http://127.0.0.1:9000
access_key_id = ...
secret_access_key = ...
force_path_style = true

Then:

rclone mkdir leblob:my-bucket
rclone copy hello.txt leblob:my-bucket
rclone ls leblob:my-bucket

Presigned URLs need SigV4

leBLOB only accepts SigV4 signatures. boto3 signs ordinary requests with SigV4, but presigns URLs with SigV2 unless told otherwise, and leBLOB refuses those with 403. Creating the client with config=Config(signature_version="s3v4"), as above, makes both SigV4:

url = s3.generate_presigned_url(
    "get_object", Params={"Bucket": "my-bucket", "Key": "hello.txt"}, ExpiresIn=3600
)

A ~/.aws/config that sets signature_version can hide this on one machine and not on another.

Check that it is up

curl http://127.0.0.1:9000/-/health

Where to go next