class_docstr: Class which encapsulate logit of the worker.
  
  Main entry point of this class is EvaluationWorker.run_work method which
  performs cleanup of temporary directories, then runs
  EvaluationWorker.run_attacks and EvaluationWorker.run_defenses
class_docstr_tok: ["Class","which","encapsulate","logit","of","the","worker",".","Main","entry","point","of","this","class","is","EvaluationWorker.run_work","method","which","performs","cleanup","of","temporary","directories",",","then","runs","EvaluationWorker.run_attacks","and","EvaluationWorker.run_defenses"]
docstr: Runs one attack work.
  
  Args:
    work_id: ID of the piece of work to run
  
  Returns:
    elapsed_time_sec, submission_id - elapsed time and id of the submission
  
  Raises:
    WorkerError: if error occurred during execution.
docstr_tok: ["Runs","one","attack","work",".","Args",":","work_id",":","ID","of","the","piece","of","work","to","run","Returns",":","elapsed_time_sec",",","submission_id","-","elapsed","time","and","id","of","the","submission","Raises",":","WorkerError",":","if","error","occurred","during","execution","."]
code: def run_attack_work(self, work_id):
      """Runs one attack work.
  
      Args:
        work_id: ID of the piece of work to run
  
      Returns:
        elapsed_time_sec, submission_id - elapsed time and id of the submission
  
      Raises:
        WorkerError: if error occurred during execution.
      """
      adv_batch_id = self.attack_work.work[work_id][
          "output_adversarial_batch_id"
      ]
      adv_batch = self.adv_batches[adv_batch_id]
      dataset_batch_id = adv_batch["dataset_batch_id"]
      submission_id = adv_batch["submission_id"]
      epsilon = self.dataset_batches[dataset_batch_id]["epsilon"]
      logging.info(
          "Attack work piece: "
          'dataset_batch_id="%s" submission_id="%s" '
          "epsilon=%d",
          dataset_batch_id,
          submission_id,
          epsilon,
      )
      if submission_id in self.blacklisted_submissions:
          raise WorkerError("Blacklisted submission")
      # get attack
      attack = AttackSubmission(
          submission_id, self.submissions, self.storage_bucket
      )
      attack.download()
      # prepare input
      input_dir = os.path.join(LOCAL_DATASET_DIR, dataset_batch_id)
      if attack.type == TYPE_TARGETED:
          # prepare file with target classes
          target_class_filename = os.path.join(
              input_dir, "target_class.csv"
          )
          self.dataset_meta.save_target_classes_for_batch(
              target_class_filename,
              self.dataset_batches,
              dataset_batch_id,
          )
      # prepare output directory
      if os.path.exists(LOCAL_OUTPUT_DIR):
          sudo_remove_dirtree(LOCAL_OUTPUT_DIR)
      os.mkdir(LOCAL_OUTPUT_DIR)
      if os.path.exists(LOCAL_PROCESSED_OUTPUT_DIR):
          shutil.rmtree(LOCAL_PROCESSED_OUTPUT_DIR)
      os.mkdir(LOCAL_PROCESSED_OUTPUT_DIR)
      if os.path.exists(LOCAL_ZIPPED_OUTPUT_DIR):
          shutil.rmtree(LOCAL_ZIPPED_OUTPUT_DIR)
      os.mkdir(LOCAL_ZIPPED_OUTPUT_DIR)
      # run attack
      elapsed_time_sec = attack.run(
          input_dir, LOCAL_OUTPUT_DIR, epsilon
      )
      if attack.type == TYPE_TARGETED:
          # remove target class file
          os.remove(target_class_filename)
      # enforce epsilon and compute hashes
      image_hashes = eval_lib.enforce_epsilon_and_compute_hash(
          input_dir,
          LOCAL_OUTPUT_DIR,
          LOCAL_PROCESSED_OUTPUT_DIR,
          epsilon,
      )
      if not image_hashes:
          logging.warning("No images saved by the attack.")
          return elapsed_time_sec, submission_id
      # write images back to datastore
      # rename images and add information to adversarial batch
      for clean_image_id, hash_val in iteritems(image_hashes):
          # we will use concatenation of batch_id and image_id
          # as adversarial image id and as a filename of adversarial images
          adv_img_id = adv_batch_id + "_" + clean_image_id
          # rename the image
          os.rename(
              os.path.join(
                  LOCAL_PROCESSED_OUTPUT_DIR, clean_image_id + ".png"
              ),
              os.path.join(
                  LOCAL_PROCESSED_OUTPUT_DIR, adv_img_id + ".png"
              ),
          )
          # populate values which will be written to datastore
          image_path = (
              "{0}/adversarial_images/{1}/{1}.zip/{2}.png".format(
                  self.round_name, adv_batch_id, adv_img_id
              )
          )
          # u'' + foo is a a python 2/3 compatible way of casting foo to unicode
          adv_batch["images"][adv_img_id] = {
              "clean_image_id": "" + str(clean_image_id),
              "image_path": "" + str(image_path),
              "image_hash": "" + str(hash_val),
          }
      # archive all images and copy to storage
      zipped_images_filename = os.path.join(
          LOCAL_ZIPPED_OUTPUT_DIR, adv_batch_id + ".zip"
      )
      try:
          logging.debug(
              "Compressing adversarial images to %s",
              zipped_images_filename,
          )
          shell_call(
              [
                  "zip",
                  "-j",
                  "-r",
                  zipped_images_filename,
                  LOCAL_PROCESSED_OUTPUT_DIR,
              ]
          )
      except subprocess.CalledProcessError as e:
          raise WorkerError(
              "Can" "t make archive from adversarial iamges", e
          )
      # upload archive to storage
      dst_filename = "{0}/adversarial_images/{1}/{1}.zip".format(
          self.round_name, adv_batch_id
      )
      logging.debug(
          "Copying archive with adversarial images to %s", dst_filename
      )
      self.storage_client.new_blob(dst_filename).upload_from_filename(
          zipped_images_filename
      )
      # writing adv batch to datastore
      logging.debug("Writing adversarial batch to datastore")
      self.adv_batches.write_single_batch_images_to_datastore(
          adv_batch_id
      )
      return elapsed_time_sec, submission_id
  
imports: from __future__ import absolute_import
  from __future__ import division
  from __future__ import print_function
  from builtins import int
  import argparse
  import json
  import logging
  import os
  import random
  import shutil
  import subprocess
  import time
  import uuid
  from six import iteritems
  import eval_lib
  from cleverhans.utils import shell_call
label_desc: Use image node_id 4 for calling the EvaluationWorker obj's underlying member method code with example usage: obj.run_attack_work(work_id) and returns: elapsed_time_sec,  submission_id, elapsed_time_sec,  submission_id