-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapi_client.py
More file actions
126 lines (99 loc) · 3.68 KB
/
api_client.py
File metadata and controls
126 lines (99 loc) · 3.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import httpx
import os
from typing import (Optional, Dict, Union, List)
from pydantic import (BaseModel, validator)
from .errors import InfuzuAPIError
class ModelWeights(BaseModel):
price: Optional[float] = None
error: Optional[float] = None
start_latency: Optional[float] = None
end_latency: Optional[float] = None
class Config:
extra: str = "allow"
class InfuzuModelParams(BaseModel):
llms: Optional[List[str]] = None
exclude_llms: Optional[List[str]] = None
weights: Optional[ModelWeights] = None
imsn: Optional[int] = None
max_input_cost: Optional[float] = None
max_output_cost: Optional[float] = None
class Config:
extra: str = "allow"
class ChatCompletionsRequestContentPart(BaseModel):
type: str
text: Optional[str] = None
image_url: Optional[str] = None
input_audio: Optional[str] = None
class Config:
extra: str = "allow"
@validator("text", always=True)
def check_content_fields(cls, value, values):
if "type" in values:
content_type = values["type"]
if content_type == "text" and value is None:
raise ValueError("Text must be provided when type is 'text'")
if content_type != "text" and value is not None:
raise ValueError("Text cannot be provided when type is not 'text'")
return value
class ChatCompletionsHandlerRequestMessage(BaseModel):
content: Union[str, List[ChatCompletionsRequestContentPart]]
role: str
name: Optional[str] = None
class Config:
extra: str = "allow"
@validator('role')
def role_must_be_valid(cls, v):
if v not in ('system', 'user', 'assistant'):
raise ValueError('Role must be one of: system, user, assistant')
return v
API_BASE_URL = "https://chat.infuzu.com/api"
def create_chat_completion(
messages: List[ChatCompletionsHandlerRequestMessage],
api_key: Optional[str] = None,
model: Optional[Union[str, InfuzuModelParams]] = None,
) -> Dict:
"""
Creates a chat completion using the Infuzu API.
Args:
messages: A list of message objects.
api_key: Your Infuzu API key. If not provided, it will be read from the
INFUZU_API_KEY environment variable.
model: The model to use for the chat completion. Can be a string (model name)
or a InfuzuModelParams object for more advanced configuration.
Returns:
A dictionary containing the JSON response from the API.
Raises:
ValueError: If the API key is not provided and the INFUZU_API_KEY
environment variable is not set.
httpx.HTTPStatusError: If the API request returns an error status code.
"""
if api_key is None:
api_key = os.environ.get("INFUZU_API_KEY")
if api_key is None:
raise ValueError(
"API key not provided and INFUZU_API_KEY environment variable not set."
)
headers = {
"Content-Type": "application/json",
"Infuzu-API-Key": api_key,
}
payload = {
"messages": [message.dict(by_alias=True) for message in messages],
}
if model:
if isinstance(model, str):
payload["model"] = model
else:
payload["model"] = model.dict(by_alias=True)
try:
with httpx.Client() as client:
response = client.post(
f"{API_BASE_URL}/v1/chat/completions",
headers=headers,
json=payload,
timeout=600
)
response.raise_for_status()
return response.json()
except httpx.HTTPStatusError as e:
raise InfuzuAPIError(e)