def METHOD_NAME(
    self, objects: List[Tuple[str, str]], remote_engine: "PsycopgEngine"
) -> List[str]:
    """
    Download objects from Minio.
    :param objects: List of (object ID, object URL (object ID it's stored under))
    """
    # By default, take up the whole connection pool with downloaders
    # (less one connection for the main thread that handles metadata)
    worker_threads = self.params.get(
        "threads", int(get_singleton(CONFIG, "SG_ENGINE_POOL")) - 1
    )
    logging.info("Getting download URLs from registry %s...", remote_engine)
    object_ids = [o[0] for o in objects]
    remote_object_ids = [o[1] for o in objects]
    urls = get_object_download_urls(remote_engine, remote_object_ids)
    local_engine = get_engine()
    def _do_download(object_url):
        object_id, url = object_url
        logging.debug("%s -> %s", url[0], object_id)
        try:
            local_engine.run_api_call("download_object", object_id, url)
            local_engine.mount_object(object_id)
        except Exception as e:
            logging.error("Error downloading object %s: %s", object_id, str(e))
            # Delete the object that we just tried to download to make sure we don't have
            # a situation where the file was downloaded but mounting failed (currently
            # we inspect the filesystem to see the list of downloaded objects).
            # TODO figure out a flow for just remounting objects whose files we already have.
            local_engine.delete_objects([object_id])
            return None
        return object_id
    successful: List[str] = []
    try:
        # Temporarily set the engine into autocommit mode. This is because a transaction
        # commit resets session state and makes the download_object engine API call
        # import all of its Python modules again (which takes about 300ms). It also
        # resets the SD and GD dictionaries so it's not possible to cache those modules
        # there either.
        local_engine.autocommit = True
        with ThreadPoolExecutor(max_workers=worker_threads) as tpe:
            # Evaluate the results so that exceptions thrown by the downloader get raised
            pbar = tqdm(
                tpe.map(_do_download, zip(object_ids, urls)),
                total=len(objects),
                unit="obj",
                ascii=SG_CMD_ASCII,
            )
            for object_id in pbar:
                if object_id:
                    successful.append(object_id)
                    pbar.set_postfix(object=object_id[:10] + "...")
        if len(successful) < len(object_ids):
            raise IncompleteObjectDownloadError(reason=None, successful_objects=successful)
        return successful
    except KeyboardInterrupt as e:
        raise IncompleteObjectDownloadError(reason=e, successful_objects=successful)
    finally:
        # Flip the engine back and close all but one pool connection.
        local_engine.autocommit = False
        local_engine.close_others()