'Upload a file to an S3 object.
Variants have also been injected into S3 client, Bucket and Object.
You don\'t have to use S3Transfer.upload_file() directly.'

def upload_file(self, filename, bucket, key, callback=None, extra_args=None):

    if (not isinstance(filename, six.string_types)):
        raise ValueError('Filename    must    be    a    string')
    subscribers = self._get_subscribers(callback)
    future = self._manager.upload(filename, bucket, key, extra_args, subscribers)
    try:
        future.result()
    except ClientError as e:
        raise S3UploadFailedError(('Failed    to    upload    %s    to    %s:    %s' % (filename, '/'.join([bucket, key]), e)))
