'archive( self, trans, history_id, filename=\'\', format=\'tgz\', dry_run=True, **kwd )
* GET /api/histories/{history_id}/contents/archive/{id}
* GET /api/histories/{history_id}/contents/archive/{filename}.{format}
build and return a compressed archive of the selected history contents
:type   filename:  string
:param  filename:  (optional) archive name (defaults to history name)
:type   dry_run:   boolean
:param  dry_run:   (optional) if True, return the archive and file paths only
as json and not an archive file
:returns:   archive file for download
.. note:: this is a volatile endpoint and settings and behavior may change.'

@expose_api_raw
def archive(self, trans, history_id, filename='', format='tgz', dry_run=True, **kwd):

    invalid_filename_char_regex = re.compile('[:<>|\\\\\\/\\?\\*    "]')
    id_name_format = u'{}.{}'
    def name_to_filename(name, max_length=150, replace_with=u'_'):
        return invalid_filename_char_regex.sub(replace_with, name)[0:max_length]
    def build_path_from_parents(parents):
        parent_names = []
        for parent in parents:
            if hasattr(parent, 'hid'):
                name = name_to_filename(parent.name)
                parent_names.append(id_name_format.format(parent.hid, name))
            elif hasattr(parent, 'element_index'):
                name = name_to_filename(parent.element_identifier)
                parent_names.append(id_name_format.format(parent.element_index, name))
        return parent_names
    history = self.history_manager.get_accessible(trans.security.decode_id(history_id), trans.user)
    archive_base_name = (filename or name_to_filename(history.name))
    paths_and_files = []
    def build_archive_files_and_paths(content, *parents):
        archive_path = archive_base_name
        if (not self.hda_manager.is_accessible(content, trans.user)):
            return
        content_container_id = content.hid
        content_name = name_to_filename(content.name)
        if parents:
            if hasattr(parents[0], 'element_index'):
                (parent_dce, parents) = (parents[0], parents[1:])
                content_container_id = parent_dce.element_index
                content_name = name_to_filename(parent_dce.element_identifier)
            archive_path = os.path.join(archive_path, *build_path_from_parents(parents)[::(-1)])
        content_id_and_name = id_name_format.format(content_container_id, content_name)
        archive_path = os.path.join(archive_path, content_id_and_name)
        if self.hda_manager.is_composite(content):
            paths_and_files.append((content.file_name, os.path.join(archive_path, (content.name + '.html'))))
            for extra_file in self.hda_manager.extra_files(content):
                extra_file_basename = os.path.basename(extra_file)
                archive_extra_file_path = os.path.join(archive_path, extra_file_basename)
                paths_and_files.append((extra_file, archive_extra_file_path))
        else:
            if (not archive_path.endswith(('.' + content.extension))):
                archive_path += ('.' + content.extension)
            paths_and_files.append((content.file_name, archive_path))
    filter_params = self.parse_filter_params(kwd)
    filters = self.history_contents_filters.parse_filters(filter_params)
    self.history_contents_manager.map_datasets(history, build_archive_files_and_paths, filters=filters)
    if (dry_run == 'True'):
        trans.response.headers['Content-Type'] = 'application/json'
        return safe_dumps(paths_and_files)
    archive_type_string = 'w|gz'
    archive_ext = 'tgz'
    if self.app.config.upstream_gzip:
        archive_type_string = 'w|'
        archive_ext = 'tar'
    archive = StreamBall(archive_type_string)
    for (file_path, archive_path) in paths_and_files:
        archive.add(file_path, archive_path)
    archive_name = '.'.join([archive_base_name, archive_ext])
    trans.response.set_content_type('application/x-tar')
    trans.response.headers['Content-Disposition'] = 'attachment;    filename="{}"'.format(archive_name)
    archive.wsgi_status = trans.response.wsgi_status()
    archive.wsgi_headeritems = trans.response.wsgi_headeritems()
    return archive.stream
