api/endpoints/ai.py

89 lines
3.4 KiB
Python
Raw Normal View History

2024-08-14 22:43:20 -04:00
import logging
import regex
2025-02-14 16:07:24 -05:00
from regex import Pattern
from typing import Union
2024-08-14 22:43:20 -04:00
from aiohttp import ClientSession, ClientTimeout
2025-02-15 21:09:33 -05:00
from fastapi import FastAPI, Request, HTTPException
from fastapi.responses import JSONResponse
2025-01-11 20:59:10 -05:00
2024-08-14 22:43:20 -04:00
class AI(FastAPI):
2025-01-11 20:59:10 -05:00
"""AI Endpoints"""
2025-02-15 21:09:33 -05:00
def __init__(self, app: FastAPI,
2025-02-16 08:50:53 -05:00
my_util, constants):
2025-02-15 21:09:33 -05:00
self.app: FastAPI = app
2024-08-14 22:43:20 -04:00
self.util = my_util
self.constants = constants
2025-02-14 16:07:24 -05:00
self.url_clean_regex: Pattern = regex.compile(r'^\/ai\/(openai|base)\/')
self.endpoints: dict = {
2024-11-14 14:37:32 -05:00
"ai/openai": self.ai_openai_handler,
"ai/base": self.ai_handler,
2024-08-14 22:43:20 -04:00
#tbd
2025-01-11 20:59:10 -05:00
}
2024-08-14 22:43:20 -04:00
for endpoint, handler in self.endpoints.items():
2025-01-29 15:48:47 -05:00
app.add_api_route(f"/{endpoint}", handler, methods=["GET", "POST"],
include_in_schema=False)
2024-10-02 20:54:34 -04:00
2025-02-15 21:09:33 -05:00
async def ai_handler(self, request: Request) -> JSONResponse:
2024-11-14 14:37:32 -05:00
"""
/ai/base
2024-11-14 14:37:32 -05:00
AI BASE Request
2024-11-29 15:33:12 -05:00
(Requires key)
2024-11-14 14:37:32 -05:00
"""
2025-01-11 20:59:10 -05:00
2024-11-14 14:37:32 -05:00
if not self.util.check_key(request.url.path, request.headers.get('X-Authd-With')):
raise HTTPException(status_code=403, detail="Unauthorized")
2024-10-02 20:54:34 -04:00
2024-11-14 14:37:32 -05:00
local_llm_headers = {
'Authorization': f'Bearer {self.constants.LOCAL_LLM_KEY}'
}
2025-01-11 20:59:10 -05:00
2024-11-14 14:37:32 -05:00
forward_path = self.url_clean_regex.sub('', request.url.path)
try:
2025-01-11 20:59:10 -05:00
async with ClientSession() as session:
async with await session.post(f'{self.constants.LOCAL_LLM_BASE}/{forward_path}',
json=await request.json(),
headers=local_llm_headers,
timeout=ClientTimeout(connect=15, sock_read=30)) as out_request:
response = await out_request.json()
2025-02-15 21:09:33 -05:00
return JSONResponse(content=response)
2025-02-16 08:50:53 -05:00
except Exception as e:
2025-01-11 20:59:10 -05:00
logging.error("Error: %s", e)
2025-02-15 21:09:33 -05:00
return JSONResponse(status_code=500, content={
2025-01-11 20:59:10 -05:00
'err': True,
'errorText': 'General Failure'
2025-02-15 21:09:33 -05:00
})
2025-01-11 20:59:10 -05:00
2025-02-15 21:09:33 -05:00
async def ai_openai_handler(self, request: Request) -> JSONResponse:
2024-11-14 14:37:32 -05:00
"""
/ai/openai
2024-11-14 14:37:32 -05:00
AI Request
2024-11-29 15:33:12 -05:00
(Requires key)
2024-11-14 14:37:32 -05:00
"""
2025-01-11 20:59:10 -05:00
2024-11-14 14:37:32 -05:00
if not self.util.check_key(request.url.path, request.headers.get('X-Authd-With')):
raise HTTPException(status_code=403, detail="Unauthorized")
2024-08-14 22:43:20 -04:00
2024-11-14 14:37:32 -05:00
"""
TODO: Implement Claude
Currently only routes to local LLM
"""
2025-01-11 20:59:10 -05:00
2024-11-14 14:37:32 -05:00
local_llm_headers = {
'Authorization': f'Bearer {self.constants.LOCAL_LLM_KEY}'
}
forward_path = self.url_clean_regex.sub('', request.url.path)
try:
2025-01-11 20:59:10 -05:00
async with ClientSession() as session:
async with await session.post(f'{self.constants.LOCAL_LLM_HOST}/{forward_path}',
json=await request.json(),
headers=local_llm_headers,
timeout=ClientTimeout(connect=15, sock_read=30)) as out_request:
response = await out_request.json()
2025-02-15 21:09:33 -05:00
return JSONResponse(content=response)
2025-02-16 08:50:53 -05:00
except Exception as e:
2025-01-11 20:59:10 -05:00
logging.error("Error: %s", e)
2025-02-15 21:09:33 -05:00
return JSONResponse(status_code=500, content={
2025-01-11 20:59:10 -05:00
'err': True,
'errorText': 'General Failure'
2025-02-15 21:09:33 -05:00
})