def upload_files(self, file_paths, file_size_sum=0, dcp_type="data", target_filename=None,
                     use_transfer_acceleration=True, report_progress=False, sync=True):
        """
        A function that takes in a list of file paths and other optional args for parallel file upload
        """
        self._setup_s3_agent_for_file_upload(file_count=len(file_paths),
                                             file_size_sum=file_size_sum,
                                             use_transfer_acceleration=use_transfer_acceleration)
        pool = ThreadPool()
        if report_progress:
            print("\nStarting upload of %s files to upload area %s" % (len(file_paths), self.uuid))
        for file_path in file_paths:
            pool.add_task(self._upload_file, file_path,
                          target_filename=target_filename,
                          use_transfer_acceleration=use_transfer_acceleration,
                          report_progress=report_progress,
                          sync=sync)
        pool.wait_for_completion()
        if report_progress:
            number_of_errors = len(self.s3agent.failed_uploads)
            if number_of_errors == 0:
                print(
                    "Completed upload of %d files to upload area %s\n" %
                    (self.s3agent.file_upload_completed_count, self.uuid))
            else:
                error = "\nThe following files failed:"
                for k, v in self.s3agent.failed_uploads.items():
                    error += "\n%s: [Exception] %s" % (k, v)
                error += "\nPlease retry or contact an hca administrator at data-help@humancellatlas.org for help.\n"
                raise UploadException(error)
A function that takes in a list of file paths and other optional args for parallel file upload