class_docstr: Rate limited PaLM wrapper
  
  This class exposes PaLM's chat, text, and embedding API, but with a rate limit.
  Besides the rate limit, the `chat` and `generate_text` method has the same name and
  behavior as `google.generativeai.chat` and `google.generativeai.generate_text`,
  respectively. The `embed` method is different from
  `google.generativeai.generate_embeddings` since `embed` returns List[float]
  while `google.generativeai.generate_embeddings` returns a dict. And that's why it
  has a different name.
class_docstr_tok: ["Rate","limited","PaLM","wrapper","This","class","exposes","PaLM","'s","chat",",","text",",","and","embedding","API",",","but","with","a","rate","limit",".","Besides","the","rate","limit",",","the","`","chat","`","and","`","generate_text","`","method","has","the","same","name","and","behavior","as","`","google.generativeai.chat","`","and","`","google.generativeai.generate_text","`",",","respectively",".","The","`","embed","`","method","is","different","from","`","google.generativeai.generate_embeddings","`","since","`","embed","`","returns","List","[","float","]","while","`","google.generativeai.generate_embeddings","`","returns","a","dict",".","And","that","'s","why","it","has","a","different","name","."]
code: def __init__(
      self,
      api_key=None,
      api_endpoint=DEFAULT_ENDPOINT,
      chat_model=None,
      text_model=None,
      content_model=None,
      embed_model=None,
      find_models=True,
  ) -> None:
      if api_key is None:
          api_key = os.getenv("PALM_API_KEY")
      if api_key is None:
          raise PaLMNoAPIKeyError()
      google.generativeai.configure(
          api_key=api_key, client_options={"api_endpoint": api_endpoint}
      )
      self.api_endpoint = api_endpoint
      self.chat_model = chat_model
      self.text_model = text_model
      self.content_model = content_model
      self.embed_model = embed_model
  
      # Check whether the specified models are supported
      supported_models = set(
          model.name for model in google.generativeai.list_models()
      )
      for model in (chat_model, text_model, content_model, embed_model):
          if model and model not in supported_models:
              raise PaLMUnsupportedModelError(model, api_endpoint)
  
      # Check whether we need to find available models
      if (not find_models) or (
          chat_model is not None
          and text_model is not None
          and content_model is not None
          and embed_model is not None
      ):
          return
      # Find available models
      for model in google.generativeai.list_models():
          if (
              self.chat_model is None
              and "generateMessage"
              in model.supported_generation_methods
              and "chat" in model.name
          ):
              self.chat_model = model.name
          if (
              self.text_model is None
              and "generateText" in model.supported_generation_methods
          ):
              self.text_model = model.name
          if (
              self.content_model is None
              and "generateContent"
              in model.supported_generation_methods
          ):
              self.content_model = model.name
          if self.embed_model is None and (
              "embedText" in model.supported_generation_methods
              or "embedContent" in model.supported_generation_methods
          ):
              self.embed_model = model.name
  
imports: import os
  import google.generativeai
  from ratelimit import limits, sleep_and_retry
  from typing import List
label_desc: Use image node_id 1 to create a new PaLM object  with example: obj = PaLM(api_key, api_endpoint, chat_model, text_model, content_model, embed_model, find_models)