Update main.py
Browse files
main.py
CHANGED
@@ -46,11 +46,11 @@ ip_rate_limit_store = defaultdict(lambda: {"count": 0, "timestamp": time.time()}
|
|
46 |
async def get_api_key(authorization: str = Header(None)) -> str:
|
47 |
if authorization is None or not authorization.startswith('Bearer '):
|
48 |
logger.warning("Invalid or missing authorization header.")
|
49 |
-
raise HTTPException(status_code=401, detail='Invalid authorization header format')
|
50 |
api_key = authorization[7:]
|
51 |
if api_key not in API_KEYS:
|
52 |
logger.warning(f"Invalid API key attempted: {api_key}")
|
53 |
-
raise HTTPException(status_code=401, detail='Invalid API key')
|
54 |
return api_key
|
55 |
|
56 |
async def rate_limiter(req: Request, api_key: str = Depends(get_api_key)):
|
@@ -61,8 +61,8 @@ async def rate_limiter(req: Request, api_key: str = Depends(get_api_key)):
|
|
61 |
rate_limit_store[api_key] = {"count": 1, "timestamp": current_time}
|
62 |
else:
|
63 |
if rate_limit_store[api_key]["count"] >= RATE_LIMIT:
|
64 |
-
logger.warning(f"Rate limit exceeded for API key: {api_key}")
|
65 |
-
raise HTTPException(status_code=429, detail='Rate limit exceeded for API key')
|
66 |
rate_limit_store[api_key]["count"] += 1
|
67 |
|
68 |
# Rate limiting per IP address
|
@@ -73,7 +73,7 @@ async def rate_limiter(req: Request, api_key: str = Depends(get_api_key)):
|
|
73 |
else:
|
74 |
if ip_rate_limit_store[client_ip]["count"] >= RATE_LIMIT:
|
75 |
logger.warning(f"Rate limit exceeded for IP address: {client_ip}")
|
76 |
-
raise HTTPException(status_code=429, detail='Rate limit exceeded for IP address')
|
77 |
ip_rate_limit_store[client_ip]["count"] += 1
|
78 |
|
79 |
# Custom exception for model not working
|
@@ -225,13 +225,13 @@ class Blackbox:
|
|
225 |
) -> AsyncGenerator[Any, None]:
|
226 |
model = cls.get_model(model)
|
227 |
if model is None:
|
228 |
-
logger.error(f"Model {model} is not available.")
|
229 |
raise ModelNotWorkingException(model)
|
230 |
|
231 |
logger.info(f"Selected model: {model}")
|
232 |
|
233 |
if not cls.working or model not in cls.models:
|
234 |
-
logger.error(f"Model {model} is not working or not supported.")
|
235 |
raise ModelNotWorkingException(model)
|
236 |
|
237 |
headers = {
|
@@ -243,13 +243,13 @@ class Blackbox:
|
|
243 |
"pragma": "no-cache",
|
244 |
"priority": "u=1, i",
|
245 |
"referer": cls.model_referers.get(model, cls.url),
|
246 |
-
"sec-ch-ua": '"Chromium";v="
|
247 |
"sec-ch-ua-mobile": "?0",
|
248 |
"sec-ch-ua-platform": '"Linux"',
|
249 |
"sec-fetch-dest": "empty",
|
250 |
"sec-fetch-mode": "cors",
|
251 |
"sec-fetch-site": "same-origin",
|
252 |
-
"user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/
|
253 |
}
|
254 |
|
255 |
if model in cls.model_prefixes:
|
@@ -324,7 +324,7 @@ class Blackbox:
|
|
324 |
yield ImageResponse(image_url, alt=messages[-1]['content'])
|
325 |
else:
|
326 |
logger.error("Image URL not found in the response.")
|
327 |
-
raise Exception("Image URL not found in the response")
|
328 |
else:
|
329 |
full_response = ""
|
330 |
search_results_json = ""
|
@@ -360,11 +360,11 @@ class Blackbox:
|
|
360 |
except ClientError as ce:
|
361 |
logger.error(f"Client error occurred: {ce}. Retrying attempt {attempt + 1}/{retry_attempts}")
|
362 |
if attempt == retry_attempts - 1:
|
363 |
-
raise HTTPException(status_code=502, detail="Error communicating with the external API.")
|
364 |
except asyncio.TimeoutError:
|
365 |
logger.error(f"Request timed out. Retrying attempt {attempt + 1}/{retry_attempts}")
|
366 |
if attempt == retry_attempts - 1:
|
367 |
-
raise HTTPException(status_code=504, detail="External API request timed out.")
|
368 |
except Exception as e:
|
369 |
logger.error(f"Unexpected error: {e}. Retrying attempt {attempt + 1}/{retry_attempts}")
|
370 |
if attempt == retry_attempts - 1:
|
@@ -440,7 +440,7 @@ async def chat_completions(request: ChatRequest, req: Request, api_key: str = De
|
|
440 |
# Validate that the requested model is available
|
441 |
if request.model not in Blackbox.models and request.model not in Blackbox.model_aliases:
|
442 |
logger.warning(f"Attempt to use unavailable model: {request.model}")
|
443 |
-
raise HTTPException(status_code=400, detail="Requested model is not available.")
|
444 |
|
445 |
# Process the request with actual message content, but don't log it
|
446 |
async_generator = Blackbox.create_async_generator(
|
@@ -525,9 +525,9 @@ async def get_models():
|
|
525 |
return {"data": [{"id": model, "object": "model"} for model in Blackbox.models]}
|
526 |
|
527 |
# Additional endpoints for better functionality
|
528 |
-
@app.get("/v1/health"
|
529 |
-
async def health_check(req: Request
|
530 |
-
logger.info(
|
531 |
return {"status": "ok"}
|
532 |
|
533 |
@app.get("/v1/models/{model}/status")
|
@@ -585,9 +585,9 @@ class CompletionRequest(BaseModel):
|
|
585 |
logit_bias: Optional[Dict[str, float]] = None
|
586 |
user: Optional[str] = None
|
587 |
|
588 |
-
@app.post("/v1/completions"
|
589 |
-
async def completions(request: CompletionRequest, req: Request
|
590 |
-
logger.info(f"Received completion request
|
591 |
|
592 |
try:
|
593 |
# Validate that the requested model is available
|
|
|
46 |
async def get_api_key(authorization: str = Header(None)) -> str:
|
47 |
if authorization is None or not authorization.startswith('Bearer '):
|
48 |
logger.warning("Invalid or missing authorization header.")
|
49 |
+
raise HTTPException(status_code=401, detail='Invalid authorization header format | NiansuhAI')
|
50 |
api_key = authorization[7:]
|
51 |
if api_key not in API_KEYS:
|
52 |
logger.warning(f"Invalid API key attempted: {api_key}")
|
53 |
+
raise HTTPException(status_code=401, detail='Invalid API key | NiansuhAI')
|
54 |
return api_key
|
55 |
|
56 |
async def rate_limiter(req: Request, api_key: str = Depends(get_api_key)):
|
|
|
61 |
rate_limit_store[api_key] = {"count": 1, "timestamp": current_time}
|
62 |
else:
|
63 |
if rate_limit_store[api_key]["count"] >= RATE_LIMIT:
|
64 |
+
logger.warning(f"Rate limit exceeded for API key: {api_key} | NiansuhAI")
|
65 |
+
raise HTTPException(status_code=429, detail='Rate limit exceeded for API key | NiansuhAI')
|
66 |
rate_limit_store[api_key]["count"] += 1
|
67 |
|
68 |
# Rate limiting per IP address
|
|
|
73 |
else:
|
74 |
if ip_rate_limit_store[client_ip]["count"] >= RATE_LIMIT:
|
75 |
logger.warning(f"Rate limit exceeded for IP address: {client_ip}")
|
76 |
+
raise HTTPException(status_code=429, detail='Rate limit exceeded for IP address | NiansuhAI')
|
77 |
ip_rate_limit_store[client_ip]["count"] += 1
|
78 |
|
79 |
# Custom exception for model not working
|
|
|
225 |
) -> AsyncGenerator[Any, None]:
|
226 |
model = cls.get_model(model)
|
227 |
if model is None:
|
228 |
+
logger.error(f"Model {model} is not available. | NiansuhAI")
|
229 |
raise ModelNotWorkingException(model)
|
230 |
|
231 |
logger.info(f"Selected model: {model}")
|
232 |
|
233 |
if not cls.working or model not in cls.models:
|
234 |
+
logger.error(f"Model {model} is not working or not supported. | NiansuhAI")
|
235 |
raise ModelNotWorkingException(model)
|
236 |
|
237 |
headers = {
|
|
|
243 |
"pragma": "no-cache",
|
244 |
"priority": "u=1, i",
|
245 |
"referer": cls.model_referers.get(model, cls.url),
|
246 |
+
"sec-ch-ua": '"Chromium";v="130", "Not=A?Brand";v="99"',
|
247 |
"sec-ch-ua-mobile": "?0",
|
248 |
"sec-ch-ua-platform": '"Linux"',
|
249 |
"sec-fetch-dest": "empty",
|
250 |
"sec-fetch-mode": "cors",
|
251 |
"sec-fetch-site": "same-origin",
|
252 |
+
"user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36",
|
253 |
}
|
254 |
|
255 |
if model in cls.model_prefixes:
|
|
|
324 |
yield ImageResponse(image_url, alt=messages[-1]['content'])
|
325 |
else:
|
326 |
logger.error("Image URL not found in the response.")
|
327 |
+
raise Exception("Image URL not found in the response | NiansuhAI")
|
328 |
else:
|
329 |
full_response = ""
|
330 |
search_results_json = ""
|
|
|
360 |
except ClientError as ce:
|
361 |
logger.error(f"Client error occurred: {ce}. Retrying attempt {attempt + 1}/{retry_attempts}")
|
362 |
if attempt == retry_attempts - 1:
|
363 |
+
raise HTTPException(status_code=502, detail="Error communicating with the external API. | NiansuhAI")
|
364 |
except asyncio.TimeoutError:
|
365 |
logger.error(f"Request timed out. Retrying attempt {attempt + 1}/{retry_attempts}")
|
366 |
if attempt == retry_attempts - 1:
|
367 |
+
raise HTTPException(status_code=504, detail="External API request timed out. | NiansuhAI")
|
368 |
except Exception as e:
|
369 |
logger.error(f"Unexpected error: {e}. Retrying attempt {attempt + 1}/{retry_attempts}")
|
370 |
if attempt == retry_attempts - 1:
|
|
|
440 |
# Validate that the requested model is available
|
441 |
if request.model not in Blackbox.models and request.model not in Blackbox.model_aliases:
|
442 |
logger.warning(f"Attempt to use unavailable model: {request.model}")
|
443 |
+
raise HTTPException(status_code=400, detail="Requested model is not available. | NiansuhAI")
|
444 |
|
445 |
# Process the request with actual message content, but don't log it
|
446 |
async_generator = Blackbox.create_async_generator(
|
|
|
525 |
return {"data": [{"id": model, "object": "model"} for model in Blackbox.models]}
|
526 |
|
527 |
# Additional endpoints for better functionality
|
528 |
+
@app.get("/v1/health")
|
529 |
+
async def health_check(req: Request):
|
530 |
+
logger.info("Health check requested")
|
531 |
return {"status": "ok"}
|
532 |
|
533 |
@app.get("/v1/models/{model}/status")
|
|
|
585 |
logit_bias: Optional[Dict[str, float]] = None
|
586 |
user: Optional[str] = None
|
587 |
|
588 |
+
@app.post("/v1/completions")
|
589 |
+
async def completions(request: CompletionRequest, req: Request):
|
590 |
+
logger.info(f"Received completion request | Model: {request.model}")
|
591 |
|
592 |
try:
|
593 |
# Validate that the requested model is available
|