code: def download_public_s3_files(
      urls, download_dir=None, num_workers=None, overwrite=True
  ):
      """Download files from a public AWS S3 bucket using unsigned URLs.
  
      The `url` argument either accepts:
  
          -   A list of paths to objects in the s3 bucket::
  
                  urls = ["s3://bucket_name/dir1/file1.ext", ...]
  
              When `urls` is a list, then the `download_dir` argument is required
              and all objects will be downloaded into that directory
  
          -   A dictionary mapping the paths of objects to files on disk to store
              each object::
  
                  urls = {
                      "s3://bucket_name/dir1/file1.ext": "/path/to/local/file1.ext",
                      ...
                  }
  
      Args:
          urls: either a list of URLs to objects in an s3 bucket, or a dict
              mapping these URLs to locations on disk. If `urls` is a list, then
              the `download_dir` argument is required
          download_dir (None): the directory to store all downloaded objects.
              This is only used if `urls` is a list
          num_workers (None): a suggested number of threads to use when
              downloading files
          overwrite (True): whether to overwrite existing files
      """
      if not isinstance(urls, dict):
          if download_dir is None:
              raise ValueError(
                  "`download_dir` is required when `urls` is a list"
              )
  
          urls = {url: None for url in urls}
  
      if download_dir:
          etau.ensure_dir(download_dir)
  
      num_workers = fou.recommend_thread_pool_workers(num_workers)
  
      s3_client = boto3.client(
          "s3",
          config=botocore.config.Config(
              signature_version=botocore.UNSIGNED,
              max_pool_connections=max(10, num_workers),
          ),
      )
  
      inputs = _build_inputs(
          urls,
          s3_client,
          download_dir=download_dir,
          overwrite=overwrite,
      )
  
      if not inputs:
          return
  
      if num_workers <= 1:
          _single_thread_download(inputs)
      else:
          _multi_thread_download(inputs, num_workers)
  
file_path: fiftyone/fiftyone/utils/aws.py
imports: import logging
  import multiprocessing.dummy
  import os
  from urllib.parse import urlparse
  import boto3
  import botocore
  import eta.core.utils
  import fiftyone.core.utils
label_desc: Use image node_id 1 for calling a global function with example usage: download_public_s3_files(urls, download_dir, num_workers, overwrite) without return types