docstr: If there is a prompt template, we use it. Otherwise, we use the concatenation of `context_column` (optional) and `question_column` to ask for a completion.
docstr_tok: ["If","there","is","a","prompt","template",",","we","use","it",".","Otherwise",",","we","use","the","concatenation","of","`","context_column","`","(","optional",")","and","`","question_column","`","to","ask","for","a","completion","."]
code: def predict(self, df, args=None):
      """
      If there is a prompt template, we use it. Otherwise, we use the concatenation of `context_column` (optional) and `question_column` to ask for a completion.
      """  # noqa
      # TODO: support for edits, embeddings and moderation
  
      pred_args = args["predict_params"] if args else {}
      args_model = PalmHandlerArgs(
          **self.model_storage.json_get("args")
      )
      df = df.reset_index(drop=True)
  
      if pred_args.get("mode"):
          if pred_args["mode"] in self.supported_modes:
              args_model.mode = pred_args["mode"]
          else:
              raise Exception(
                  f"Invalid operation mode. Please use one of {self.supported_modes}."
              )  # noqa
  
      if pred_args.get("prompt_template", False):
          base_template = pred_args[
              "prompt_template"
          ]  # override with predict-time template if available
      elif args_model.prompt_template:
          base_template = args_model.prompt_template
      else:
          base_template = None
  
      # Embedding Mode
      if args_model.mode == "embedding":
          api_args = {
              "model": pred_args.get(
                  "model_name", "models/embedding-gecko-001"
              )
          }
          model_name = "models/embedding-gecko-001"
          if args_model.question_column:
              prompts = list(
                  df[args_model.question_column].apply(lambda x: str(x))
              )
              empty_prompt_ids = np.where(
                  df[[args_model.question_column]]
                  .isna()
                  .all(axis=1)
                  .values
              )[0]
          else:
              raise Exception("Embedding mode needs a question_column")
  
      # Chat or normal completion mode
      else:
          if (
              args_model.question_column
              and args_model.question_column not in df.columns
          ):
              raise Exception(
                  f"This model expects a question to answer in the '{args_model.question_column}' column."
              )
  
          if (
              args_model.context_column
              and args_model.context_column not in df.columns
          ):
              raise Exception(
                  f"This model expects context in the '{args_model.context_column}' column."
              )
  
          # api argument validation
          model_name = args_model.model_name
          api_args = {
              "max_output_tokens": pred_args.get(
                  "max_output_tokens",
                  args_model.max_output_tokens,
              ),
              "temperature": min(
                  1.0,
                  max(
                      0.0,
                      pred_args.get(
                          "temperature", args_model.temperature
                      ),
                  ),
              ),
              "top_p": pred_args.get("top_p", None),
              "candidate_count": pred_args.get("candidate_count", None),
              "stop_sequences": pred_args.get("stop_sequences", None),
          }
  
          if (
              args_model.mode != "default"
              and model_name not in self.chat_completion_models
          ):
              raise Exception(
                  f"Conversational modes are only available for the following models: {', '.join(self.chat_completion_models)}"
              )  # noqa
  
          if args_model.prompt_template:
              prompts, empty_prompt_ids = get_completed_prompts(
                  base_template, df
              )
              if len(prompts) == 0:
                  raise Exception("No prompts found")
  
          elif args_model.context_column:
              empty_prompt_ids = np.where(
                  df[
                      [
                          args_model.context_column,
                          args_model.question_column,
                      ]
                  ]
                  .isna()
                  .all(axis=1)
                  .values
              )[0]
              contexts = list(
                  df[args_model.context_column].apply(lambda x: str(x))
              )
              questions = list(
                  df[args_model.question_column].apply(lambda x: str(x))
              )
              prompts = [
                  f"Context: {c}\nQuestion: {q}\nAnswer: "
                  for c, q in zip(contexts, questions)
              ]
              api_args["context"] = "".join(contexts)
  
          elif args_model.prompt:
              empty_prompt_ids = []
              prompts = list(df[args_model.user_column])
              if len(prompts) == 0:
                  raise Exception("No prompts found")
          else:
              empty_prompt_ids = np.where(
                  df[[args_model.question_column]]
                  .isna()
                  .all(axis=1)
                  .values
              )[0]
              prompts = list(
                  df[args_model.question_column].apply(lambda x: str(x))
              )
  
      # remove prompts without signal from completion queue
      prompts = [
          j for i, j in enumerate(prompts) if i not in empty_prompt_ids
      ]
  
      api_key = get_api_key(
          "palm", args_model.dict(), self.engine_storage
      )
      api_args = {
          k: v for k, v in api_args.items() if v is not None
      }  # filter out non-specified api args
      completion = self._completion(
          model_name, prompts, api_key, api_args, args_model, df
      )
  
      # add null completion for empty prompts
      for i in sorted(empty_prompt_ids):
          completion.insert(i, None)
  
      pred_df = pd.DataFrame(completion, columns=[args_model.target])
  
      return pred_df
  
file_path: mindsdb/mindsdb/integrations/handlers/palm_handler/palm_handler.py
imports: import textwrap
  from pydantic import BaseModel, Extra
  import google.generativeai
  import numpy
  import pandas
  from mindsdb.utilities.hooks import before_palm_query, after_palm_query
  from mindsdb.utilities import log
  from mindsdb.integrations.libs.base import BaseMLEngine
  from mindsdb.integrations.utilities.handler_utils import get_api_key
  from mindsdb.integrations.libs.llm_utils import get_completed_prompts
label_desc: Use image node_id 4 for calling the PalmHandler obj's underlying member method code with example usage: obj.predict(df, args) and returns: pred_df