def upload_file(self, filename, bucket, key,<EOL>callback=None, extra_args=None):
if not isinstance(filename, six.string_types):<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>subscribers = self._get_subscribers(callback)<EOL>future = self._manager.upload(<EOL>filename, bucket, key, extra_args, subscribers)<EOL>try:<EOL><INDENT>future.result()<EOL><DEDENT>except ClientError as e:<EOL><INDENT>raise S3UploadFailedError(<EOL>"<STR_LIT>" % (<EOL>filename, '<STR_LIT:/>'.join([bucket, key]), e))<EOL><DEDENT>
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.

        .. seealso::
            :py:meth:`S3.Client.upload_file`
            :py:meth:`S3.Client.upload_fileobj`