code: def download(self, url, listener=None, path_or_fd=None, chunk_size_bytes=None, timeout_secs=None):
      
      @contextmanager
      def download_fp(_path_or_fd):
        if _path_or_fd and not isinstance(_path_or_fd, six.string_types):
          yield _path_or_fd, _path_or_fd.name
        else:
          if not _path_or_fd:
            fd, _path_or_fd = tempfile.mkstemp()
            os.close(fd)
          with safe_open(_path_or_fd, 'wb') as fp:
            yield fp, _path_or_fd
  
      with download_fp(path_or_fd) as (fp, path):
        listener = self.DownloadListener(fp).wrap(listener)
        self.fetch(url, listener, chunk_size_bytes=chunk_size_bytes, timeout_secs=timeout_secs)
        return path
docs: Downloads data from the given URL.
  
      By default data is downloaded to a temporary file.
  
      :param string url: the url to GET data from
      :param listener: an optional listener to notify of all download lifecycle events
      :param path_or_fd: an optional file path or open file descriptor to write data to
      :param chunk_size_bytes: the chunk size to use for buffering data
      :param timeout_secs: the maximum time to wait for data to be available
      :returns: the path to the file data was downloaded to.
      :raises: Fetcher.Error if there was a problem downloading all data from the given url.