gnilets commited on
Commit
31c4c6a
·
verified ·
1 Parent(s): 71806d4

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +14 -28
app.py CHANGED
@@ -2,7 +2,6 @@ from datetime import datetime, timedelta
2
  from functools import partial
3
  from os import environ
4
  from typing import Callable, Coroutine
5
- from itertools import chain
6
 
7
  from anyio import create_task_group
8
  from fastapi import FastAPI, HTTPException, Request
@@ -11,8 +10,7 @@ from fastapi.responses import StreamingResponse
11
  from httpx import AsyncClient, RequestError, Timeout
12
  from starlette.types import Receive, Scope, Send
13
 
14
- API_KEYS = ['bad_key'] + [line for line in environ['API_KEYS'].strip().split('\n') if line and line.startswith('sk-')]
15
- print(f'всего ключей: {len(API_KEYS)}')
16
  COMPLETIONS_URL = 'https://openrouter.ai/api/v1/chat/completions'
17
  app = FastAPI(title='reverse-proxy')
18
 
@@ -119,44 +117,32 @@ async def proxy_openai_api(request: Request):
119
  streaming = client.stream(request.method, COMPLETIONS_URL, headers=headers, params=request.query_params, json=request_body)
120
  async with streaming as stream_response:
121
  if stream_response.status_code in {401, 402, 429}:
122
- print(api_key, 'не валиден')
123
- yield 'auth_error'
124
- return
125
  if stream_response.status_code == 403:
126
- raise CensoredError('отклонено по цензуре')
127
-
 
 
128
  async for chunk in stream_response.aiter_bytes():
129
  if chunk.strip():
130
  yield chunk.strip()
 
131
 
132
  except RequestError as exc:
133
  raise HTTPException(status_code=500, detail=f'произошла ошибка при запросе: {exc}')
134
 
135
- async def get_response(headers: dict) -> OverrideStreamResponse:
136
  for api_key in API_KEYS:
137
- response_generator = stream_api_response(api_key)
138
  try:
139
- first_chunk = await anext(response_generator)
140
- if first_chunk == 'auth_error':
141
- print(f'ключ API {api_key} недействителен или превышен лимит отправки запросов')
142
- continue
143
- else:
144
- headers_to_forward = {k: v for k, v in headers.items() if k.lower() not in {'content-length', 'content-encoding', 'alt-svc'}}
145
-
146
- async def combined_generator():
147
- if first_chunk.strip():
148
- yield first_chunk.strip() + b'\n'
149
- async for chunk in response_generator:
150
- if chunk.strip():
151
- yield chunk.strip() + b'\n'
152
-
153
- return OverrideStreamResponse(combined_generator(), headers=headers_to_forward)
154
- except StopAsyncIteration:
155
  continue
156
  raise HTTPException(status_code=401, detail='все ключи API использованы, доступ запрещен.')
157
 
158
-
159
- return await get_response(headers)
160
 
161
 
162
  @cache_results
 
2
  from functools import partial
3
  from os import environ
4
  from typing import Callable, Coroutine
 
5
 
6
  from anyio import create_task_group
7
  from fastapi import FastAPI, HTTPException, Request
 
10
  from httpx import AsyncClient, RequestError, Timeout
11
  from starlette.types import Receive, Scope, Send
12
 
13
+ API_KEYS = [line for line in environ['API_KEYS'].strip().split('\n') if line and line.startswith('sk-')]
 
14
  COMPLETIONS_URL = 'https://openrouter.ai/api/v1/chat/completions'
15
  app = FastAPI(title='reverse-proxy')
16
 
 
117
  streaming = client.stream(request.method, COMPLETIONS_URL, headers=headers, params=request.query_params, json=request_body)
118
  async with streaming as stream_response:
119
  if stream_response.status_code in {401, 402, 429}:
120
+ raise AuthError('ключ API недействителен или превышен лимит отправки запросов')
 
 
121
  if stream_response.status_code == 403:
122
+ raise CensoredError('отклонено по цензуре') # это специфичная ошибка именно для опенроутера!
123
+ response.init_headers({k: v for k, v in stream_response.headers.items() if k not in {'content-length', 'content-encoding', 'alt-svc'}})
124
+
125
+ content = bytearray()
126
  async for chunk in stream_response.aiter_bytes():
127
  if chunk.strip():
128
  yield chunk.strip()
129
+ content.extend(chunk.strip())
130
 
131
  except RequestError as exc:
132
  raise HTTPException(status_code=500, detail=f'произошла ошибка при запросе: {exc}')
133
 
134
+ async def try_api_keys():
135
  for api_key in API_KEYS:
 
136
  try:
137
+ response_generator = stream_api_response(api_key)
138
+ response = OverrideStreamResponse(response_generator)
139
+ return response
140
+ except AuthError:
141
+ print(f'ключ API {api_key} недействителен или превышен лимит отправки запросов')
 
 
 
 
 
 
 
 
 
 
 
142
  continue
143
  raise HTTPException(status_code=401, detail='все ключи API использованы, доступ запрещен.')
144
 
145
+ return await try_api_keys()
 
146
 
147
 
148
  @cache_results