'Start a multipart upload operation.
.. note::
Note: After you initiate multipart upload and upload one or more
parts, you must either complete or abort multipart upload in order
to stop getting charged for storage of the uploaded parts. Only
after you either complete or abort multipart upload, Amazon S3
frees up the parts storage and stops charging you for the parts
storage.
:type key_name: string
:param key_name: The name of the key that will ultimately
result from this multipart upload operation.  This will be
exactly as the key appears in the bucket after the upload
process has been completed.
:type headers: dict
:param headers: Additional HTTP headers to send and store with the
resulting key in S3.
:type reduced_redundancy: boolean
:param reduced_redundancy: In multipart uploads, the storage
class is specified when initiating the upload, not when
uploading individual parts.  So if you want the resulting
key to use the reduced redundancy storage class set this
flag when you initiate the upload.
:type metadata: dict
:param metadata: Any metadata that you would like to set on the key
that results from the multipart upload.
:type encrypt_key: bool
:param encrypt_key: If True, the new copy of the object will
be encrypted on the server-side by S3 and will be stored
in an encrypted form while at rest in S3.
:type policy: :class:`boto.s3.acl.CannedACLStrings`
:param policy: A canned ACL policy that will be applied to the
new key (once completed) in S3.'

def initiate_multipart_upload(self, key_name, headers=None, reduced_redundancy=False, metadata=None, encrypt_key=False, policy=None):

    query_args = 'uploads'
    provider = self.connection.provider
    headers = (headers or {})
    if policy:
        headers[provider.acl_header] = policy
    if reduced_redundancy:
        storage_class_header = provider.storage_class_header
        if storage_class_header:
            headers[storage_class_header] = 'REDUCED_REDUNDANCY'
    if encrypt_key:
        headers[provider.server_side_encryption_header] = 'AES256'
    if (metadata is None):
        metadata = {}
    headers = boto.utils.merge_meta(headers, metadata, self.connection.provider)
    response = self.connection.make_request('POST', self.name, key_name, query_args=query_args, headers=headers)
    body = response.read()
    boto.log.debug(body)
    if (response.status == 200):
        resp = MultiPartUpload(self)
        h = handler.XmlHandler(resp, self)
        if (not isinstance(body, bytes)):
            body = body.encode('utf-8')
        xml.sax.parseString(body, h)
        return resp
    else:
        raise self.connection.provider.storage_response_error(response.status, response.reason, body)
