9
from dotenv import load_dotenv
14
async def generate_key(session, models=[]):
15
url = "http://0.0.0.0:4000/key/generate"
16
headers = {"Authorization": "Bearer sk-1234", "Content-Type": "application/json"}
22
async with session.post(url, headers=headers, json=data) as response:
23
status = response.status
24
response_text = await response.text()
30
raise Exception(f"Request did not return a 200 status code: {status}")
31
return await response.json()
34
async def get_models(session, key):
35
url = "http://0.0.0.0:4000/models"
37
"Authorization": f"Bearer {key}",
38
"Content-Type": "application/json",
41
async with session.get(url, headers=headers) as response:
42
status = response.status
43
response_text = await response.text()
44
print("response from /models")
49
raise Exception(f"Request did not return a 200 status code: {status}")
53
async def test_get_models():
54
async with aiohttp.ClientSession() as session:
55
key_gen = await generate_key(session=session)
57
await get_models(session=session, key=key)
60
async def add_models(session, model_id="123", model_name="azure-gpt-3.5"):
61
url = "http://0.0.0.0:4000/model/new"
63
"Authorization": f"Bearer sk-1234",
64
"Content-Type": "application/json",
68
"model_name": model_name,
70
"model": "azure/chatgpt-v-2",
71
"api_key": "os.environ/AZURE_API_KEY",
72
"api_base": "https://openai-gpt-4-test-v-1.openai.azure.com/",
73
"api_version": "2023-05-15",
75
"model_info": {"id": model_id},
78
async with session.post(url, headers=headers, json=data) as response:
79
status = response.status
80
response_text = await response.text()
81
print(f"Add models {response_text}")
85
raise Exception(f"Request did not return a 200 status code: {status}")
87
response_json = await response.json()
91
async def get_model_info(session, key):
93
Make sure only models user has access to are returned
95
url = "http://0.0.0.0:4000/model/info"
97
"Authorization": f"Bearer {key}",
98
"Content-Type": "application/json",
101
async with session.get(url, headers=headers) as response:
102
status = response.status
103
response_text = await response.text()
108
raise Exception(f"Request did not return a 200 status code: {status}")
109
return await response.json()
112
async def chat_completion(session, key, model="azure-gpt-3.5"):
113
url = "http://0.0.0.0:4000/chat/completions"
115
"Authorization": f"Bearer {key}",
116
"Content-Type": "application/json",
121
{"role": "system", "content": "You are a helpful assistant."},
122
{"role": "user", "content": "Hello!"},
126
async with session.post(url, headers=headers, json=data) as response:
127
status = response.status
128
response_text = await response.text()
134
raise Exception(f"Request did not return a 200 status code: {status}")
138
async def test_get_models():
140
Get models user has access to
142
async with aiohttp.ClientSession() as session:
143
key_gen = await generate_key(session=session, models=["gpt-4"])
145
response = await get_model_info(session=session, key=key)
146
models = [m["model_name"] for m in response["data"]]
151
async def delete_model(session, model_id="123"):
153
Make sure only models user has access to are returned
155
url = "http://0.0.0.0:4000/model/delete"
157
"Authorization": f"Bearer sk-1234",
158
"Content-Type": "application/json",
160
data = {"id": model_id}
162
async with session.post(url, headers=headers, json=data) as response:
163
status = response.status
164
response_text = await response.text()
169
raise Exception(f"Request did not return a 200 status code: {status}")
170
return await response.json()
174
async def test_add_and_delete_models():
177
- Call new model -> expect to pass
179
- Call model -> expect to fail
183
async with aiohttp.ClientSession() as session:
184
key_gen = await generate_key(session=session)
186
model_id = f"12345_{uuid.uuid4()}"
187
model_name = f"{uuid.uuid4()}"
188
response = await add_models(
189
session=session, model_id=model_id, model_name=model_name
191
assert response["model_id"] == model_id
192
await asyncio.sleep(10)
193
await chat_completion(session=session, key=key, model=model_name)
194
await delete_model(session=session, model_id=model_id)
196
await chat_completion(session=session, key=key, model=model_name)
197
pytest.fail(f"Expected call to fail.")
202
async def add_model_for_health_checking(session, model_id="123"):
203
url = "http://0.0.0.0:4000/model/new"
205
"Authorization": f"Bearer sk-1234",
206
"Content-Type": "application/json",
210
"model_name": f"azure-model-health-check-{model_id}",
212
"model": "azure/chatgpt-v-2",
213
"api_key": os.getenv("AZURE_API_KEY"),
214
"api_base": "https://openai-gpt-4-test-v-1.openai.azure.com/",
215
"api_version": "2023-05-15",
217
"model_info": {"id": model_id},
220
async with session.post(url, headers=headers, json=data) as response:
221
status = response.status
222
response_text = await response.text()
224
print(f"Add models {response_text}")
228
raise Exception(f"Request did not return a 200 status code: {status}")
231
async def get_model_info_v2(session, key):
232
url = "http://0.0.0.0:4000/v2/model/info"
234
"Authorization": f"Bearer {key}",
235
"Content-Type": "application/json",
238
async with session.get(url, headers=headers) as response:
239
status = response.status
240
response_text = await response.text()
241
print("response from v2/model/info")
246
raise Exception(f"Request did not return a 200 status code: {status}")
249
async def get_specific_model_info_v2(session, key, model_name):
250
url = "http://0.0.0.0:4000/v2/model/info?debug=True&model=" + model_name
251
print("running /model/info check for model=", model_name)
254
"Authorization": f"Bearer {key}",
255
"Content-Type": "application/json",
258
async with session.get(url, headers=headers) as response:
259
status = response.status
260
response_text = await response.text()
261
print("response from v2/model/info")
265
_json_response = await response.json()
266
print("JSON response from /v2/model/info?model=", model_name, _json_response)
268
_model_info = _json_response["data"]
269
assert len(_model_info) == 1, f"Expected 1 model, got {len(_model_info)}"
272
raise Exception(f"Request did not return a 200 status code: {status}")
273
return _model_info[0]
276
async def get_model_health(session, key, model_name):
277
url = "http://0.0.0.0:4000/health?model=" + model_name
279
"Authorization": f"Bearer {key}",
280
"Content-Type": "application/json",
283
async with session.get(url, headers=headers) as response:
284
status = response.status
285
response_text = await response.json()
286
print("response from /health?model=", model_name)
291
raise Exception(f"Request did not return a 200 status code: {status}")
296
async def test_add_model_run_health():
299
Call /model/info and v2/model/info
300
-> Admin UI calls v2/model/info
301
Call /chat/completions
303
-> Ensure the health check for the endpoint is working as expected
307
async with aiohttp.ClientSession() as session:
308
key_gen = await generate_key(session=session)
310
master_key = "sk-1234"
311
model_id = str(uuid.uuid4())
312
model_name = f"azure-model-health-check-{model_id}"
313
print("adding model", model_name)
314
await add_model_for_health_checking(session=session, model_id=model_id)
315
_old_model_info = await get_specific_model_info_v2(
316
session=session, key=key, model_name=model_name
318
print("model info before test", _old_model_info)
320
await asyncio.sleep(30)
321
print("calling /model/info")
322
await get_model_info(session=session, key=key)
323
print("calling v2/model/info")
324
await get_model_info_v2(session=session, key=key)
326
print("calling /chat/completions -> expect to work")
327
await chat_completion(session=session, key=key, model=model_name)
329
print("calling /health?model=", model_name)
330
_health_info = await get_model_health(
331
session=session, key=master_key, model_name=model_name
333
_healthy_endpooint = _health_info["healthy_endpoints"][0]
335
assert _health_info["healthy_count"] == 1
337
_healthy_endpooint["model"] == "azure/chatgpt-v-2"
342
await asyncio.sleep(10)
344
_model_info_after_test = await get_specific_model_info_v2(
345
session=session, key=key, model_name=model_name
348
print("model info after test", _model_info_after_test)
349
old_openai_client = _old_model_info["openai_client"]
350
new_openai_client = _model_info_after_test["openai_client"]
351
print("old openai client", old_openai_client)
352
print("new openai client", new_openai_client)
355
PROD TEST - This is extremly important
356
The OpenAI client used should be the same after 30 seconds
357
It is a serious bug if the openai client does not match here
360
old_openai_client == new_openai_client
361
), "OpenAI client does not match for the same model after 30 seconds"
364
await delete_model(session=session, model_id=model_id)