def download_file(self, bucket, key, filename, extra_args=None,<EOL>expected_size=None):
self._start_if_needed()<EOL>if extra_args is None:<EOL><INDENT>extra_args = {}<EOL><DEDENT>self._validate_all_known_args(extra_args)<EOL>transfer_id = self._transfer_monitor.notify_new_transfer()<EOL>download_file_request = DownloadFileRequest(<EOL>transfer_id=transfer_id, bucket=bucket, key=key,<EOL>filename=filename, extra_args=extra_args,<EOL>expected_size=expected_size,<EOL>)<EOL>logger.debug(<EOL>'<STR_LIT>', download_file_request)<EOL>self._download_request_queue.put(download_file_request)<EOL>call_args = CallArgs(<EOL>bucket=bucket, key=key, filename=filename, extra_args=extra_args,<EOL>expected_size=expected_size)<EOL>future = self._get_transfer_future(transfer_id, call_args)<EOL>return future<EOL>
Downloads the object's contents to a file

        :type bucket: str
        :param bucket: The name of the bucket to download from

        :type key: str
        :param key: The name of the key to download from

        :type filename: str
        :param filename: The name of a file to download to.

        :type extra_args: dict
        :param extra_args: Extra arguments that may be passed to the
            client operation

        :type expected_size: int
        :param expected_size: The expected size in bytes of the download. If
            provided, the downloader will not call HeadObject to determine the
            object's size and use the provided value instead. The size is
            needed to determine whether to do a multipart download.

        :rtype: s3transfer.futures.TransferFuture
        :returns: Transfer future representing the download