docs: def parse_arguments(argv):
    """Parse command line arguments.
  
    Args:
      argv: includes the script's name.
  
    Returns:
      argparse object
    """
    parser = argparse.ArgumentParser(
        description='Runs Prediction inside a beam or Dataflow job.')
    # cloud options
    parser.add_argument('--project-id',
                        help='The project to which the job will be submitted.')
    parser.add_argument('--cloud',
                        action='store_true',
                        help='Run preprocessing on the cloud.')
    parser.add_argument('--job-name',
                        default=('mltoolbox-batch-prediction-' +
                                 datetime.datetime.now().strftime('%Y%m%d%H%M%S')),
                        help='Dataflow job name. Must be unique over all jobs.')
    parser.add_argument('--extra-package',
                        default=[],
                        action='append',
                        help=('If using --cloud, also installs these packages on '
                              'each dataflow worker'))
  
    # I/O args
    parser.add_argument('--predict-data',
                        required=True,
                        help='Data to run prediction on')
    parser.add_argument('--trained-model-dir',
                        required=True,
                        help='Usually train_output_path/model.')
    parser.add_argument('--output-dir',
                        required=True,
                        help=('Location to save output.'))
  
    # Other args
    parser.add_argument('--batch-size',
                        required=False,
                        default=1000,
                        type=int,
                        help=('Batch size. Larger values consumes more memrory '
                              'but takes less time to finish.'))
    parser.add_argument('--shard-files',
                        dest='shard_files',
                        action='store_true',
                        help='Shard files')
    parser.add_argument('--no-shard-files',
                        dest='shard_files',
                        action='store_false',
                        help='Don\'t shard files')
    parser.set_defaults(shard_files=True)
  
    parser.add_argument('--output-format',
                        choices=['csv', 'json'],
                        default='csv',
                        help="""
        The output results.
          raw_json: produces a newline file where each line is json. No
              post processing is performed and the output matches what the trained
              model produces.
          csv: produces a csv file without a header row and a header csv file.
              For classification problems, the vector of probabalities for each
              target class is split into individual csv columns.""")
  
    args, _ = parser.parse_known_args(args=argv[1:])
  
    if args.cloud:
      if not args.project_id:
        raise ValueError('--project-id needed with --cloud')
      if not args.trained_model_dir.startswith('gs://'):
        raise ValueError('--trained-model-dir needs to be a GCS path,')
      if not args.output_dir.startswith('gs://'):
        raise ValueError('--output-dir needs to be a GCS path.')
      if not args.predict_data.startswith('gs://'):
        raise ValueError('--predict-data needs to be a GCS path.')
  
    return args