Skip to content

Commit 2045839

Browse files
committed
streamline api and providers specification
1 parent 6303b12 commit 2045839

File tree

4 files changed

+68
-88
lines changed

4 files changed

+68
-88
lines changed

oneping/curl.py

Lines changed: 23 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@
55
import requests
66
import aiohttp
77

8-
from .providers import (
9-
get_provider, get_embed_provider, convert_history, DEFAULT_MAX_TOKENS
10-
)
8+
from .providers import get_provider, convert_history, DEFAULT_MAX_TOKENS
119

1210
##
1311
## printing
@@ -25,11 +23,15 @@ def print_dryrun(url, headers, payload):
2523
## payloads
2624
##
2725

28-
def prepare_url(prov, url=None, host=None, port=None):
29-
host = prov.get('host') if host is None else host
30-
port = prov.get('port') if port is None else port
31-
url = prov.get('url') if url is None else url
32-
return url.format(host=host, port=port)
26+
def prepare_url(prov, path_key, base_url=None, path=None):
27+
base_url = prov.get('base_url') if base_url is None else base_url
28+
path = prov.get(path_key) if path is None else path
29+
return f'{base_url}/{path}'
30+
31+
def prepare_model(prov, model_key, model=None):
32+
if model is None:
33+
model = prov.get(model_key)
34+
return {'model': model} if model is not None else {}
3335

3436
def prepare_auth(prov, api_key=None):
3537
if (auth_func := prov.get('authorize')) is not None:
@@ -40,20 +42,15 @@ def prepare_auth(prov, api_key=None):
4042
headers_auth = {}
4143
return headers_auth
4244

43-
def prepare_model(prov, model=None):
44-
if model is None:
45-
model = prov.get('model')
46-
return {'model': model} if model is not None else {}
47-
4845
def prepare_request(
4946
query, provider='local', system=None, image=None, prefill=None, prediction=None, history=None,
50-
url=None, host=None, port=None, api_key=None, model=None, max_tokens=DEFAULT_MAX_TOKENS, **kwargs
47+
base_url=None, path=None, api_key=None, model=None, max_tokens=DEFAULT_MAX_TOKENS, **kwargs
5148
):
5249
# external provider details
5350
prov = get_provider(provider)
54-
max_tokens_name = prov.get('max_tokens_name', 'max_tokens')
55-
url = prepare_url(prov, url=url, host=host, port=port)
56-
payload_model = prepare_model(prov, model=model)
51+
max_tokens_name = prov.get('max_tokens_name', 'max_completion_tokens')
52+
url = prepare_url(prov, 'chat_path', base_url=base_url, path=path)
53+
payload_model = prepare_model(prov, 'chat_model', model=model)
5754

5855
# convert history to provider format
5956
history = convert_history(history, prov['content'])
@@ -225,27 +222,27 @@ async def stream_async(query, provider='local', history=None, prefill=None, **kw
225222
## embeddings
226223
##
227224

228-
def embed(text, provider='local', url=None, port=None, api_key=None, model=None, **kwargs):
225+
def embed(text, provider='local', base_url=None, path=None, api_key=None, model=None, **kwargs):
229226
# get provider details
230-
prov = get_embed_provider(provider)
231-
url = prepare_url(prov, url=url, port=port)
232-
extractor = prov['embed']
227+
prov = get_provider(provider)
228+
url = prepare_url(prov, 'embed_path', base_url=base_url, path=path)
229+
payload_model = prepare_model(prov, 'embed_model', model=model)
233230

234-
# get extra headers and model
231+
# get extra headers
235232
headers_auth = prepare_auth(prov, api_key=api_key)
236-
payload_model = prepare_model(prov, model=model)
233+
headers_extra = prov.get('headers', {})
237234

238235
# compose request
239-
headers = {'Content-Type': 'application/json', **headers_auth}
240-
payload = {'input': text, **payload_model}
236+
headers = {'Content-Type': 'application/json', **headers_auth, **headers_extra}
237+
payload = {'input': text, **payload_model, **kwargs}
241238

242239
# make the request
243240
response = requests.post(url, headers=headers, data=json.dumps(payload))
244241
response.raise_for_status()
245242

246243
# extract text
247244
data = response.json()
248-
vecs = extractor(data)
245+
vecs = prov['embed'](data)
249246

250247
# return text
251248
return vecs

oneping/native/__init__.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ def make_client(provider, **kwargs):
160160
else:
161161
raise Exception(f'Provider {provider} not found')
162162

163-
def reply(query, provider, **kwargs):
163+
def reply(query, provider, port=None, **kwargs):
164164
if provider == 'openai':
165165
return reply_openai(query, **kwargs)
166166
elif provider == 'anthropic':
@@ -178,7 +178,7 @@ def reply(query, provider, **kwargs):
178178
else:
179179
raise Exception(f'Provider {provider} not found')
180180

181-
def reply_async(query, provider, **kwargs):
181+
def reply_async(query, provider, port=None, **kwargs):
182182
if provider == 'openai':
183183
return reply_async_openai(query, **kwargs)
184184
elif provider == 'anthropic':
@@ -196,7 +196,7 @@ def reply_async(query, provider, **kwargs):
196196
else:
197197
raise Exception(f'Provider {provider} not found')
198198

199-
def stream(query, provider, **kwargs):
199+
def stream(query, provider, port=None, **kwargs):
200200
if provider == 'openai':
201201
return stream_openai(query, **kwargs)
202202
elif provider == 'anthropic':
@@ -214,7 +214,7 @@ def stream(query, provider, **kwargs):
214214
else:
215215
raise Exception(f'Provider {provider} not found')
216216

217-
def stream_async(query, provider, **kwargs):
217+
def stream_async(query, provider, port=None, **kwargs):
218218
if provider == 'openai':
219219
return stream_async_openai(query, **kwargs)
220220
elif provider == 'anthropic':
@@ -232,7 +232,7 @@ def stream_async(query, provider, **kwargs):
232232
else:
233233
raise Exception(f'Provider {provider} not found')
234234

235-
def embed(text, provider, **kwargs):
235+
def embed(text, provider, port=None, **kwargs):
236236
if provider == 'openai':
237237
return embed_openai(text, **kwargs)
238238
elif provider == 'azure':
@@ -244,7 +244,7 @@ def embed(text, provider, **kwargs):
244244
else:
245245
raise Exception(f'Provider {provider} does not support embeddings')
246246

247-
def transcribe(audio, provider, **kwargs):
247+
def transcribe(audio, provider, port=None, **kwargs):
248248
if provider == 'openai':
249249
return transcribe_openai(audio, **kwargs)
250250
elif provider == 'azure':

oneping/native/openai.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import openai
55

66
from ..providers import (
7-
DEFAULT_SYSTEM, OPENAI_MODEL, OPENAI_EMBED, OPENAI_WHISPER, OPENAI_KEYENV,
7+
DEFAULT_SYSTEM, OPENAI_MODEL, OPENAI_EMBED, OPENAI_TRANSCRIBE, OPENAI_KEYENV,
88
content_openai, convert_history, payload_openai,
99
response_openai_native, stream_openai_native,
1010
embed_openai, transcribe_openai
@@ -59,7 +59,7 @@ def embed(query, model=OPENAI_EMBED, api_key=None, **kwargs):
5959
response = client.embeddings.create(model=model, **kwargs)
6060
return embed_openai(response)
6161

62-
def transcribe(audio, model=OPENAI_WHISPER, api_key=None, **kwargs):
62+
def transcribe(audio, model=OPENAI_TRANSCRIBE, api_key=None, **kwargs):
6363
client = make_client(api_key=api_key)
6464
response = client.audio.transcriptions.create(model=model, **kwargs)
6565
return transcribe_openai(response)

oneping/providers.py

Lines changed: 37 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@
1313
## models
1414
##
1515

16-
OPENAI_MODEL = 'gpt-4o'
17-
OPENAI_EMBED = 'text-embedding-3-small'
18-
OPENAI_WHISPER = 'whisper-1'
19-
ANTHROPIC_MODEL = 'claude-3-5-sonnet-latest'
16+
OPENAI_MODEL = 'gpt-4.1'
17+
OPENAI_EMBED = 'text-embedding-3-large'
18+
OPENAI_TRANSCRIBE = 'gpt-4o-transcribe'
19+
ANTHROPIC_MODEL = 'claude-3-7-sonnet-latest'
2020
FIREWORKS_MODEL = 'accounts/fireworks/models/llama-v3p3-70b-instruct'
2121
GROQ_MODEL = 'llama-3.3-70b-versatile'
2222
DEEPSEEK_MODEL = 'deepseek-chat'
@@ -42,7 +42,6 @@
4242
AZURE_API_VERSION = '2024-10-21'
4343
ANTHROPIC_HEADERS = {
4444
'anthropic-version': '2023-06-01',
45-
'anthropic-beta': 'prompt-caching-2024-07-31',
4645
}
4746

4847
##
@@ -131,7 +130,11 @@ def payload_anthropic(content, system=None, prefill=None, prediction=None, histo
131130
messages.append({'role': 'assistant', 'content': prefill})
132131
payload = {'messages': messages}
133132
if system is not None:
134-
payload['system'] = system
133+
payload['system'] = [{
134+
'text': system,
135+
'type': 'text',
136+
'cache_control': {'type': 'ephemeral'},
137+
}]
135138
return payload
136139

137140
def payload_oneping(content, system=None, prefill=None, prediction=None, history=None):
@@ -212,6 +215,10 @@ def transcribe_openai(audio):
212215
##
213216

214217
DEFAULT_PROVIDER = {
218+
'chat_path': 'chat/completions',
219+
'embed_path': 'embeddings',
220+
'transcribe_path': 'audio/transcriptions',
221+
'authorize': authorize_openai,
215222
'content': content_openai,
216223
'payload': payload_openai,
217224
'response': response_openai,
@@ -222,86 +229,62 @@ def transcribe_openai(audio):
222229
# presets for known llm providers
223230
LLM_PROVIDERS = {
224231
'local': {
225-
'url': 'http://{host}:{port}/v1/chat/completions',
226-
'host': 'localhost',
227-
'port': 8000,
232+
'base_url': 'http://localhost:8000/v1',
233+
'authorize': None,
228234
},
229235
'oneping': {
230-
'url': 'http://{host}:{port}/chat',
231-
'host': 'localhost',
232-
'port': 5000,
236+
'base_url': 'http://localhost:5000',
237+
'chat_path': 'chat',
233238
'authorize': None,
239+
'max_tokens_name': 'max_tokens',
234240
'content': content_oneping,
235241
'payload': payload_oneping,
236242
'response': response_oneping,
237243
'stream': stream_oneping,
238244
},
239245
'openai': {
240-
'url': 'https://api.openai.com/v1/chat/completions',
241-
'authorize': authorize_openai,
242-
'max_tokens_name': 'max_completion_tokens',
246+
'base_url': 'https://api.openai.com/v1',
243247
'api_key_env': OPENAI_KEYENV,
244-
'model': OPENAI_MODEL,
248+
'chat_model': OPENAI_MODEL,
249+
'embed_model': OPENAI_EMBED,
245250
},
246251
'anthropic': {
247-
'url': 'https://api.anthropic.com/v1/messages',
252+
'base_url': 'https://api.anthropic.com/v1',
253+
'chat_path': 'messages',
254+
'max_tokens_name': 'max_tokens',
248255
'content': content_anthropic,
249256
'payload': payload_anthropic,
250257
'authorize': authorize_anthropic,
251258
'response': response_anthropic,
252259
'stream': stream_anthropic,
253260
'api_key_env': ANTHROPIC_KEYENV,
254-
'model': ANTHROPIC_MODEL,
261+
'chat_model': ANTHROPIC_MODEL,
255262
'headers': ANTHROPIC_HEADERS,
256263
},
264+
'google': {
265+
'base_url': 'https://generativelanguage.googleapis.com/v1beta/openai',
266+
'api_key_env': GOOGLE_KEYENV,
267+
'chat_model': GOOGLE_MODEL,
268+
'embed_model': GOOGLE_EMBED,
269+
},
257270
'fireworks': {
258-
'url': 'https://api.fireworks.ai/inference/v1/chat/completions',
259-
'authorize': authorize_openai,
271+
'base_url': 'https://api.fireworks.ai/inference',
260272
'api_key_env': FIREWORKS_KEYENV,
261-
'model': FIREWORKS_MODEL,
273+
'chat_model': FIREWORKS_MODEL,
262274
},
263275
'groq': {
264-
'url': 'https://api.groq.com/openai/v1/chat/completions',
265-
'authorize': authorize_openai,
266-
'max_tokens_name': 'max_completion_tokens',
276+
'base_url': 'https://api.groq.com/openai',
267277
'api_key_env': GROQ_KEYENV,
268-
'model': GROQ_MODEL,
278+
'chat_model': GROQ_MODEL,
269279
},
270280
'deepseek': {
271-
'url': 'https://api.deepseek.com/chat/completions',
272-
'authorize': authorize_openai,
281+
'base_url': 'https://api.deepseek.com',
273282
'api_key_env': DEEPSEEK_KEYENV,
274-
'model': DEEPSEEK_MODEL,
283+
'chat_model': DEEPSEEK_MODEL,
275284
},
276285
}
277286

278287
def get_provider(provider):
279288
if type(provider) is str:
280289
provider = LLM_PROVIDERS[provider]
281290
return {**DEFAULT_PROVIDER, **provider}
282-
283-
##
284-
## embedding providers
285-
##
286-
287-
DEFAULT_EMBED = {
288-
'authorize': authorize_openai,
289-
'embed': embed_openai,
290-
}
291-
292-
EMBED_PROVIDERS = {
293-
'local': {
294-
'url': 'http://{host}:{port}/v1/embeddings',
295-
'authorize': None,
296-
},
297-
'openai': {
298-
'url': 'https://api.openai.com/v1/embeddings',
299-
'api_key_env': 'OPENAI_API_KEY',
300-
'model': 'text-embedding-3-small',
301-
},
302-
}
303-
304-
def get_embed_provider(provider):
305-
if type(provider) is str:
306-
provider = EMBED_PROVIDERS[provider]
307-
return {**DEFAULT_EMBED, **provider}

0 commit comments

Comments
 (0)