mirror of
https://github.com/microsoft/autogen.git
synced 2025-08-11 18:21:31 +00:00
[Core] Extending inline docs for openai_utils.py
, boosting coverage in test_utils.py
, fixing #762 (#1046)
* fix for #762 ,get_config_list/oia assetion, docs, test * Improved docstrings * test_utils using fake data and temp files * "Black" formatting applied * Fix build (KEY_LOC and OAI_CONFIG_LIST as consts in test_client) * Ramping up openai_utils coverage * Missing parameter doc. --------- Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
This commit is contained in:
parent
9388bae02d
commit
16b1723c74
@ -74,14 +74,36 @@ def get_key(config):
|
||||
def get_config_list(
|
||||
api_keys: List, base_urls: Optional[List] = None, api_type: Optional[str] = None, api_version: Optional[str] = None
|
||||
) -> List[Dict]:
|
||||
"""Get a list of configs for openai api calls.
|
||||
"""Get a list of configs for OpenAI API client.
|
||||
|
||||
Args:
|
||||
api_keys (list): The api keys for openai api calls.
|
||||
base_urls (list, optional): The api bases for openai api calls.
|
||||
base_urls (list, optional): The api bases for openai api calls. If provided, should match the length of api_keys.
|
||||
api_type (str, optional): The api type for openai api calls.
|
||||
api_version (str, optional): The api version for openai api calls.
|
||||
|
||||
Returns:
|
||||
list: A list of configs for OepnAI API calls.
|
||||
|
||||
Example:
|
||||
```
|
||||
# Define a list of API keys
|
||||
api_keys = ['key1', 'key2', 'key3']
|
||||
|
||||
# Optionally, define a list of base URLs corresponding to each API key
|
||||
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
|
||||
api_type = 'openai'
|
||||
api_version = 'v1'
|
||||
|
||||
# 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)
|
||||
```
|
||||
|
||||
"""
|
||||
if base_urls is not None:
|
||||
assert len(api_keys) == len(base_urls), "The length of api_keys must match the length of base_urls"
|
||||
config_list = []
|
||||
for i, api_key in enumerate(api_keys):
|
||||
if not api_key.strip():
|
||||
@ -101,20 +123,57 @@ def config_list_openai_aoai(
|
||||
key_file_path: Optional[str] = ".",
|
||||
openai_api_key_file: Optional[str] = "key_openai.txt",
|
||||
aoai_api_key_file: Optional[str] = "key_aoai.txt",
|
||||
openai_api_base_file: Optional[str] = "base_openai.txt",
|
||||
aoai_api_base_file: Optional[str] = "base_aoai.txt",
|
||||
exclude: Optional[str] = None,
|
||||
) -> List[Dict]:
|
||||
"""Get a list of configs for openai + azure openai api calls.
|
||||
"""Get a list of configs for OpenAI API client (including Azure or local model deployments that support OpenAI's chat completion API).
|
||||
|
||||
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.
|
||||
|
||||
Args:
|
||||
key_file_path (str, optional): The path to the key files.
|
||||
openai_api_key_file (str, optional): The file name of the openai api key.
|
||||
aoai_api_key_file (str, optional): The file name of the azure openai api key.
|
||||
aoai_api_base_file (str, optional): The file name of the azure openai api base.
|
||||
exclude (str, optional): The api type to exclude, "openai" or "aoai".
|
||||
key_file_path (str, optional): The directory path where the API key files are located. Defaults to the current directory.
|
||||
openai_api_key_file (str, optional): The filename containing the OpenAI API key. Defaults to 'key_openai.txt'.
|
||||
aoai_api_key_file (str, optional): The filename containing the Azure OpenAI API key. Defaults to 'key_aoai.txt'.
|
||||
openai_api_base_file (str, optional): The filename containing the OpenAI API base URL. Defaults to 'base_openai.txt'.
|
||||
aoai_api_base_file (str, optional): The filename containing the Azure OpenAI API base URL. Defaults to 'base_aoai.txt'.
|
||||
exclude (str, optional): The API type to exclude from the configuration list. Can be 'openai' or 'aoai'. Defaults to None.
|
||||
|
||||
Returns:
|
||||
list: A list of configs for openai api calls.
|
||||
List[Dict]: A list of configuration dictionaries. Each dictionary contains keys for 'api_key', 'base_url', 'api_type',
|
||||
and 'api_version'.
|
||||
|
||||
Raises:
|
||||
FileNotFoundError: If the specified key files are not found and the corresponding API key is not set in the environment variables.
|
||||
|
||||
Example:
|
||||
# To generate configurations excluding Azure OpenAI:
|
||||
configs = config_list_openai_aoai(exclude='aoai')
|
||||
|
||||
File samples:
|
||||
- key_aoai.txt
|
||||
|
||||
```
|
||||
aoai-12345abcdef67890ghijklmnopqr
|
||||
aoai-09876zyxwvuts54321fedcba
|
||||
```
|
||||
|
||||
- base_aoai.txt
|
||||
|
||||
```
|
||||
https://api.azure.com/v1
|
||||
https://api.azure2.com/v1
|
||||
```
|
||||
|
||||
Notes:
|
||||
- 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
|
||||
'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.
|
||||
- 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
|
||||
multiple entries.
|
||||
"""
|
||||
if "OPENAI_API_KEY" not in os.environ and exclude != "openai":
|
||||
try:
|
||||
@ -125,6 +184,15 @@ def config_list_openai_aoai(
|
||||
"OPENAI_API_KEY is not found in os.environ "
|
||||
"and key_openai.txt is not found in the specified path. You can specify the api_key in the config_list."
|
||||
)
|
||||
if "OPENAI_API_BASE" not in os.environ and exclude != "openai":
|
||||
try:
|
||||
with open(f"{key_file_path}/{openai_api_base_file}") as key_file:
|
||||
os.environ["OPENAI_API_BASE"] = key_file.read().strip()
|
||||
except FileNotFoundError:
|
||||
logging.info(
|
||||
"OPENAI_API_BASE is not found in os.environ "
|
||||
"and base_openai.txt is not found in the specified path. You can specify the base_url in the config_list."
|
||||
)
|
||||
if "AZURE_OPENAI_API_KEY" not in os.environ and exclude != "aoai":
|
||||
try:
|
||||
with open(f"{key_file_path}/{aoai_api_key_file}") as key_file:
|
||||
@ -159,8 +227,8 @@ def config_list_openai_aoai(
|
||||
get_config_list(
|
||||
# Assuming OpenAI API_KEY in os.environ["OPENAI_API_KEY"]
|
||||
api_keys=os.environ.get("OPENAI_API_KEY", "").split("\n"),
|
||||
base_urls=os.environ.get("OPENAI_API_BASE", "").split("\n"),
|
||||
# "api_type": "open_ai",
|
||||
# "base_url": "https://api.openai.com/v1",
|
||||
)
|
||||
if exclude != "openai"
|
||||
else []
|
||||
@ -177,18 +245,52 @@ def config_list_from_models(
|
||||
exclude: Optional[str] = None,
|
||||
model_list: Optional[list] = None,
|
||||
) -> List[Dict]:
|
||||
"""Get a list of configs for api calls with models in the model list.
|
||||
"""
|
||||
Get a list of configs for API calls with models specified in the model list.
|
||||
|
||||
This function extends `config_list_openai_aoai` by allowing to clone its' out for each fof the models provided.
|
||||
Each configuration will have a 'model' key with the model name as its value. This is particularly useful when
|
||||
all endpoints have same set of models.
|
||||
|
||||
Args:
|
||||
key_file_path (str, optional): The path to the key files.
|
||||
openai_api_key_file (str, optional): The file name of the openai api key.
|
||||
aoai_api_key_file (str, optional): The file name of the azure openai api key.
|
||||
aoai_api_base_file (str, optional): The file name of the azure openai api base.
|
||||
exclude (str, optional): The api type to exclude, "openai" or "aoai".
|
||||
model_list (list, optional): The model list.
|
||||
openai_api_key_file (str, optional): The file name of the OpenAI API key.
|
||||
aoai_api_key_file (str, optional): The file name of the Azure OpenAI API key.
|
||||
aoai_api_base_file (str, optional): The file name of the Azure OpenAI API base.
|
||||
exclude (str, optional): The API type to exclude, "openai" or "aoai".
|
||||
model_list (list, optional): The list of model names to include in the configs.
|
||||
|
||||
Returns:
|
||||
list: A list of configs for openai api calls.
|
||||
list: A list of configs for OpenAI API calls, each including model information.
|
||||
|
||||
Example:
|
||||
```
|
||||
# Define the path where the API key files are located
|
||||
key_file_path = '/path/to/key/files'
|
||||
|
||||
# Define the file names for the OpenAI and Azure OpenAI API keys and bases
|
||||
openai_api_key_file = 'key_openai.txt'
|
||||
aoai_api_key_file = 'key_aoai.txt'
|
||||
aoai_api_base_file = 'base_aoai.txt'
|
||||
|
||||
# Define the list of models for which to create configurations
|
||||
model_list = ['text-davinci-003', 'gpt-3.5-turbo']
|
||||
|
||||
# Call the function to get a list of configuration dictionaries
|
||||
config_list = config_list_from_models(
|
||||
key_file_path=key_file_path,
|
||||
openai_api_key_file=openai_api_key_file,
|
||||
aoai_api_key_file=aoai_api_key_file,
|
||||
aoai_api_base_file=aoai_api_base_file,
|
||||
model_list=model_list
|
||||
)
|
||||
|
||||
# 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-3.5-turbo'}
|
||||
# ]
|
||||
```
|
||||
"""
|
||||
config_list = config_list_openai_aoai(
|
||||
key_file_path,
|
||||
@ -209,7 +311,7 @@ def config_list_gpt4_gpt35(
|
||||
aoai_api_base_file: Optional[str] = "base_aoai.txt",
|
||||
exclude: Optional[str] = None,
|
||||
) -> List[Dict]:
|
||||
"""Get a list of configs for gpt-4 followed by gpt-3.5 api calls.
|
||||
"""Get a list of configs for 'gpt-4' followed by 'gpt-3.5-turbo' API calls.
|
||||
|
||||
Args:
|
||||
key_file_path (str, optional): The path to the key files.
|
||||
@ -232,15 +334,50 @@ def config_list_gpt4_gpt35(
|
||||
|
||||
|
||||
def filter_config(config_list, filter_dict):
|
||||
"""Filter the config list by provider and model.
|
||||
"""
|
||||
This function filters `config_list` by checking each configuration dictionary against the
|
||||
criteria specified in `filter_dict`. A configuration dictionary is retained if for every
|
||||
key in `filter_dict`, see example below.
|
||||
|
||||
Args:
|
||||
config_list (list): The config list.
|
||||
filter_dict (dict, optional): The filter dict with keys corresponding to a field in each config,
|
||||
and values corresponding to lists of acceptable values for each key.
|
||||
config_list (list of dict): A list of configuration dictionaries to be filtered.
|
||||
filter_dict (dict): A dictionary representing the filter criteria, where each key is a
|
||||
field name to check within the configuration dictionaries, and the
|
||||
corresponding value is a list of acceptable values for that field.
|
||||
|
||||
Returns:
|
||||
list: The filtered config list.
|
||||
list of dict: A list of configuration dictionaries that meet all the criteria specified
|
||||
in `filter_dict`.
|
||||
|
||||
Example:
|
||||
```
|
||||
# Example configuration list with various models and API types
|
||||
configs = [
|
||||
{'model': 'gpt-3.5-turbo', 'api_type': 'openai'},
|
||||
{'model': 'gpt-4', 'api_type': 'openai'},
|
||||
{'model': 'gpt-3.5-turbo', 'api_type': 'azure'},
|
||||
]
|
||||
|
||||
# Define filter criteria to select configurations for the 'gpt-3.5-turbo' model
|
||||
# that are also using the 'openai' API type
|
||||
filter_criteria = {
|
||||
'model': ['gpt-3.5-turbo'], # Only accept configurations for 'gpt-3.5-turbo'
|
||||
'api_type': ['openai'] # Only accept configurations for 'openai' API type
|
||||
}
|
||||
|
||||
# Apply the filter to the configuration list
|
||||
filtered_configs = filter_config(configs, filter_criteria)
|
||||
|
||||
# The resulting `filtered_configs` will be:
|
||||
# [{'model': 'gpt-3.5-turbo', 'api_type': 'openai'}]
|
||||
```
|
||||
|
||||
Note:
|
||||
- If `filter_dict` is empty or None, no filtering is applied and `config_list` is returned as is.
|
||||
- If a configuration dictionary in `config_list` does not contain a key specified in `filter_dict`,
|
||||
it is considered a non-match and is excluded from the result.
|
||||
- If the list of acceptable values for a key in `filter_dict` includes None, then configuration
|
||||
dictionaries that do not have that key will also be considered a match.
|
||||
"""
|
||||
if filter_dict:
|
||||
config_list = [
|
||||
@ -254,23 +391,37 @@ def config_list_from_json(
|
||||
file_location: Optional[str] = "",
|
||||
filter_dict: Optional[Dict[str, Union[List[Union[str, None]], Set[Union[str, None]]]]] = None,
|
||||
) -> List[Dict]:
|
||||
"""Get a list of configs from a json parsed from an env variable or a file.
|
||||
"""
|
||||
Retrieves a list of API configurations from a JSON stored in an environment variable or a file.
|
||||
|
||||
This function attempts to parse JSON data from the given `env_or_file` parameter. If `env_or_file` is an
|
||||
environment variable containing JSON data, it will be used directly. Otherwise, it is assumed to be a filename,
|
||||
and the function will attempt to read the file from the specified `file_location`.
|
||||
|
||||
The `filter_dict` parameter allows for filtering the configurations based on specified criteria. Each key in the
|
||||
`filter_dict` corresponds to a field in the configuration dictionaries, and the associated value is a list or set
|
||||
of acceptable values for that field. If a field is missing in a configuration and `None` is included in the list
|
||||
of acceptable values for that field, the configuration will still be considered a match.
|
||||
|
||||
Args:
|
||||
env_or_file (str): The env variable name or file name.
|
||||
file_location (str, optional): The file location.
|
||||
filter_dict (dict, optional): The filter dict with keys corresponding to a field in each config,
|
||||
and values corresponding to lists of acceptable values for each key.
|
||||
e.g.,
|
||||
```python
|
||||
filter_dict = {
|
||||
"api_type": ["open_ai", None], # None means a missing key is acceptable
|
||||
"model": ["gpt-3.5-turbo", "gpt-4"],
|
||||
}
|
||||
env_or_file (str): The name of the environment variable or the filename containing the JSON data.
|
||||
file_location (str, optional): The directory path where the file is located, if `env_or_file` is a filename.
|
||||
filter_dict (dict, optional): A dictionary specifying the filtering criteria for the configurations, with
|
||||
keys representing field names and values being lists or sets of acceptable values for those fields.
|
||||
|
||||
Example:
|
||||
```
|
||||
# Suppose we have an environment variable 'CONFIG_JSON' with the following content:
|
||||
# '[{"model": "gpt-3.5-turbo", "api_type": "openai"}, {"model": "gpt-4", "api_type": "openai"}]'
|
||||
|
||||
# We can retrieve a filtered list of configurations like this:
|
||||
filter_criteria = {"api_type": ["openai"], "model": ["gpt-3.5-turbo"]}
|
||||
configs = config_list_from_json('CONFIG_JSON', filter_dict=filter_criteria)
|
||||
# The 'configs' variable will now contain only the configurations that match the filter criteria.
|
||||
```
|
||||
|
||||
Returns:
|
||||
list: A list of configs for openai api calls.
|
||||
List[Dict]: A list of configuration dictionaries that match the filtering criteria specified in `filter_dict`.
|
||||
"""
|
||||
json_str = os.environ.get(env_or_file)
|
||||
if json_str:
|
||||
@ -290,27 +441,33 @@ def get_config(
|
||||
api_key: str, base_url: Optional[str] = None, api_type: Optional[str] = None, api_version: Optional[str] = None
|
||||
) -> Dict:
|
||||
"""
|
||||
Construct a configuration dictionary with the provided API configurations.
|
||||
Appending the additional configurations to the config only if they're set
|
||||
Constructs a configuration dictionary for a single model with the provided API configurations.
|
||||
|
||||
Example:
|
||||
```
|
||||
config = get_config(
|
||||
api_key="sk-abcdef1234567890",
|
||||
base_url="https://api.openai.com",
|
||||
api_type="openai",
|
||||
api_version="v1"
|
||||
)
|
||||
# The 'config' variable will now contain:
|
||||
# {
|
||||
# "api_key": "sk-abcdef1234567890",
|
||||
# "base_url": "https://api.openai.com",
|
||||
# "api_type": "openai",
|
||||
# "api_version": "v1"
|
||||
# }
|
||||
```
|
||||
|
||||
example:
|
||||
>> model_api_key_map={
|
||||
"gpt-4": "OPENAI_API_KEY",
|
||||
"gpt-3.5-turbo": {
|
||||
"api_key_env_var": "ANOTHER_API_KEY",
|
||||
"api_type": "aoai",
|
||||
"api_version": "v2",
|
||||
"base_url": "https://api.someotherapi.com"
|
||||
}
|
||||
}
|
||||
Args:
|
||||
api_key (str): The API key used for authenticating API requests.
|
||||
base_url (str, optional): The base URL of the API. Defaults to None.
|
||||
api_type (str, optional): The type or kind of API. Defaults to None.
|
||||
api_version (str, optional): The API version. Defaults to None.
|
||||
api_key (str): The API key for authenticating API requests.
|
||||
base_url (Optional[str]): The base URL of the API. If not provided, defaults to None.
|
||||
api_type (Optional[str]): The type of API. If not provided, defaults to None.
|
||||
api_version (Optional[str]): The version of the API. If not provided, defaults to None.
|
||||
|
||||
Returns:
|
||||
Dict: A dictionary containing the API configurations.
|
||||
Dict: A dictionary containing the provided API configurations.
|
||||
"""
|
||||
config = {"api_key": api_key}
|
||||
if base_url:
|
||||
|
@ -1,6 +1,5 @@
|
||||
import pytest
|
||||
from autogen import OpenAIWrapper, config_list_from_json, config_list_openai_aoai
|
||||
from test_utils import OAI_CONFIG_LIST, KEY_LOC
|
||||
|
||||
TOOL_ENABLED = False
|
||||
try:
|
||||
@ -15,6 +14,9 @@ else:
|
||||
if openai.__version__ >= "1.1.0":
|
||||
TOOL_ENABLED = True
|
||||
|
||||
KEY_LOC = "notebook"
|
||||
OAI_CONFIG_LIST = "OAI_CONFIG_LIST"
|
||||
|
||||
|
||||
@pytest.mark.skipif(skip, reason="openai>=1 not installed")
|
||||
def test_aoai_chat_completion():
|
||||
|
@ -1,6 +1,5 @@
|
||||
import pytest
|
||||
from autogen import OpenAIWrapper, config_list_from_json, config_list_openai_aoai
|
||||
from test_utils import OAI_CONFIG_LIST, KEY_LOC
|
||||
|
||||
try:
|
||||
from openai import OpenAI
|
||||
@ -9,6 +8,9 @@ except ImportError:
|
||||
else:
|
||||
skip = False
|
||||
|
||||
KEY_LOC = "notebook"
|
||||
OAI_CONFIG_LIST = "OAI_CONFIG_LIST"
|
||||
|
||||
|
||||
@pytest.mark.skipif(skip, reason="openai>=1 not installed")
|
||||
def test_aoai_chat_completion_stream():
|
||||
|
@ -5,11 +5,9 @@ import pytest
|
||||
import logging
|
||||
import tempfile
|
||||
from unittest import mock
|
||||
from unittest.mock import patch
|
||||
import autogen # noqa: E402
|
||||
|
||||
KEY_LOC = "notebook"
|
||||
OAI_CONFIG_LIST = "OAI_CONFIG_LIST"
|
||||
|
||||
sys.path.append("../../autogen")
|
||||
|
||||
# Example environment variables
|
||||
@ -38,6 +36,31 @@ FILTER_DICT = {
|
||||
}
|
||||
}
|
||||
|
||||
JSON_SAMPLE = """
|
||||
[
|
||||
{
|
||||
"model": "gpt-3.5-turbo",
|
||||
"api_type": "openai"
|
||||
},
|
||||
{
|
||||
"model": "gpt-4",
|
||||
"api_type": "openai"
|
||||
},
|
||||
{
|
||||
"model": "gpt-35-turbo-v0301",
|
||||
"api_key": "111113fc7e8a46419bfac511bb301111",
|
||||
"base_url": "https://1111.openai.azure.com",
|
||||
"api_type": "azure",
|
||||
"api_version": "2023-07-01-preview"
|
||||
},
|
||||
{
|
||||
"model": "gpt",
|
||||
"api_key": "not-needed",
|
||||
"base_url": "http://localhost:1234/v1"
|
||||
}
|
||||
]
|
||||
"""
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_os_environ():
|
||||
@ -46,35 +69,125 @@ def mock_os_environ():
|
||||
|
||||
|
||||
def test_config_list_from_json():
|
||||
# Test the functionality for loading configurations from JSON file
|
||||
# and ensuring that the loaded configurations are as expected.
|
||||
config_list = autogen.config_list_gpt4_gpt35(key_file_path=KEY_LOC)
|
||||
json_file = os.path.join(KEY_LOC, "config_list_test.json")
|
||||
with tempfile.NamedTemporaryFile(mode="w+", delete=False) as tmp_file:
|
||||
json_data = json.loads(JSON_SAMPLE)
|
||||
tmp_file.write(JSON_SAMPLE)
|
||||
tmp_file.flush()
|
||||
|
||||
with open(json_file, "w") as f:
|
||||
json.dump(config_list, f, indent=4)
|
||||
config_list = autogen.config_list_from_json(tmp_file.name)
|
||||
|
||||
config_list_1 = autogen.config_list_from_json(json_file)
|
||||
assert config_list == config_list_1
|
||||
assert len(config_list) == len(json_data)
|
||||
i = 0
|
||||
for config in config_list:
|
||||
assert isinstance(config, dict)
|
||||
for key in config:
|
||||
assert key in json_data[i]
|
||||
assert config[key] == json_data[i][key]
|
||||
i += 1
|
||||
|
||||
os.environ["config_list_test"] = json.dumps(config_list)
|
||||
os.environ["config_list_test"] = JSON_SAMPLE
|
||||
config_list_2 = autogen.config_list_from_json("config_list_test")
|
||||
assert config_list == config_list_2
|
||||
|
||||
config_list_3 = autogen.config_list_from_json(
|
||||
OAI_CONFIG_LIST, file_location=KEY_LOC, filter_dict={"model": ["gpt4", "gpt-4-32k"]}
|
||||
tmp_file.name, filter_dict={"model": ["gpt", "gpt-4", "gpt-4-32k"]}
|
||||
)
|
||||
assert all(config.get("model") in ["gpt4", "gpt-4-32k"] for config in config_list_3)
|
||||
assert all(config.get("model") in ["gpt-4", "gpt"] for config in config_list_3)
|
||||
|
||||
del os.environ["config_list_test"]
|
||||
os.remove(json_file)
|
||||
|
||||
|
||||
def test_config_list_openai_aoai():
|
||||
# Testing the functionality for loading configurations for different API types
|
||||
# and ensuring the API types in the loaded configurations are as expected.
|
||||
config_list = autogen.config_list_openai_aoai(key_file_path=KEY_LOC)
|
||||
assert all(config.get("api_type") in [None, "open_ai", "azure"] for config in config_list)
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
# Create temporary files with sample data for keys and base URLs
|
||||
openai_key_file = os.path.join(temp_dir, "key_openai.txt")
|
||||
aoai_key_file = os.path.join(temp_dir, "key_aoai.txt")
|
||||
openai_base_file = os.path.join(temp_dir, "base_openai.txt")
|
||||
aoai_base_file = os.path.join(temp_dir, "base_aoai.txt")
|
||||
|
||||
# Write sample data to the temporary files
|
||||
with open(openai_key_file, "w") as f:
|
||||
f.write("sk-testkeyopenai123\nsk-testkeyopenai456")
|
||||
with open(aoai_key_file, "w") as f:
|
||||
f.write("sk-testkeyaoai456")
|
||||
with open(openai_base_file, "w") as f:
|
||||
f.write("https://api.openai.com/v1\nhttps://api.openai.com/v1")
|
||||
with open(aoai_base_file, "w") as f:
|
||||
f.write("https://api.azure.com/v1")
|
||||
|
||||
# Pass the temporary directory as a parameter to the function
|
||||
config_list = autogen.config_list_openai_aoai(key_file_path=temp_dir)
|
||||
assert len(config_list) == 3
|
||||
expected_config_list = [
|
||||
{"api_key": "sk-testkeyopenai123", "base_url": "https://api.openai.com/v1"},
|
||||
{"api_key": "sk-testkeyopenai456", "base_url": "https://api.openai.com/v1"},
|
||||
{
|
||||
"api_key": "sk-testkeyaoai456",
|
||||
"base_url": "https://api.azure.com/v1",
|
||||
"api_type": "azure",
|
||||
"api_version": "2023-08-01-preview",
|
||||
},
|
||||
]
|
||||
assert config_list == expected_config_list
|
||||
|
||||
|
||||
@patch(
|
||||
"os.environ",
|
||||
{
|
||||
"OPENAI_API_KEY": "test_openai_key",
|
||||
"OPENAI_API_BASE": "https://api.openai.com",
|
||||
"AZURE_OPENAI_API_KEY": "test_aoai_key",
|
||||
"AZURE_OPENAI_API_BASE": "https://api.azure.com",
|
||||
},
|
||||
)
|
||||
def test_config_list_openai_aoai_env_vars():
|
||||
# Test the config_list_openai_aoai function with environment variables set
|
||||
configs = autogen.oai.openai_utils.config_list_openai_aoai()
|
||||
assert len(configs) == 2
|
||||
assert {"api_key": "test_openai_key", "base_url": "https://api.openai.com"} in configs
|
||||
assert {
|
||||
"api_key": "test_aoai_key",
|
||||
"base_url": "https://api.azure.com",
|
||||
"api_type": "azure",
|
||||
"api_version": "2023-08-01-preview",
|
||||
} in configs
|
||||
|
||||
|
||||
@patch(
|
||||
"os.environ",
|
||||
{
|
||||
"OPENAI_API_KEY": "test_openai_key\ntest_openai_key2",
|
||||
"OPENAI_API_BASE": "https://api.openai.com\nhttps://api.openai.com/v2",
|
||||
"AZURE_OPENAI_API_KEY": "test_aoai_key\ntest_aoai_key2",
|
||||
"AZURE_OPENAI_API_BASE": "https://api.azure.com\nhttps://api.azure.com/v2",
|
||||
},
|
||||
)
|
||||
def test_config_list_openai_aoai_env_vars_multi():
|
||||
# Test the config_list_openai_aoai function with multiple environment variable values (new line separated)
|
||||
configs = autogen.oai.openai_utils.config_list_openai_aoai()
|
||||
assert len(configs) == 4
|
||||
assert {"api_key": "test_openai_key", "base_url": "https://api.openai.com"} in configs
|
||||
assert {"api_key": "test_openai_key2", "base_url": "https://api.openai.com/v2"} in configs
|
||||
assert {
|
||||
"api_key": "test_aoai_key",
|
||||
"base_url": "https://api.azure.com",
|
||||
"api_type": "azure",
|
||||
"api_version": "2023-08-01-preview",
|
||||
} in configs
|
||||
assert {
|
||||
"api_key": "test_aoai_key2",
|
||||
"base_url": "https://api.azure.com/v2",
|
||||
"api_type": "azure",
|
||||
"api_version": "2023-08-01-preview",
|
||||
} in configs
|
||||
|
||||
|
||||
def test_config_list_openai_aoai_file_not_found():
|
||||
with mock.patch.dict(os.environ, {}, clear=True):
|
||||
config_list = autogen.config_list_openai_aoai(key_file_path="non_existent_path")
|
||||
assert len(config_list) == 0
|
||||
|
||||
|
||||
def test_config_list_from_dotenv(mock_os_environ, caplog):
|
||||
@ -160,5 +273,52 @@ def test_config_list_from_dotenv(mock_os_environ, caplog):
|
||||
assert "API key not found or empty for model gpt-4" in caplog.text
|
||||
|
||||
|
||||
def test_get_config_list():
|
||||
# Define a list of API keys and corresponding base URLs
|
||||
api_keys = ["key1", "key2", "key3"]
|
||||
base_urls = ["https://api.service1.com", "https://api.service2.com", "https://api.service3.com"]
|
||||
api_type = "openai"
|
||||
api_version = "v1"
|
||||
|
||||
# Call the get_config_list function to get a list of configuration dictionaries
|
||||
config_list = autogen.get_config_list(api_keys, base_urls, api_type, api_version)
|
||||
|
||||
# Check that the config_list is not empty
|
||||
assert config_list, "The config_list should not be empty."
|
||||
|
||||
# Check that the config_list has the correct length
|
||||
assert len(config_list) == len(
|
||||
api_keys
|
||||
), "The config_list should have the same number of items as the api_keys list."
|
||||
|
||||
# Check that each config in the config_list has the correct structure and data
|
||||
for i, config in enumerate(config_list):
|
||||
assert config["api_key"] == api_keys[i], f"The api_key for config {i} is incorrect."
|
||||
assert config["base_url"] == base_urls[i], f"The base_url for config {i} is incorrect."
|
||||
assert config["api_type"] == api_type, f"The api_type for config {i} is incorrect."
|
||||
assert config["api_version"] == api_version, f"The api_version for config {i} is incorrect."
|
||||
|
||||
# Test with mismatched lengths of api_keys and base_urls
|
||||
with pytest.raises(AssertionError) as exc_info:
|
||||
autogen.get_config_list(api_keys, base_urls[:2], api_type, api_version)
|
||||
assert str(exc_info.value) == "The length of api_keys must match the length of base_urls"
|
||||
|
||||
# Test with empty api_keys
|
||||
with pytest.raises(AssertionError) as exc_info:
|
||||
autogen.get_config_list([], base_urls, api_type, api_version)
|
||||
assert str(exc_info.value) == "The length of api_keys must match the length of base_urls"
|
||||
|
||||
# Test with None base_urls
|
||||
config_list_without_base = autogen.get_config_list(api_keys, None, api_type, api_version)
|
||||
assert all(
|
||||
"base_url" not in config for config in config_list_without_base
|
||||
), "The configs should not have base_url when None is provided."
|
||||
|
||||
# Test with empty string in api_keys
|
||||
api_keys_with_empty = ["key1", "", "key3"]
|
||||
config_list_with_empty_key = autogen.get_config_list(api_keys_with_empty, base_urls, api_type, api_version)
|
||||
assert len(config_list_with_empty_key) == 2, "The config_list should exclude configurations with empty api_keys."
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
pytest.main()
|
||||
|
Loading…
x
Reference in New Issue
Block a user