Python | Tigris Object Storage Documentation

Using Tigris with Python

There are three ways to use Tigris with Python:

All approaches are fully S3-compatible. Pick whichever fits your needs.

Prerequisites

Install

pip install boto3
pip install tigris-boto3-ext

This installs boto3 as a dependency if you don't already have it.

pip install boto3

If you already have boto3 installed, no changes needed — just update your configuration.

Configure credentials

Set your Tigris credentials as environment variables:

export AWS_ACCESS_KEY_ID="tid_your_access_key"

export AWS_SECRET_ACCESS_KEY="tsec_your_secret_key"

export AWS_ENDPOINT_URL="https://t3.storage.dev"

export AWS_REGION="auto"

Create a client

With AWS_ENDPOINT_URL set in your environment:

import boto3

s3 = boto3.client("s3")

Or pass the endpoint explicitly:

import boto3

s3 = boto3.client(

"s3",

endpoint_url="https://t3.storage.dev",

aws_access_key_id="tid_your_access_key",

aws_secret_access_key="tsec_your_secret_key",

region_name="auto",

)

The extension works with a standard boto3 client — no special setup required:

import boto3

s3 = boto3.client("s3")

If you have existing code that uses boto3 with AWS S3, you can migrate to Tigris by changing the endpoint and credentials. Set the environment variables above, then update your client configuration:

import boto3

from botocore.client import Config

# Before (AWS S3)

# s3 = boto3.client("s3")

# After (Tigris) — just add the endpoint and addressing style

s3 = boto3.client(

"s3",

endpoint_url="https://t3.storage.dev",

config=Config(s3={"addressing_style": "virtual"}),

)

The rest of your code stays the same. All standard S3 operations — put_object, get_object, upload_file, list_objects_v2, presigned URLs — work as-is.

Basic operations

These work the same with both boto3 and the extension.

Create a bucket

s3.create_bucket(Bucket="my-bucket")

Upload a file

# From a file on disk

s3.upload_file("data.csv", "my-bucket", "data.csv")

# From a string

s3.put_object(Bucket="my-bucket", Key="hello.txt", Body="Hello, World!")

Download a file

s3.download_file("my-bucket", "data.csv", "local-copy.csv")

List objects

response = s3.list_objects_v2(Bucket="my-bucket")

for obj in response.get("Contents", []):

print(f"  {obj['Key']}  ({obj['Size']} bytes)")

Generate a presigned URL

url = s3.generate_presigned_url(

"get_object",

Params={"Bucket": "my-bucket", "Key": "data.csv"},

ExpiresIn=3600,

)

print(url)

Snapshots and forks

You can use snapshots and forks with plain boto3 by passing Tigris-specific headers on each request, but the tigris-boto3-ext package handles this for you automatically.

Create a snapshot-enabled bucket

from tigris_boto3_ext import create_snapshot_bucket

create_snapshot_bucket(s3, "my-snapshots")

Take a snapshot

from tigris_boto3_ext import create_snapshot, list_snapshots

# Upload some data

s3.put_object(Bucket="my-snapshots", Key="model.bin", Body=b"v1 weights")

# Snapshot the current state

snapshot = create_snapshot(s3, "my-snapshots")

print(f"Snapshot version: {snapshot}")

# List all snapshots

for snap in list_snapshots(s3, "my-snapshots"):

print(snap)

Read from a snapshot

from tigris_boto3_ext import get_object_from_snapshot

# Read the object as it was at snapshot time — even if it's been

# overwritten or deleted since

obj = get_object_from_snapshot(s3, "my-snapshots", "model.bin", snapshot)

data = obj["Body"].read()

Fork a bucket

Forking creates a copy-on-write clone — instant, no data copying:

from tigris_boto3_ext import create_fork

create_fork(s3, source_bucket="my-snapshots", fork_bucket="experiment-lr-1e-4")

# The fork has all the same objects but writes are independent

s3.put_object(Bucket="experiment-lr-1e-4", Key="model.bin", Body=b"new weights")

# Original bucket is unchanged

Context managers

For scoped operations, use context managers:

from tigris_boto3_ext import TigrisSnapshot, TigrisFork

# Read from a specific snapshot

with TigrisSnapshot(s3, "my-snapshots", snapshot_version=snapshot):

obj = s3.get_object(Bucket="my-snapshots", Key="model.bin")

print(obj["Body"].read())

# Work inside a fork

with TigrisFork(s3, source_bucket="my-snapshots", fork_bucket="test-fork"):

s3.put_object(Bucket="test-fork", Key="results.json", Body=b"{}");

Decorators

You can also use decorators to scope snapshot/fork behavior to a function:

from tigris_boto3_ext import snapshot_enabled, with_snapshot, forked_from

@snapshot_enabled

def backup_workflow(s3_client):

s3_client.put_object(Bucket="backups", Key="data.bak", Body=b"backup data")

@with_snapshot(snapshot_version="v1")

def read_historical(s3_client):

return s3_client.get_object(Bucket="backups", Key="data.bak")

@forked_from(source_bucket="production")

def run_test(s3_client):

# Writes go to the fork, production is untouched

s3_client.put_object(Bucket="test-env", Key="test.txt", Body=b"test")