66# --------------------------------------------------------------------------
77import os
88import pytest
9+ import importlib
10+ import contextlib
911import requests
1012import aiohttp
1113import yarl
1214import functools
1315import openai
1416from devtools_testutils .sanitizers import add_header_regex_sanitizer , add_oauth_response_sanitizer
15- from azure .identity import DefaultAzureCredential
17+ from azure .identity import DefaultAzureCredential , get_bearer_token_provider
18+ from azure .identity .aio import (
19+ DefaultAzureCredential as AsyncDefaultAzureCredential ,
20+ get_bearer_token_provider as get_bearer_token_provider_async ,
21+ )
1622
23+ # controls whether we run tests against v0 or v1. Options: v0 or v1. Default: v1
24+ ENV_OPENAI_TEST_MODE = "OPENAI_TEST_MODE"
1725
1826# for pytest.parametrize
1927ALL = ["azure" , "azuread" , "openai" ]
2028AZURE = "azure"
2129OPENAI = "openai"
2230AZURE_AD = "azuread"
31+ WHISPER_AZURE = "whisper_azure"
32+ WHISPER_AZURE_AD = "whisper_azuread"
33+ WHISPER_ALL = ["whisper_azure" , "whisper_azuread" , "openai" ]
2334
2435# Environment variable keys
25- ENV_AZURE_OPENAI_ENDPOINT = "AZURE_OPENAI_ENDPOINT "
36+ ENV_AZURE_OPENAI_ENDPOINT = "AZ_OPENAI_ENDPOINT "
2637ENV_AZURE_OPENAI_KEY = "AZURE_OPENAI_KEY"
2738ENV_AZURE_OPENAI_WHISPER_ENDPOINT = "AZURE_OPENAI_WHISPER_ENDPOINT"
2839ENV_AZURE_OPENAI_WHISPER_KEY = "AZURE_OPENAI_WHISPER_KEY"
@@ -88,22 +99,162 @@ def azure_openai_creds():
8899 "audio_model" : ENV_OPENAI_AUDIO_MODEL ,
89100 }
90101
102+ # openai>=1.0.0 ---------------------------------------------------------------------------
91103
92- def configure_api_type (api_type , whisper = False , ** kwargs ):
104+ @pytest .fixture
105+ def client (api_type ):
106+ if os .getenv (ENV_OPENAI_TEST_MODE , "v1" ) != "v1" :
107+ pytest .skip ("Skipping - tests set to run against v1." )
93108 if api_type == "azure" :
94- if whisper :
95- openai .api_base = os .getenv (ENV_AZURE_OPENAI_WHISPER_ENDPOINT ).rstrip ("/" )
96- openai .api_key = os .getenv (ENV_AZURE_OPENAI_WHISPER_KEY )
97- else :
98- openai .api_base = os .getenv (ENV_AZURE_OPENAI_ENDPOINT ).rstrip ("/" )
99- openai .api_key = os .getenv (ENV_AZURE_OPENAI_KEY )
109+ client = openai .AzureOpenAI (
110+ azure_endpoint = os .getenv (ENV_AZURE_OPENAI_ENDPOINT ),
111+ api_key = os .getenv (ENV_AZURE_OPENAI_KEY ),
112+ api_version = ENV_AZURE_OPENAI_API_VERSION ,
113+ )
114+ elif api_type == "azuread" :
115+ client = openai .AzureOpenAI (
116+ azure_endpoint = os .getenv (ENV_AZURE_OPENAI_ENDPOINT ),
117+ azure_ad_token_provider = get_bearer_token_provider (DefaultAzureCredential (), "https://cognitiveservices.azure.com/.default" ),
118+ api_version = ENV_AZURE_OPENAI_API_VERSION ,
119+ )
120+ elif api_type == "openai" :
121+ client = openai .OpenAI (
122+ api_key = os .getenv (ENV_OPENAI_KEY )
123+ )
124+ elif api_type == "whisper_azure" :
125+ client = openai .AzureOpenAI (
126+ azure_endpoint = os .getenv (ENV_AZURE_OPENAI_WHISPER_ENDPOINT ),
127+ api_key = os .getenv (ENV_AZURE_OPENAI_WHISPER_KEY ),
128+ api_version = ENV_AZURE_OPENAI_API_VERSION ,
129+ )
130+ elif api_type == "whisper_azuread" :
131+ client = openai .AzureOpenAI (
132+ azure_endpoint = os .getenv (ENV_AZURE_OPENAI_WHISPER_ENDPOINT ),
133+ azure_ad_token_provider = get_bearer_token_provider (DefaultAzureCredential (), "https://cognitiveservices.azure.com/.default" ),
134+ api_version = ENV_AZURE_OPENAI_API_VERSION ,
135+ )
136+
137+ return client
138+
139+
140+ @pytest .fixture
141+ def client_async (api_type ):
142+ if os .getenv (ENV_OPENAI_TEST_MODE , "v1" ) != "v1" :
143+ pytest .skip ("Skipping - tests set to run against v1." )
144+ if api_type == "azure" :
145+ client = openai .AsyncAzureOpenAI (
146+ azure_endpoint = os .getenv (ENV_AZURE_OPENAI_ENDPOINT ),
147+ api_key = os .getenv (ENV_AZURE_OPENAI_KEY ),
148+ api_version = ENV_AZURE_OPENAI_API_VERSION ,
149+ )
150+ elif api_type == "azuread" :
151+ client = openai .AsyncAzureOpenAI (
152+ azure_endpoint = os .getenv (ENV_AZURE_OPENAI_ENDPOINT ),
153+ azure_ad_token_provider = get_bearer_token_provider_async (AsyncDefaultAzureCredential (), "https://cognitiveservices.azure.com/.default" ),
154+ api_version = ENV_AZURE_OPENAI_API_VERSION ,
155+ )
156+ elif api_type == "openai" :
157+ client = openai .AsyncOpenAI (
158+ api_key = os .getenv (ENV_OPENAI_KEY )
159+ )
160+ elif api_type == "whisper_azure" :
161+ client = openai .AsyncAzureOpenAI (
162+ azure_endpoint = os .getenv (ENV_AZURE_OPENAI_WHISPER_ENDPOINT ),
163+ api_key = os .getenv (ENV_AZURE_OPENAI_WHISPER_KEY ),
164+ api_version = ENV_AZURE_OPENAI_API_VERSION ,
165+ )
166+ elif api_type == "whisper_azuread" :
167+ client = openai .AsyncAzureOpenAI (
168+ azure_endpoint = os .getenv (ENV_AZURE_OPENAI_WHISPER_ENDPOINT ),
169+ azure_ad_token_provider = get_bearer_token_provider_async (AsyncDefaultAzureCredential (), "https://cognitiveservices.azure.com/.default" ),
170+ api_version = ENV_AZURE_OPENAI_API_VERSION ,
171+ )
172+
173+ return client
174+
175+
176+ def build_kwargs (args , api_type ):
177+ test_feature = args [0 ].qualified_test_name
178+ if test_feature .startswith ("test_audio" ):
179+ if api_type in ["whisper_azure" , "whisper_azuread" ]:
180+ return {"model" : ENV_AZURE_OPENAI_AUDIO_NAME }
181+ elif api_type == "openai" :
182+ return {"model" : ENV_OPENAI_AUDIO_MODEL }
183+ if test_feature .startswith ("test_chat_completions" ) \
184+ or test_feature .startswith (("test_client" , "test_models" )):
185+ if api_type in ["azure" , "azuread" ]:
186+ return {"model" : ENV_AZURE_OPENAI_CHAT_COMPLETIONS_NAME }
187+ elif api_type == "openai" :
188+ return {"model" : ENV_OPENAI_CHAT_COMPLETIONS_MODEL }
189+ if test_feature .startswith ("test_completions" ):
190+ if api_type in ["azure" , "azuread" ]:
191+ return {"model" : ENV_AZURE_OPENAI_COMPLETIONS_NAME }
192+ elif api_type == "openai" :
193+ return {"model" : ENV_OPENAI_COMPLETIONS_MODEL }
194+ if test_feature .startswith ("test_embeddings" ):
195+ if api_type in ["azure" , "azuread" ]:
196+ return {"model" : ENV_AZURE_OPENAI_EMBEDDINGS_NAME }
197+ elif api_type == "openai" :
198+ return {"model" : ENV_OPENAI_EMBEDDINGS_MODEL }
199+ if test_feature .startswith (("test_dall_e" , "test_module_client" , "test_cli" )):
200+ return {}
201+ raise ValueError (f"Test feature: { test_feature } needs to have its kwargs configured." )
202+
203+
204+ def configure_async (f ):
205+ @functools .wraps (f )
206+ async def wrapper (* args , ** kwargs ):
207+ api_type = kwargs .pop ("api_type" )
208+ client_async = kwargs .pop ("client_async" )
209+ azure_openai_creds = kwargs .pop ("azure_openai_creds" )
210+ kwargs = build_kwargs (args , api_type )
211+ try :
212+ return await f (* args , client_async = client_async , azure_openai_creds = azure_openai_creds , api_type = api_type , ** kwargs )
213+ except openai .RateLimitError :
214+ pytest .skip (f"{ str (f ).split (' ' )[1 ]} [{ api_type } ]: Skipping - Rate limit reached." )
215+
216+ return wrapper
217+
218+
219+ def configure (f ):
220+ @functools .wraps (f )
221+ def wrapper (* args , ** kwargs ):
222+ api_type = kwargs .pop ("api_type" )
223+ client = kwargs .pop ("client" )
224+ azure_openai_creds = kwargs .pop ("azure_openai_creds" )
225+ kwargs = build_kwargs (args , api_type )
226+ try :
227+ return f (* args , client = client , azure_openai_creds = azure_openai_creds , api_type = api_type , ** kwargs )
228+ except openai .RateLimitError :
229+ pytest .skip (f"{ str (f ).split (' ' )[1 ]} [{ api_type } ]: Skipping - Rate limit reached." )
230+
231+ return wrapper
232+
233+
234+
235+ @contextlib .contextmanager
236+ def reload ():
237+ try :
238+ importlib .reload (openai )
239+ yield
240+ finally :
241+ importlib .reload (openai )
242+
243+
244+ # openai<1.0.0 ---------------------------------------------------------------------------
245+
246+ @pytest .fixture
247+ def set_vars (api_type ):
248+ if os .getenv (ENV_OPENAI_TEST_MODE , "v1" ) != "v0" :
249+ pytest .skip ("Skipping - tests set to run against v0." )
250+
251+ if api_type == "azure" :
252+ openai .api_base = os .getenv (ENV_AZURE_OPENAI_ENDPOINT ).rstrip ("/" )
253+ openai .api_key = os .getenv (ENV_AZURE_OPENAI_KEY )
100254 openai .api_type = "azure"
101255 openai .api_version = ENV_AZURE_OPENAI_API_VERSION
102256 elif api_type == "azuread" :
103- if whisper :
104- openai .api_base = os .getenv (ENV_AZURE_OPENAI_WHISPER_ENDPOINT ).rstrip ("/" )
105- else :
106- openai .api_base = os .getenv (ENV_AZURE_OPENAI_ENDPOINT ).rstrip ("/" )
257+ openai .api_base = os .getenv (ENV_AZURE_OPENAI_ENDPOINT ).rstrip ("/" )
107258 credential = DefaultAzureCredential ()
108259 token = credential .get_token ("https://cognitiveservices.azure.com/.default" )
109260 openai .api_type = "azuread"
@@ -114,30 +265,42 @@ def configure_api_type(api_type, whisper=False, **kwargs):
114265 openai .api_type = "openai"
115266 openai .api_key = os .getenv (ENV_OPENAI_KEY )
116267 openai .api_version = None
268+ elif api_type == "whisper_azure" :
269+ openai .api_base = os .getenv (ENV_AZURE_OPENAI_WHISPER_ENDPOINT ).rstrip ("/" )
270+ openai .api_key = os .getenv (ENV_AZURE_OPENAI_WHISPER_KEY )
271+ openai .api_type = "azure"
272+ openai .api_version = ENV_AZURE_OPENAI_API_VERSION
273+ elif api_type == "whisper_azuread" :
274+ openai .api_base = os .getenv (ENV_AZURE_OPENAI_WHISPER_ENDPOINT ).rstrip ("/" )
275+ credential = DefaultAzureCredential ()
276+ token = credential .get_token ("https://cognitiveservices.azure.com/.default" )
277+ openai .api_type = "azuread"
278+ openai .api_key = token .token
279+ openai .api_version = ENV_AZURE_OPENAI_API_VERSION
117280
118281
119- def configure_async (f ):
282+ def configure_v0_async (f ):
120283 @functools .wraps (f )
121284 async def wrapper (* args , ** kwargs ):
122285 api_type = kwargs .pop ("api_type" )
123- whisper = args [ 0 ]. qualified_test_name . startswith ( "test_audio " )
124- configure_api_type ( api_type , whisper = whisper , ** kwargs )
286+ set_vars = kwargs . pop ( "set_vars " )
287+ azure_openai_creds = kwargs . pop ( "azure_openai_creds" )
125288 try :
126- return await f (* args , api_type = api_type , ** kwargs )
289+ return await f (* args , set_vars = set_vars , azure_openai_creds = azure_openai_creds , api_type = api_type , ** kwargs )
127290 except openai .error .RateLimitError :
128291 pytest .skip (f"{ str (f ).split (' ' )[1 ]} [{ api_type } ]: Skipping - Rate limit reached." )
129292
130293 return wrapper
131294
132295
133- def configure (f ):
296+ def configure_v0 (f ):
134297 @functools .wraps (f )
135298 def wrapper (* args , ** kwargs ):
136299 api_type = kwargs .pop ("api_type" )
137- whisper = args [ 0 ]. qualified_test_name . startswith ( "test_audio " )
138- configure_api_type ( api_type , whisper = whisper , ** kwargs )
300+ set_vars = kwargs . pop ( "set_vars " )
301+ azure_openai_creds = kwargs . pop ( "azure_openai_creds" )
139302 try :
140- return f (* args , api_type = api_type , ** kwargs )
303+ return f (* args , set_vars = set_vars , azure_openai_creds = azure_openai_creds , api_type = api_type , ** kwargs )
141304 except openai .error .RateLimitError :
142305 pytest .skip (f"{ str (f ).split (' ' )[1 ]} [{ api_type } ]: Skipping - Rate limit reached." )
143306
0 commit comments