OpenStack Object Storage API Client Library
The Connection class provides a high-level interface to Swift with automatic authentication, connection pooling, retry logic, and convenient wrapper methods for all Swift operations.
Create a connection with comprehensive authentication options, retry configuration, and SSL settings.
class Connection:
def __init__(
self,
authurl=None,
user=None,
key=None,
retries=5,
preauthurl=None,
preauthtoken=None,
snet=False,
starting_backoff=1,
max_backoff=64,
tenant_name=None,
os_options=None,
auth_version="1",
cacert=None,
insecure=False,
cert=None,
cert_key=None,
ssl_compression=True,
retry_on_ratelimit=True,
timeout=None,
session=None,
force_auth_retry=False
):
"""
Initialize Swift connection with authentication and configuration options.
Parameters:
- authurl: str, authentication URL
- user: str, username to authenticate as
- key: str, key/password to authenticate with
- retries: int, number of times to retry requests before failing (default 5)
- preauthurl: str, storage URL if already authenticated
- preauthtoken: str, authentication token if already authenticated
- snet: bool, use SERVICENET internal network (default False)
- starting_backoff: int, initial delay between retries in seconds (default 1)
- max_backoff: int, maximum delay between retries in seconds (default 64)
- tenant_name: str, tenant/account name for auth 2.0+ systems
- os_options: dict, OpenStack options (tenant_id, auth_token, service_type, etc.)
- auth_version: str, OpenStack auth version ('1', '2.0', '3', default '1')
- cacert: str, CA bundle file for TLS server certificate verification
- insecure: bool, allow access without checking SSL certs (default False)
- cert: str, client certificate file for SSL client certificate authentication
- cert_key: str, client certificate private key file
- ssl_compression: bool, enable SSL compression (default True)
- retry_on_ratelimit: bool, retry ratelimited connections after backoff (default True)
- timeout: float, socket read timeout passed to requests library
- session: keystoneauth1.session.Session object for authentication
- force_auth_retry: bool, reset auth info on unexpected errors (default False)
"""# Basic v1 authentication
conn = Connection(
authurl='http://swift.example.com/auth/v1.0',
user='tenant:username',
key='password'
)
# Keystone v3 authentication
conn = Connection(
authurl='https://identity.example.com:5000/v3',
user='myuser',
key='mypassword',
auth_version='3',
os_options={
'project_name': 'myproject',
'user_domain_name': 'mydomain',
'project_domain_name': 'mydomain',
}
)
# Pre-authenticated connection
conn = Connection(
preauthurl='https://swift.example.com/v1/AUTH_account',
preauthtoken='existing_auth_token'
)
# SSL configuration
conn = Connection(
authurl='https://identity.example.com:5000/v3',
user='myuser',
key='mypassword',
auth_version='3',
cacert='/path/to/ca-bundle.crt',
cert='/path/to/client.crt',
cert_key='/path/to/client.key',
insecure=False
)Retrieve account metadata and container listings with optional filtering and pagination.
def head_account(self, headers=None):
"""
Get account metadata.
Parameters:
- headers: dict, additional headers to include in request
Returns:
dict: account metadata headers (all lowercase keys)
"""
def get_account(
self,
marker=None,
limit=None,
prefix=None,
end_marker=None,
full_listing=False,
headers=None,
delimiter=None
):
"""
Get account container listing.
Parameters:
- marker: str, start listing after this container name
- limit: int, maximum number of containers to return
- prefix: str, only list containers beginning with this prefix
- end_marker: str, stop listing before this container name
- full_listing: bool, return complete listing (may require multiple requests)
- headers: dict, additional headers to include in request
- delimiter: str, delimiter for hierarchical container names
Returns:
tuple: (response_headers dict, containers list)
"""
def post_account(self, headers, response_dict=None, query_string=None, data=None):
"""
Update account metadata.
Parameters:
- headers: dict, headers to set as account metadata
- response_dict: dict, optional dict to store response info
- query_string: str, optional query string to append to request
- data: bytes, optional data to include in request body
Returns:
tuple: (response_headers dict, response_body bytes)
"""Complete container management including creation, metadata operations, object listings, and deletion.
def head_container(self, container, headers=None):
"""
Get container metadata.
Parameters:
- container: str, container name
- headers: dict, additional headers to include in request
Returns:
dict: container metadata headers (all lowercase keys)
"""
def get_container(
self,
container,
marker=None,
limit=None,
prefix=None,
delimiter=None,
end_marker=None,
version_marker=None,
path=None,
full_listing=False,
headers=None,
query_string=None
):
"""
Get container object listing.
Parameters:
- container: str, container name to list objects from
- marker: str, start listing after this object name
- limit: int, maximum number of objects to return
- prefix: str, only list objects beginning with this prefix
- delimiter: str, delimiter for hierarchical object names
- end_marker: str, stop listing before this object name
- version_marker: str, version marker for versioned objects
- path: str, path query (equivalent to delimiter='/' and prefix=path/)
- full_listing: bool, return complete listing (may require multiple requests)
- headers: dict, additional headers to include in request
- query_string: str, optional query string to append to request
Returns:
tuple: (response_headers dict, objects list)
"""
def put_container(self, container, headers=None, response_dict=None, query_string=None):
"""
Create container.
Parameters:
- container: str, container name to create
- headers: dict, additional headers to set on container
- response_dict: dict, optional dict to store response info
- query_string: str, optional query string to append to request
"""
def post_container(self, container, headers, response_dict=None):
"""
Update container metadata.
Parameters:
- container: str, container name to update
- headers: dict, headers to set as container metadata
- response_dict: dict, optional dict to store response info
"""
def delete_container(self, container, response_dict=None, query_string=None, headers={}):
"""
Delete container.
Parameters:
- container: str, container name to delete
- response_dict: dict, optional dict to store response info
- query_string: str, optional query string to append to request
- headers: dict, additional headers to include in request
"""Full object lifecycle management with support for large objects, streaming, metadata, and efficient transfers.
def head_object(self, container, obj, headers=None, query_string=None):
"""
Get object metadata.
Parameters:
- container: str, container name containing the object
- obj: str, object name to get metadata for
- headers: dict, additional headers to include in request
- query_string: str, optional query string to append to request
Returns:
dict: object metadata headers (all lowercase keys)
"""
def get_object(
self,
container,
obj,
resp_chunk_size=None,
query_string=None,
response_dict=None,
headers=None
):
"""
Download object.
Parameters:
- container: str, container name containing the object
- obj: str, object name to download
- resp_chunk_size: int, chunk size for reading response (enables streaming)
- query_string: str, optional query string to append to request
- response_dict: dict, optional dict to store response info
- headers: dict, additional headers to include in request
Returns:
tuple: (response_headers dict, object_content bytes or iterable)
"""
def put_object(
self,
container,
obj,
contents,
content_length=None,
etag=None,
chunk_size=None,
content_type=None,
headers=None,
query_string=None,
response_dict=None
):
"""
Upload object.
Parameters:
- container: str, container name to upload object to
- obj: str, object name to create/update
- contents: str/bytes/file-like/iterable, object content to upload
- content_length: int, content length (computed automatically if None)
- etag: str, expected MD5 hash of content
- chunk_size: int, chunk size for reading file-like contents (default 65536)
- content_type: str, MIME type of content
- headers: dict, additional headers to set on object
- query_string: str, optional query string to append to request
- response_dict: dict, optional dict to store response info
Returns:
str: MD5 hash (ETag) of uploaded content
"""
def post_object(self, container, obj, headers, response_dict=None):
"""
Update object metadata.
Parameters:
- container: str, container name containing the object
- obj: str, object name to update
- headers: dict, headers to set as object metadata
- response_dict: dict, optional dict to store response info
"""
def copy_object(
self,
container,
obj,
destination=None,
headers=None,
fresh_metadata=None,
response_dict=None
):
"""
Copy object.
Parameters:
- container: str, source container name
- obj: str, source object name
- destination: str, destination in format "/container/object" (None for same location)
- headers: dict, additional headers for copy request
- fresh_metadata: bool, omit existing metadata (None/False preserves metadata)
- response_dict: dict, optional dict to store response info
"""
def delete_object(
self,
container,
obj,
query_string=None,
response_dict=None,
headers=None
):
"""
Delete object.
Parameters:
- container: str, container name containing the object
- obj: str, object name to delete
- query_string: str, optional query string to append to request
- response_dict: dict, optional dict to store response info
- headers: dict, additional headers to include in request
"""def close(self):
"""
Close the connection and clean up resources.
"""
def get_capabilities(self, url=None):
"""
Get cluster capability information.
Parameters:
- url: str, optional URL to query capabilities from
Returns:
dict: cluster capabilities and configuration
"""from swiftclient import Connection
conn = Connection(
authurl='https://identity.example.com:5000/v3',
user='myuser',
key='mypassword',
auth_version='3',
os_options={'project_name': 'myproject'}
)
# Account operations
account_headers = conn.head_account()
print(f"Account has {account_headers['x-account-container-count']} containers")
headers, containers = conn.get_account()
for container in containers:
print(f"Container: {container['name']}, Objects: {container['count']}")
# Container operations
conn.put_container('documents')
conn.put_container('images', headers={'X-Container-Read': '.r:*'})
headers, objects = conn.get_container('documents')
for obj in objects:
print(f"Object: {obj['name']}, Size: {obj['bytes']}")
# Object operations
conn.put_object('documents', 'readme.txt', 'Hello, World!')
headers, content = conn.get_object('documents', 'readme.txt')
print(content.decode('utf-8'))
# Set object metadata
conn.post_object('documents', 'readme.txt', {'X-Object-Meta-Author': 'John Doe'})
# Copy object
conn.copy_object('documents', 'readme.txt', '/documents/readme-copy.txt')
# Cleanup
conn.delete_object('documents', 'readme.txt')
conn.delete_object('documents', 'readme-copy.txt')
conn.delete_container('documents')
conn.close()import io
# Upload large file with streaming
large_data = io.BytesIO(b'x' * 10000000) # 10MB of data
etag = conn.put_object(
'documents',
'large-file.dat',
large_data,
content_length=10000000,
chunk_size=65536
)
print(f"Uploaded with ETag: {etag}")
# Download with streaming
headers, content = conn.get_object('documents', 'large-file.dat', resp_chunk_size=65536)
total_bytes = 0
for chunk in content:
total_bytes += len(chunk)
print(f"Downloaded {total_bytes} bytes", end='\r')
print(f"\nTotal downloaded: {total_bytes} bytes")Install with Tessl CLI
npx tessl i tessl/pypi-python-swiftclient