docs: def get_prediction_results(model_dir_or_id, data, headers, img_cols=None,
                             cloud=False, with_source=True, show_image=True):
    """ Predict with a specified model.
  
    It predicts with the model, join source data with prediction results, and formats
    the results so they can be displayed nicely in Datalab.
  
    Args:
      model_dir_or_id: The model directory if cloud is False, or model.version if cloud is True.
      data: Can be a list of dictionaries, a list of csv lines, or a Pandas DataFrame. If it is not
          a list of csv lines, data will be converted to csv lines first, using the orders specified
          by headers and then send to model. For images, it can be image gs urls or in-memory PIL
          images. Images will be converted to base64 encoded strings before prediction.
      headers: the column names of data. It specifies the order of the columns when
          serializing to csv lines for prediction.
      img_cols: The image url columns. If specified, the img_urls will be converted to
          base64 encoded image bytes.
      with_source: Whether return a joined prediction source and prediction results, or prediction
          results only.
      show_image: When displaying prediction source, whether to add a column of image bytes for
          each image url column.
  
    Returns:
      A dataframe of joined prediction source and prediction results, or prediction results only.
    """
  
    if img_cols is None:
      img_cols = []
  
    if isinstance(data, pd.DataFrame):
      data = list(data.T.to_dict().values())
    elif isinstance(data[0], six.string_types):
      data = list(csv.DictReader(data, fieldnames=headers))
  
    images = _download_images(data, img_cols)
    predict_data = _get_predicton_csv_lines(data, headers, images)
  
    if cloud:
      parts = model_dir_or_id.split('.')
      if len(parts) != 2:
        raise ValueError('Invalid model name for cloud prediction. Use "model.version".')
  
      predict_results = ml.ModelVersions(parts[0]).predict(parts[1], predict_data)
    else:
      tf_logging_level = logging.getLogger("tensorflow").level
      logging.getLogger("tensorflow").setLevel(logging.WARNING)
      try:
        predict_results = _tf_predict(model_dir_or_id, predict_data)
      finally:
        logging.getLogger("tensorflow").setLevel(tf_logging_level)
  
    df_r = pd.DataFrame(predict_results)
    if not with_source:
      return df_r
  
    display_data = data
    if show_image:
      display_data = _get_display_data_with_images(data, images)
  
    df_s = pd.DataFrame(display_data)
    df = pd.concat([df_r, df_s], axis=1)
    # Remove duplicate columns. All 'key' columns are duplicate here.
    df = df.loc[:, ~df.columns.duplicated()]
  
    return df