code: def copy(self, source_path, destination_path, threads=DEFAULT_THREADS, start_time=None, end_time=None,
               part_size=DEFAULT_PART_SIZE, **kwargs):
          
  
          # don't allow threads to be less than 3
          threads = 3 if threads < 3 else threads
  
          if self.isdir(source_path):
              return self._copy_dir(source_path, destination_path, threads=threads,
                                    start_time=start_time, end_time=end_time, part_size=part_size, **kwargs)
  
          # If the file isn't a directory just perform a simple copy
          else:
              return self._copy_file(source_path, destination_path, threads=threads, part_size=part_size, **kwargs)
docs: Copy object(s) from one S3 location to another. Works for individual keys or entire directories.
          When files are larger than `part_size`, multipart uploading will be used.
          :param source_path: The `s3://` path of the directory or key to copy from
          :param destination_path: The `s3://` path of the directory or key to copy to
          :param threads: Optional argument to define the number of threads to use when copying (min: 3 threads)
          :param start_time: Optional argument to copy files with modified dates after start_time
          :param end_time: Optional argument to copy files with modified dates before end_time
          :param part_size: Part size in bytes
          :param kwargs: Keyword arguments are passed to the boto function `copy` as ExtraArgs
          :returns tuple (number_of_files_copied, total_size_copied_in_bytes)