Spaces:
Paused
Paused
| import os | |
| import httpx | |
| from fastapi import FastAPI, Request, Response | |
| app = FastAPI( | |
| title="Simple OpenAI Proxy", | |
| description="A non-streaming proxy that waits for the full response from OpenAI." | |
| ) | |
| OR_BASE_URL = "https://api.openai.com/v1" | |
| # Создаем один асинхронный клиент на все приложение | |
| # Увеличим таймаут по умолчанию, т.к. генерация может быть долгой | |
| client = httpx.AsyncClient(base_url=OR_BASE_URL, timeout=120.0) | |
| # "Hop-by-hop" заголовки, которые не должны проксироваться. | |
| # Они относятся к конкретному соединению, а не к сообщению в целом. | |
| HOP_BY_HOP_HEADERS = { | |
| "connection", "keep-alive", "proxy-authenticate", "proxy-authorization", | |
| "te", "trailers", "transfer-encoding", "upgrade", | |
| } | |
| async def home(): | |
| return {"status": "ok", "message": "Simple, non-streaming OpenAI proxy is working."} | |
| async def proxy(endpoint: str, request: Request): | |
| try: | |
| # 1. Формируем URL для запроса к OpenAI | |
| url = httpx.URL(path=f"/{endpoint}", query=request.url.query.encode("utf-8")) | |
| # 2. Копируем заголовки и тело из входящего запроса | |
| headers = {k: v for k, v in request.headers.items() if k.lower() != "host"} | |
| body = await request.body() | |
| # 3. Отправляем запрос и ЖДЕМ ПОЛНОГО ОТВЕТА | |
| # Никакого stream=True. Мы ждем, пока `httpx` полностью загрузит ответ. | |
| resp_openai = await client.request( | |
| method=request.method, | |
| url=url, | |
| headers=headers, | |
| content=body | |
| ) | |
| # 4. Фильтруем "hop-by-hop" заголовки из ответа OpenAI | |
| # Все остальные заголовки (Content-Type, openai-*, и т.д.) будут сохранены | |
| response_headers = { | |
| k: v for k, v in resp_openai.headers.items() | |
| if k.lower() not in HOP_BY_HOP_HEADERS | |
| } | |
| # 5. Возвращаем обычный `Response` со всеми данными от OpenAI | |
| # Это не стриминг. Мы возвращаем готовый, полный ответ. | |
| return Response( | |
| content=resp_openai.content, | |
| status_code=resp_openai.status_code, | |
| headers=response_headers | |
| ) | |
| except httpx.RequestError as e: | |
| # Ошибка сети при обращении к OpenAI | |
| return Response(content=f"Error connecting to OpenAI API: {e}", status_code=502) # 502 Bad Gateway | |
| except Exception as e: | |
| # Внутренняя ошибка в самом прокси-сервере | |
| return Response(content=f"Internal proxy error: {e}", status_code=500) |