openai base url default to None; read files when env vars exist; remove deprecated models (#1110)

* openai base url default to None

* read from files when env vars exist
This commit is contained in:
Chi Wang 2023-12-31 10:12:49 -08:00 committed by GitHub
parent a9483a492c
commit 3b0e059699
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 67 additions and 58 deletions

View File

@ -8,7 +8,7 @@ import inspect
from flaml.automl.logger import logger_formatter from flaml.automl.logger import logger_formatter
from pydantic import ValidationError from pydantic import ValidationError
from autogen.oai.openai_utils import get_key, oai_price1k from autogen.oai.openai_utils import get_key, OAI_PRICE1K
from autogen.token_count_utils import count_token from autogen.token_count_utils import count_token
TOOL_ENABLED = False TOOL_ENABLED = False
@ -446,13 +446,13 @@ class OpenAIWrapper:
def cost(self, response: Union[ChatCompletion, Completion]) -> float: def cost(self, response: Union[ChatCompletion, Completion]) -> float:
"""Calculate the cost of the response.""" """Calculate the cost of the response."""
model = response.model model = response.model
if model not in oai_price1k: if model not in OAI_PRICE1K:
# TODO: add logging to warn that the model is not found # TODO: add logging to warn that the model is not found
return 0 return 0
n_input_tokens = response.usage.prompt_tokens n_input_tokens = response.usage.prompt_tokens
n_output_tokens = response.usage.completion_tokens n_output_tokens = response.usage.completion_tokens
tmp_price1K = oai_price1k[model] tmp_price1K = OAI_PRICE1K[model]
# First value is input token rate, second value is output token rate # First value is input token rate, second value is output token rate
if isinstance(tmp_price1K, tuple): if isinstance(tmp_price1K, tuple):
return (tmp_price1K[0] * n_input_tokens + tmp_price1K[1] * n_output_tokens) / 1000 return (tmp_price1K[0] * n_input_tokens + tmp_price1K[1] * n_output_tokens) / 1000

View File

@ -17,8 +17,8 @@ except ImportError:
Assistant = object Assistant = object
NON_CACHE_KEY = ["api_key", "base_url", "api_type", "api_version"] NON_CACHE_KEY = ["api_key", "base_url", "api_type", "api_version"]
DEFAULT_AZURE_API_VERSION = "2023-08-01-preview"
oai_price1k = { OAI_PRICE1K = {
"text-ada-001": 0.0004, "text-ada-001": 0.0004,
"text-babbage-001": 0.0005, "text-babbage-001": 0.0005,
"text-curie-001": 0.002, "text-curie-001": 0.002,
@ -94,8 +94,8 @@ def get_config_list(
base_urls = ['https://api.service1.com', 'https://api.service2.com', 'https://api.service3.com'] base_urls = ['https://api.service1.com', 'https://api.service2.com', 'https://api.service3.com']
# Optionally, define the API type and version if they are common for all keys # Optionally, define the API type and version if they are common for all keys
api_type = 'openai' api_type = 'azure'
api_version = 'v1' api_version = '2023-08-01-preview'
# Call the get_config_list function to get a list of configuration dictionaries # Call the get_config_list function to get a list of configuration dictionaries
config_list = get_config_list(api_keys, base_urls, api_type, api_version) config_list = get_config_list(api_keys, base_urls, api_type, api_version)
@ -131,6 +131,9 @@ def config_list_openai_aoai(
This function constructs configurations by reading API keys and base URLs from environment variables or text files. This function constructs configurations by reading API keys and base URLs from environment variables or text files.
It supports configurations for both OpenAI and Azure OpenAI services, allowing for the exclusion of one or the other. It supports configurations for both OpenAI and Azure OpenAI services, allowing for the exclusion of one or the other.
When text files are used, the environment variables will be overwritten.
To prevent text files from being used, set the corresponding file name to None.
Or set key_file_path to None to disallow reading from text files.
Args: Args:
key_file_path (str, optional): The directory path where the API key files are located. Defaults to the current directory. key_file_path (str, optional): The directory path where the API key files are located. Defaults to the current directory.
@ -170,47 +173,53 @@ def config_list_openai_aoai(
- The function checks for API keys and base URLs in the following environment variables: 'OPENAI_API_KEY', 'AZURE_OPENAI_API_KEY', - The function checks for API keys and base URLs in the following environment variables: 'OPENAI_API_KEY', 'AZURE_OPENAI_API_KEY',
'OPENAI_API_BASE' and 'AZURE_OPENAI_API_BASE'. If these are not found, it attempts to read from the specified files in the 'OPENAI_API_BASE' and 'AZURE_OPENAI_API_BASE'. If these are not found, it attempts to read from the specified files in the
'key_file_path' directory. 'key_file_path' directory.
- The API version for Azure configurations is set to '2023-08-01-preview' by default and can be changed as necessary. - The API version for Azure configurations is set to DEFAULT_AZURE_API_VERSION by default.
- If 'exclude' is set to 'openai', only Azure OpenAI configurations are returned, and vice versa. - If 'exclude' is set to 'openai', only Azure OpenAI configurations are returned, and vice versa.
- The function assumes that the API keys and base URLs in the environment variables are separated by new lines if there are - The function assumes that the API keys and base URLs in the environment variables are separated by new lines if there are
multiple entries. multiple entries.
""" """
if "OPENAI_API_KEY" not in os.environ and exclude != "openai": if exclude != "openai" and key_file_path is not None:
try: # skip if key_file_path is None
with open(f"{key_file_path}/{openai_api_key_file}") as key_file: if openai_api_key_file is not None:
os.environ["OPENAI_API_KEY"] = key_file.read().strip() # skip if openai_api_key_file is None
except FileNotFoundError: try:
logging.info( with open(f"{key_file_path}/{openai_api_key_file}") as key_file:
"OPENAI_API_KEY is not found in os.environ " os.environ["OPENAI_API_KEY"] = key_file.read().strip()
"and key_openai.txt is not found in the specified path. You can specify the api_key in the config_list." except FileNotFoundError:
) logging.info(
if "OPENAI_API_BASE" not in os.environ and exclude != "openai": "OPENAI_API_KEY is not found in os.environ "
try: "and key_openai.txt is not found in the specified path. You can specify the api_key in the config_list."
with open(f"{key_file_path}/{openai_api_base_file}") as key_file: )
os.environ["OPENAI_API_BASE"] = key_file.read().strip() if openai_api_base_file is not None:
except FileNotFoundError: # skip if openai_api_base_file is None
logging.info( try:
"OPENAI_API_BASE is not found in os.environ " with open(f"{key_file_path}/{openai_api_base_file}") as key_file:
"and base_openai.txt is not found in the specified path. You can specify the base_url in the config_list." os.environ["OPENAI_API_BASE"] = key_file.read().strip()
) except FileNotFoundError:
if "AZURE_OPENAI_API_KEY" not in os.environ and exclude != "aoai": logging.info(
try: "OPENAI_API_BASE is not found in os.environ "
with open(f"{key_file_path}/{aoai_api_key_file}") as key_file: "and base_openai.txt is not found in the specified path. You can specify the base_url in the config_list."
os.environ["AZURE_OPENAI_API_KEY"] = key_file.read().strip() )
except FileNotFoundError: if exclude != "aoai" and key_file_path is not None:
logging.info( # skip if key_file_path is None
"AZURE_OPENAI_API_KEY is not found in os.environ " if aoai_api_key_file is not None:
"and key_aoai.txt is not found in the specified path. You can specify the api_key in the config_list." try:
) with open(f"{key_file_path}/{aoai_api_key_file}") as key_file:
if "AZURE_OPENAI_API_BASE" not in os.environ and exclude != "aoai": os.environ["AZURE_OPENAI_API_KEY"] = key_file.read().strip()
try: except FileNotFoundError:
with open(f"{key_file_path}/{aoai_api_base_file}") as key_file: logging.info(
os.environ["AZURE_OPENAI_API_BASE"] = key_file.read().strip() "AZURE_OPENAI_API_KEY is not found in os.environ "
except FileNotFoundError: "and key_aoai.txt is not found in the specified path. You can specify the api_key in the config_list."
logging.info( )
"AZURE_OPENAI_API_BASE is not found in os.environ " if aoai_api_base_file is not None:
"and base_aoai.txt is not found in the specified path. You can specify the base_url in the config_list." try:
) with open(f"{key_file_path}/{aoai_api_base_file}") as key_file:
os.environ["AZURE_OPENAI_API_BASE"] = key_file.read().strip()
except FileNotFoundError:
logging.info(
"AZURE_OPENAI_API_BASE is not found in os.environ "
"and base_aoai.txt is not found in the specified path. You can specify the base_url in the config_list."
)
aoai_config = ( aoai_config = (
get_config_list( get_config_list(
# Assuming Azure OpenAI api keys in os.environ["AZURE_OPENAI_API_KEY"], in separated lines # Assuming Azure OpenAI api keys in os.environ["AZURE_OPENAI_API_KEY"], in separated lines
@ -218,16 +227,19 @@ def config_list_openai_aoai(
# Assuming Azure OpenAI api bases in os.environ["AZURE_OPENAI_API_BASE"], in separated lines # Assuming Azure OpenAI api bases in os.environ["AZURE_OPENAI_API_BASE"], in separated lines
base_urls=os.environ.get("AZURE_OPENAI_API_BASE", "").split("\n"), base_urls=os.environ.get("AZURE_OPENAI_API_BASE", "").split("\n"),
api_type="azure", api_type="azure",
api_version="2023-08-01-preview", # change if necessary api_version=DEFAULT_AZURE_API_VERSION,
) )
if exclude != "aoai" if exclude != "aoai"
else [] else []
) )
# process openai base urls
base_urls = os.environ.get("OPENAI_API_BASE", None)
base_urls = base_urls if base_urls is None else base_urls.split("\n")
openai_config = ( openai_config = (
get_config_list( get_config_list(
# Assuming OpenAI API_KEY in os.environ["OPENAI_API_KEY"] # Assuming OpenAI API_KEY in os.environ["OPENAI_API_KEY"]
api_keys=os.environ.get("OPENAI_API_KEY", "").split("\n"), api_keys=os.environ.get("OPENAI_API_KEY", "").split("\n"),
base_urls=os.environ.get("OPENAI_API_BASE", "").split("\n"), base_urls=base_urls,
# "api_type": "open_ai", # "api_type": "open_ai",
) )
if exclude != "openai" if exclude != "openai"
@ -274,7 +286,7 @@ def config_list_from_models(
aoai_api_base_file = 'base_aoai.txt' aoai_api_base_file = 'base_aoai.txt'
# Define the list of models for which to create configurations # Define the list of models for which to create configurations
model_list = ['text-davinci-003', 'gpt-3.5-turbo'] model_list = ['gpt-4', 'gpt-3.5-turbo']
# Call the function to get a list of configuration dictionaries # Call the function to get a list of configuration dictionaries
config_list = config_list_from_models( config_list = config_list_from_models(
@ -287,7 +299,7 @@ def config_list_from_models(
# The `config_list` will contain configurations for the specified models, for example: # The `config_list` will contain configurations for the specified models, for example:
# [ # [
# {'api_key': '...', 'base_url': 'https://api.openai.com', 'model': 'text-davinci-003'}, # {'api_key': '...', 'base_url': 'https://api.openai.com', 'model': 'gpt-4'},
# {'api_key': '...', 'base_url': 'https://api.openai.com', 'model': 'gpt-3.5-turbo'} # {'api_key': '...', 'base_url': 'https://api.openai.com', 'model': 'gpt-3.5-turbo'}
# ] # ]
``` ```

View File

@ -99,7 +99,6 @@ def test_completion():
[ [
(None, "gpt-3.5-turbo-instruct"), (None, "gpt-3.5-turbo-instruct"),
(42, "gpt-3.5-turbo-instruct"), (42, "gpt-3.5-turbo-instruct"),
(None, "text-ada-001"),
], ],
) )
def test_cost(cache_seed, model): def test_cost(cache_seed, model):
@ -144,5 +143,5 @@ if __name__ == "__main__":
test_oai_tool_calling_extraction() test_oai_tool_calling_extraction()
test_chat_completion() test_chat_completion()
test_completion() test_completion()
test_cost() # test_cost()
test_usage_summary() test_usage_summary()

View File

@ -1,5 +1,4 @@
import os import os
import sys
import json import json
import pytest import pytest
import logging import logging
@ -7,8 +6,7 @@ import tempfile
from unittest import mock from unittest import mock
from unittest.mock import patch from unittest.mock import patch
import autogen # noqa: E402 import autogen # noqa: E402
from autogen.oai.openai_utils import DEFAULT_AZURE_API_VERSION
sys.path.append("../../autogen")
# Example environment variables # Example environment variables
ENV_VARS = { ENV_VARS = {
@ -127,7 +125,7 @@ def test_config_list_openai_aoai():
"api_key": "sk-testkeyaoai456", "api_key": "sk-testkeyaoai456",
"base_url": "https://api.azure.com/v1", "base_url": "https://api.azure.com/v1",
"api_type": "azure", "api_type": "azure",
"api_version": "2023-08-01-preview", "api_version": DEFAULT_AZURE_API_VERSION,
}, },
] ]
assert config_list == expected_config_list assert config_list == expected_config_list
@ -144,14 +142,14 @@ def test_config_list_openai_aoai():
) )
def test_config_list_openai_aoai_env_vars(): def test_config_list_openai_aoai_env_vars():
# Test the config_list_openai_aoai function with environment variables set # Test the config_list_openai_aoai function with environment variables set
configs = autogen.oai.openai_utils.config_list_openai_aoai() configs = autogen.oai.openai_utils.config_list_openai_aoai(key_file_path=None)
assert len(configs) == 2 assert len(configs) == 2
assert {"api_key": "test_openai_key", "base_url": "https://api.openai.com"} in configs assert {"api_key": "test_openai_key", "base_url": "https://api.openai.com"} in configs
assert { assert {
"api_key": "test_aoai_key", "api_key": "test_aoai_key",
"base_url": "https://api.azure.com", "base_url": "https://api.azure.com",
"api_type": "azure", "api_type": "azure",
"api_version": "2023-08-01-preview", "api_version": DEFAULT_AZURE_API_VERSION,
} in configs } in configs
@ -174,13 +172,13 @@ def test_config_list_openai_aoai_env_vars_multi():
"api_key": "test_aoai_key", "api_key": "test_aoai_key",
"base_url": "https://api.azure.com", "base_url": "https://api.azure.com",
"api_type": "azure", "api_type": "azure",
"api_version": "2023-08-01-preview", "api_version": DEFAULT_AZURE_API_VERSION,
} in configs } in configs
assert { assert {
"api_key": "test_aoai_key2", "api_key": "test_aoai_key2",
"base_url": "https://api.azure.com/v2", "base_url": "https://api.azure.com/v2",
"api_type": "azure", "api_type": "azure",
"api_version": "2023-08-01-preview", "api_version": DEFAULT_AZURE_API_VERSION,
} in configs } in configs