This change creates two directories of content, based on who they're relevant to: users and contributors. Files which were in the top-level folder were moved, as well as some within folders in that top-level. This is one change of a multi-step process, so it only deals with renamings in order to make further changes cleaner. Change-Id: I3c9bb7da4f283e2696e7bcea84824c778bbcecfb Partial-Bug: 1416553
		
			
				
	
	
		
			225 lines
		
	
	
		
			8.9 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
			
		
		
	
	
			225 lines
		
	
	
		
			8.9 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
Using the OpenStack Object Store API
 | 
						|
====================================
 | 
						|
 | 
						|
The Object Store API operates on two things: containers and objects.
 | 
						|
 | 
						|
Before working with the ``object_store`` API, you'll need to obtain a
 | 
						|
:class:`~openstack.connection.Connection` object like so.
 | 
						|
 | 
						|
.. literalinclude:: /code/connection.py
 | 
						|
 | 
						|
Working with Containers
 | 
						|
-----------------------
 | 
						|
 | 
						|
Listing Containers
 | 
						|
******************
 | 
						|
 | 
						|
To list existing containers, use the
 | 
						|
:meth:`~openstack.object_store.v1._proxy.Proxy.containers` method. ::
 | 
						|
 | 
						|
    >>> for cont in conn.object_store.containers():
 | 
						|
    ...     print cont
 | 
						|
    ...
 | 
						|
    Container: {u'count': 5, u'bytes': 500, u'name': u'my container'}
 | 
						|
    Container: {u'count': 0, u'bytes': 0, u'name': u'empty container'}
 | 
						|
    Container: {u'count': 100, u'bytes': 1000000, u'name': u'another container'}
 | 
						|
 | 
						|
The ``containers`` method returns a generator which yields
 | 
						|
:class:`~openstack.object_store.v1.container.Container` objects. It handles
 | 
						|
pagination for you, which can be adjusted via the ``limit`` argument.
 | 
						|
By default, the ``containers`` method will yield as many containers as the
 | 
						|
service will return, and it will continue requesting until it receives
 | 
						|
no more. ::
 | 
						|
 | 
						|
    >>> for cont in conn.object_store.containers(limit=500):
 | 
						|
    ...     print(cont)
 | 
						|
    ...
 | 
						|
    <500 Containers>
 | 
						|
    ... another request transparently made to the Object Store service
 | 
						|
    <500 more Containers>
 | 
						|
    ...
 | 
						|
 | 
						|
Creating Containers
 | 
						|
*******************
 | 
						|
 | 
						|
To create a container, use the
 | 
						|
:meth:`~openstack.object_store.v1._proxy.Proxy.create_container` method. ::
 | 
						|
 | 
						|
    >>> cont = conn.object_store.create_container("new container".decode("utf8"))
 | 
						|
    >>> cont
 | 
						|
    Container: {'name': u'new container'}
 | 
						|
 | 
						|
You can also create containers by passing in a
 | 
						|
:class:`~openstack.object_store.v1.container.Container` resource. This is
 | 
						|
helpful if you wanted to create another container which uses the same metadata
 | 
						|
settings that another container has. ::
 | 
						|
 | 
						|
    >>> from copy import copy
 | 
						|
    >>> print cont.name, cont.read_ACL
 | 
						|
    MyContainer .r:mysite.com
 | 
						|
    >>> new_cont = copy(cont)
 | 
						|
    >>> new_cont.name = "copied container"
 | 
						|
    >>> conn.object_store.create_container(new_cont)
 | 
						|
    Container: {u'name': 'copied container', 'x-container-read': '.r:mysite.com'}
 | 
						|
 | 
						|
Working with Container Metadata
 | 
						|
*******************************
 | 
						|
 | 
						|
To get the metadata for a container, use the
 | 
						|
:meth:`~openstack.object_store.v1._proxy.Proxy.get_container_metadata` method.
 | 
						|
This method either takes the name of a container, or a
 | 
						|
:class:`~openstack.object_store.v1.container.Container` object, and it returns
 | 
						|
a `Container` object with all of its metadata attributes set. ::
 | 
						|
 | 
						|
    >>> cont = conn.object_store.get_container_metadata("new container".decode("utf8"))
 | 
						|
    Container: {'content-length': '0', 'x-container-object-count': '0',
 | 
						|
    'name': u'new container', 'accept-ranges': 'bytes',
 | 
						|
    'x-trans-id': 'tx22c5de63466e4c05bb104-0054740c39',
 | 
						|
    'date': 'Tue, 25 Nov 2014 04:57:29 GMT',
 | 
						|
    'x-timestamp': '1416889793.23520', 'x-container-read': '.r:mysite.com',
 | 
						|
    'x-container-bytes-used': '0', 'content-type': 'text/plain; charset=utf-8'}
 | 
						|
 | 
						|
To set the metadata for a container, use the
 | 
						|
:meth:`~openstack.object_store.v1._proxy.Proxy.set_container_metadata` method.
 | 
						|
This method takes a :class:`~openstack.object_store.v1.container.Container`
 | 
						|
object. For example, to grant another user write access to this container,
 | 
						|
you can set the
 | 
						|
:attr:`~openstack.object_store.v1.container.Container.write_ACL` on a
 | 
						|
resource and pass it to `set_container_metadata`. ::
 | 
						|
 | 
						|
    >>> cont.write_ACL = "big_project:another_user"
 | 
						|
    >>> conn.object_store.set_container_metadata(cont)
 | 
						|
    Container: {'content-length': '0', 'x-container-object-count': '0',
 | 
						|
    'name': u'my new container', 'accept-ranges': 'bytes',
 | 
						|
    'x-trans-id': 'txc3ee751f971d41de9e9f4-0054740ec1',
 | 
						|
    'date': 'Tue, 25 Nov 2014 05:08:17 GMT',
 | 
						|
    'x-timestamp': '1416889793.23520', 'x-container-read': '.r:mysite.com',
 | 
						|
    'x-container-bytes-used': '0', 'content-type': 'text/plain; charset=utf-8',
 | 
						|
    'x-container-write': 'big_project:another_user'}
 | 
						|
 | 
						|
Working with Objects
 | 
						|
--------------------
 | 
						|
 | 
						|
Objects are held in containers. From an API standpoint, you work with
 | 
						|
them using similarly named methods, typically with an additional argument
 | 
						|
to specify their container.
 | 
						|
 | 
						|
Listing Objects
 | 
						|
***************
 | 
						|
 | 
						|
To list the objects that exist in a container, use the
 | 
						|
:meth:`~openstack.object_store.v1._proxy.Proxy.objects` method.
 | 
						|
 | 
						|
If you have a :class:`~openstack.object_store.v1.container.Container`
 | 
						|
object, you can pass it to ``objects``. ::
 | 
						|
 | 
						|
    >>> print cont.name
 | 
						|
    pictures
 | 
						|
    >>> for obj in conn.object_store.objects(cont):
 | 
						|
    ...     print obj
 | 
						|
    ...
 | 
						|
    Object: {u'hash': u'0522d4ccdf9956badcb15c4087a0c4cb',
 | 
						|
    u'name': u'pictures/selfie.jpg', u'bytes': 15744,
 | 
						|
    'last-modified': u'2014-10-31T06:33:36.618640',
 | 
						|
    u'last_modified': u'2014-10-31T06:33:36.618640',
 | 
						|
    u'content_type': u'image/jpeg', 'container': u'pictures',
 | 
						|
    'content-type': u'image/jpeg'}
 | 
						|
    ...
 | 
						|
 | 
						|
Similar to the :meth:`~openstack.object_store.v1._proxy.Proxy.containers`
 | 
						|
method, ``objects`` returns a generator which yields
 | 
						|
:class:`~openstack.object_store.v1.obj.Object` objects stored in the
 | 
						|
container. It also handles pagination for you, which you can adjust
 | 
						|
with the ``limit`` parameter, otherwise making each request for the maximum
 | 
						|
that your Object Store will return.
 | 
						|
 | 
						|
If you have the name of a container instead of an object, you can also
 | 
						|
pass that to the ``objects`` method. ::
 | 
						|
 | 
						|
    >>> for obj in conn.object_store.objects("pictures".decode("utf8"),
 | 
						|
                                             limit=100):
 | 
						|
    ...     print obj
 | 
						|
    ...
 | 
						|
    <100 Objects>
 | 
						|
    ... another request transparently made to the Object Store service
 | 
						|
    <100 more Objects>
 | 
						|
 | 
						|
Getting Object Data
 | 
						|
*******************
 | 
						|
 | 
						|
Once you have an :class:`~openstack.object_store.v1.obj.Object`, you get
 | 
						|
the data stored inside of it with the
 | 
						|
:meth:`~openstack.object_store.v1._proxy.Proxy.get_object_data` method. ::
 | 
						|
 | 
						|
    >>> print ob.name
 | 
						|
    message.txt
 | 
						|
    >>> data = conn.object_store.get_object_data(ob)
 | 
						|
    >>> print data
 | 
						|
    Hello, world!
 | 
						|
 | 
						|
Additionally, if you want to save the object to disk, the
 | 
						|
:meth:`~openstack.object_store.v1._proxy.Proxy.save_object` convenience
 | 
						|
method takes an :class:`~openstack.object_store.v1.obj.Object` and a
 | 
						|
``path`` to write the contents to. ::
 | 
						|
 | 
						|
    >>> conn.object_store.save_object(ob, "the_message.txt")
 | 
						|
 | 
						|
Creating Objects
 | 
						|
****************
 | 
						|
 | 
						|
Once you have data you'd like to store in the Object Store service, you use
 | 
						|
the :meth:`~openstack.object_store.v1._proxy.Proxy.create_object` method.
 | 
						|
This method takes the ``data`` to be stored, along with an ``obj`` and
 | 
						|
``container``. The ``obj`` can either be the name of an object or an
 | 
						|
:class:`~openstack.object_store.v1.obj.Object` instance, and ``container``
 | 
						|
can either be the name of a container or an
 | 
						|
:class:`~openstack.object_store.v1.container.Container` instance. ::
 | 
						|
 | 
						|
    >>> hello = conn.object_store.create_object("Hello, world!",
 | 
						|
                                                "helloworld.txt".decode("utf8"),
 | 
						|
                                                "My Container".decode("utf8"))
 | 
						|
    >>> print hello
 | 
						|
    Object: {'content-length': '0', 'container': u'My Container',
 | 
						|
    'name': u'helloworld.txt',
 | 
						|
    'last-modified': 'Tue, 25 Nov 2014 17:39:29 GMT',
 | 
						|
    'etag': '5eb63bbbe01eeed093cb22bb8f5acdc3',
 | 
						|
    'x-trans-id': 'tx3035d41b03334aeaaf3dd-005474bed0',
 | 
						|
    'date': 'Tue, 25 Nov 2014 17:39:28 GMT',
 | 
						|
    'content-type': 'text/html; charset=UTF-8'}
 | 
						|
 | 
						|
If you have an existing object and want to update its data, you can easily
 | 
						|
do that by passing new ``data`` along with existing
 | 
						|
:class:`~openstack.object_store.v1.obj.Object` and
 | 
						|
:class:`~openstack.object_store.v1.container.Container` instances. ::
 | 
						|
 | 
						|
    >>> conn.object_store.create_object("Hola, mundo!", hello, cont)
 | 
						|
 | 
						|
Working with Object Metadata
 | 
						|
****************************
 | 
						|
 | 
						|
Working with metadata on objects is identical to how it's done with
 | 
						|
containers. You use the
 | 
						|
:meth:`~openstack.object_store.v1._proxy.Proxy.get_object_metadata` and
 | 
						|
:meth:`~openstack.object_store.v1._proxy.Proxy.set_object_metadata` methods.
 | 
						|
 | 
						|
The metadata attributes to be set can be found on the
 | 
						|
:class:`~openstack.object_store.v1.obj.Object` object. ::
 | 
						|
 | 
						|
    >>> secret.delete_after = 300
 | 
						|
    >>> secret = conn.object_store.set_object_metadata(secret)
 | 
						|
 | 
						|
We set the :attr:`~openstack.object_store.obj.Object.delete_after`
 | 
						|
value to 500 seconds, causing the object to be deleted in 300 seconds,
 | 
						|
or five minutes. That attribute corresponds to the ``X-Delete-After``
 | 
						|
header value, which you can see is returned when we retreive the updated
 | 
						|
metadata. ::
 | 
						|
 | 
						|
    >>> conn.object_store.get_object_metadata(ob)
 | 
						|
    Object: {'content-length': '11', 'container': u'Secret Container',
 | 
						|
    'name': u'selfdestruct.txt', 'x-delete-after': 300,
 | 
						|
    'accept-ranges': 'bytes', 'last-modified': 'Tue, 25 Nov 2014 17:50:45 GMT',
 | 
						|
    'etag': '5eb63bbbe01eeed093cb22bb8f5acdc3',
 | 
						|
    'x-timestamp': '1416937844.36805',
 | 
						|
    'x-trans-id': 'tx5c3fd94adf7c4e1b8f334-005474c17b',
 | 
						|
    'date': 'Tue, 25 Nov 2014 17:50:51 GMT', 'content-type': 'text/plain'}
 |