class_docstr: A wrapper class for openai client.
docstr: Make a completion for a given config using openai's clients.
  Besides the kwargs allowed in openai's client, we allow the following additional kwargs.
  The config in each client will be overridden by the config.
  
  Args:
      - context (Dict | None): The context to instantiate the prompt or messages. Default to None.
          It needs to contain keys that are used by the prompt template or the filter function.
          E.g., `prompt="Complete the following sentence: {prefix}, context={"prefix": "Today I feel"}`.
          The actual prompt will be:
          "Complete the following sentence: Today I feel".
          More examples can be found at [templating](/docs/Use-Cases/enhanced_inference#templating).
      - `cache_seed` (int | None) for the cache. Default to 41.
          An integer cache_seed is useful when implementing "controlled randomness" for the completion.
          None for no caching.
      - filter_func (Callable | None): A function that takes in the context and the response
          and returns a boolean to indicate whether the response is valid. E.g.,
  
  ```python
  def yes_or_no_filter(context, response):
      return context.get("yes_or_no_choice", False) is False or any(
          text in ["Yes.", "No."] for text in client.extract_text_or_completion_object(response)
      )
  ```
  
      - allow_format_str_template (bool | None): Whether to allow format string template in the config. Default to false.
      - api_version (str | None): The api version. Default to None. E.g., "2023-08-01-preview".
docstr_tok: ["Make","a","completion","for","a","given","config","using","openai","'s","clients",".","Besides","the","kwargs","allowed","in","openai","'s","client",",","we","allow","the","following","additional","kwargs",".","The","config","in","each","client","will","be","overridden","by","the","config",".","Args",":","-","context","(","Dict","|","None",")",":","The","context","to","instantiate","the","prompt","or","messages",".","Default","to","None",".","It","needs","to","contain","keys","that","are","used","by","the","prompt","template","or","the","filter","function",".","E.g.",",","`","prompt=","''","Complete","the","following","sentence",":","{","prefix","}",",","context=","{","``","prefix","''",":","``","Today","I","feel","''","}","`",".","The","actual","prompt","will","be",":","``","Complete","the","following","sentence",":","Today","I","feel","''",".","More","examples","can","be","found","at","[","templating","]","(","\/docs\/Use-Cases\/enhanced_inference","#","templating",")",".","-","`","cache_seed","`","(","int","|","None",")","for","the","cache",".","Default","to","41",".","An","integer","cache_seed","is","useful","when","implementing","``","controlled","randomness","''","for","the","completion",".","None","for","no","caching",".","-","filter_func","(","Callable","|","None",")",":","A","function","that","takes","in","the","context","and","the","response","and","returns","a","boolean","to","indicate","whether","the","response","is","valid",".","E.g.",",","``","`","python","def","yes_or_no_filter","(","context",",","response",")",":","return","context.get","(","``","yes_or_no_choice","''",",","False",")","is","False","or","any","(","text","in","[","``","Yes",".","``",",","``","No",".","''","]","for","text","in","client.extract_text_or_completion_object","(","response",")",")","``","`","-","allow_format_str_template","(","bool","|","None",")",":","Whether","to","allow","format","string","template","in","the","config",".","Default","to","false",".","-","api_version","(","str","|","None",")",":","The","api","version",".","Default","to","None",".","E.g.",",","``","2023-08-01-preview","''","."]
code: def create(self, **config: Any) -> ChatCompletion:
      """Make a completion for a given config using openai's clients.
      Besides the kwargs allowed in openai's client, we allow the following additional kwargs.
      The config in each client will be overridden by the config.
  
      Args:
          - context (Dict | None): The context to instantiate the prompt or messages. Default to None.
              It needs to contain keys that are used by the prompt template or the filter function.
              E.g., `prompt="Complete the following sentence: {prefix}, context={"prefix": "Today I feel"}`.
              The actual prompt will be:
              "Complete the following sentence: Today I feel".
              More examples can be found at [templating](/docs/Use-Cases/enhanced_inference#templating).
          - `cache_seed` (int | None) for the cache. Default to 41.
              An integer cache_seed is useful when implementing "controlled randomness" for the completion.
              None for no caching.
          - filter_func (Callable | None): A function that takes in the context and the response
              and returns a boolean to indicate whether the response is valid. E.g.,
  
      ```python
      def yes_or_no_filter(context, response):
          return context.get("yes_or_no_choice", False) is False or any(
              text in ["Yes.", "No."] for text in client.extract_text_or_completion_object(response)
          )
      ```
  
          - allow_format_str_template (bool | None): Whether to allow format string template in the config. Default to false.
          - api_version (str | None): The api version. Default to None. E.g., "2023-08-01-preview".
      """
      if ERROR:
          raise ERROR
      last = len(self._clients) - 1
      for i, client in enumerate(self._clients):
          # merge the input config with the i-th config in the config list
          full_config = {**config, **self._config_list[i]}
          # separate the config into create_config and extra_kwargs
          create_config, extra_kwargs = self._separate_create_config(
              full_config
          )
          api_type = extra_kwargs.get("api_type")
          if (
              api_type
              and api_type.startswith("azure")
              and "model" in create_config
          ):
              create_config["model"] = create_config["model"].replace(
                  ".", ""
              )
          # construct the create params
          params = self._construct_create_params(
              create_config, extra_kwargs
          )
          # get the cache_seed, filter_func and context
          cache_seed = extra_kwargs.get("cache_seed", 41)
          filter_func = extra_kwargs.get("filter_func")
          context = extra_kwargs.get("context")
  
          # Try to load the response from cache
          if cache_seed is not None:
              with diskcache.Cache(
                  f"{self.cache_path_root}/{cache_seed}"
              ) as cache:
                  # Try to get the response from cache
                  key = get_key(params)
                  response: ChatCompletion = cache.get(key, None)
  
                  if response is not None:
                      try:
                          response.cost  # type: ignore [attr-defined]
                      except AttributeError:
                          # update attribute if cost is not calculated
                          response.cost = self.cost(response)
                          cache.set(key, response)
                      self._update_usage_summary(
                          response, use_cache=True
                      )
                      # check the filter
                      pass_filter = filter_func is None or filter_func(
                          context=context, response=response
                      )
                      if pass_filter or i == last:
                          # Return the response if it passes the filter or it is the last client
                          response.config_id = i
                          response.pass_filter = pass_filter
                          return response
                      continue  # filter is not passed; try the next config
          try:
              response = self._completions_create(client, params)
          except APIError as err:
              error_code = getattr(err, "code", None)
              if error_code == "content_filter":
                  # raise the error for content_filter
                  raise
              logger.debug(f"config {i} failed", exc_info=True)
              if i == last:
                  raise
          else:
              # add cost calculation before caching no matter filter is passed or not
              response.cost = self.cost(response)
              self._update_usage_summary(response, use_cache=False)
              if cache_seed is not None:
                  # Cache the response
                  with diskcache.Cache(
                      f"{self.cache_path_root}/{cache_seed}"
                  ) as cache:
                      cache.set(key, response)
  
              # check the filter
              pass_filter = filter_func is None or filter_func(
                  context=context, response=response
              )
              if pass_filter or i == last:
                  # Return the response if it passes the filter or it is the last client
                  response.config_id = i
                  response.pass_filter = pass_filter
                  return response
              continue  # filter is not passed; try the next config
      raise RuntimeError("Should not reach here.")
  
imports: from __future__ import annotations
  import os
  import sys
  from typing import Any, List, Optional, Dict, Callable, Tuple, Union
  import logging
  import inspect
  from flaml.automl.logger import logger_formatter
  from pydantic import BaseModel
  from autogen.oai import completion
  from autogen.oai.openai_utils import DEFAULT_AZURE_API_VERSION, get_key, OAI_PRICE1K
  from autogen.token_count_utils import count_token
  from autogen._pydantic import model_dump
label_desc: Use image node_id 7 for calling the OpenAIWrapper obj's underlying member method code with example usage: obj.create() and returns: response, response