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", } @app.get("/") async def home(): return {"status": "ok", "message": "Simple, non-streaming OpenAI proxy is working."} @app.api_route("/{endpoint:path}", methods=["GET", "POST", "PUT", "PATCH", "DELETE"]) 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)