Search code examples
pythonopenstackopenstack-swift

Python-swiftclient: what is the general usage procedure?


The project I am currently working on requires me to upload and download files to and from swift object storage on an Openstack cloud instance. I have all of the API information required to login to the Openstack instance, but I can't figure out how to use the swiftclient from inside python.

I am specifically trying to use the swiftclient from inside python, not the swift command line interface. I need to be able to respond to exceptions that occur during swift operations.

My current attempt at connecting and posting a container looks like this:

try:
    opts = dict(tenant_id=<tenant id value>, region_name=<region name>)
    swift_conn = swiftclient.client.Connection(authurl=<auth url>, user=<username>, key=<password>, tenant_name=<tenant name>, os_options=opts)
    swift_conn.post_container(cont)
    swift_conn.close()
except swiftclient.exceptions.ClientException:
    print(traceback.format_exc())

This fails because the post_container method requires at least one header value. I haven't been able to find out what constitutes a valid header for a swift request.

More importantly, I'm not certain this is even the correct way to go about executing a swift operation. I have read through the documentation (http://docs.openstack.org/developer/python-swiftclient/swiftclient.html#module-swiftclient.exceptions) and the source code (https://github.com/openstack/python-swiftclient/blob/master/swiftclient/client.py) but have found both to be somewhat obtuse. While there is some direction for what methods there are and what arguments they require, there is no clear order of operations for executing a generic swift operation.

If anyone could provide some advice or guidance on the general process for this, that would be greatly appreciated. I can likely extrude the solution to a post_container request to solve my own problems with the rest of the operations.


Solution

  • I have found the answer to my own question through a lot of trial and error. The main trap that I fell into was not providing the auth_version parameter to the Connection object. If the auth_version parameter is not provided, it defaults to 1.0, and the get_auth_1_0 method that is called rebuilds the url wrong and fails.

    A general put_object operation looks like this, for anyone looking to use the python-swiftclient and running across this question:

        swift_conn = swiftclient.client.Connection(authurl='<url>', user='<user>', key='<password>', tenant_name='<tenant name>', auth_version='2.0', os_options={'tenant_id': '<tenant id>', 'region_name': '<region name>'})
        swift_conn.put_object(<container name>, <object name>, <data>)
        swift_conn.close()
    

    This code assumes you have the information required from your Openstack instance and that you are using a specific region.

    A general get_object operation looks like this:

        swift_conn = swiftclient.client.Connection(authurl='<url>', user='<user>', key='<password>', tenant_name='<tenant name>', auth_version='2.0', os_options={'tenant_id': '<tenant id>', 'region_name': '<region name>'})
        response, object_body = swift_conn.get_object(<container name>, <object_name>)
        swift_conn.close()
        f = open(<filename>, 'wb')
        f.write(object_body)
        f.close()
    

    This code gets an object and saves its contents to a file.

    Hopefully someone in the same position I was in finds this useful.