|
|
import httpx |
|
|
from fastapi import FastAPI, Request, HTTPException |
|
|
from fastapi.responses import StreamingResponse |
|
|
import json |
|
|
import random |
|
|
import logging |
|
|
import ipaddress |
|
|
|
|
|
|
|
|
logging.basicConfig( |
|
|
level=logging.INFO, |
|
|
format="%(asctime)s - %(levelname)s - %(message)s", |
|
|
datefmt="%Y-%m-%d %H:%M:%S", |
|
|
) |
|
|
|
|
|
app = FastAPI() |
|
|
|
|
|
|
|
|
API_URLS = [ |
|
|
"https://api.deepinfra.com/v1/openai/chat/completions", |
|
|
"https://stage.api.deepinfra.com/v1/openai/chat/completions", |
|
|
] |
|
|
|
|
|
|
|
|
USER_AGENTS = [ |
|
|
|
|
|
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36", |
|
|
|
|
|
"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:132.0) Gecko/20100101 Firefox/132.0", |
|
|
|
|
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 14_5) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.5 Safari/605.1.15", |
|
|
|
|
|
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0", |
|
|
|
|
|
"Mozilla/5.0 (Linux; Android 14; Pixel 7 Pro) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Mobile Safari/537.36", |
|
|
|
|
|
"Mozilla/5.0 (iPhone; CPU iPhone OS 17_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.5 Mobile/15E148 Safari/604.1", |
|
|
] |
|
|
|
|
|
def generate_random_ip() -> str: |
|
|
"""Generate a random IPv4 address, avoiding reserved ranges.""" |
|
|
while True: |
|
|
ip = ipaddress.IPv4Address(random.getrandbits(32)) |
|
|
if not (ip.is_private or ip.is_multicast or ip.is_reserved or ip.is_loopback): |
|
|
return str(ip) |
|
|
|
|
|
@app.post("/v1/openai/chat/completions") |
|
|
async def proxy_deepinfra(request: Request): |
|
|
""" |
|
|
Proxies chat completion requests to the DeepInfra API. |
|
|
Randomizes API URLs, spoofed random IP, fake headers, and User-Agent rotation. |
|
|
""" |
|
|
try: |
|
|
body = await request.json() |
|
|
except json.JSONDecodeError: |
|
|
raise HTTPException(status_code=400, detail="Invalid JSON in request body") |
|
|
|
|
|
|
|
|
random_ip = generate_random_ip() |
|
|
user_agent = random.choice(USER_AGENTS) |
|
|
|
|
|
headers = { |
|
|
|
|
|
"User-Agent": user_agent, |
|
|
"accept": "text/event-stream", |
|
|
"sec-ch-ua": '"Chromium";v="140", "Not=A?Brand";v="24", "Google Chrome";v="140"', |
|
|
"sec-ch-ua-mobile": "?0", |
|
|
"sec-ch-ua-platform": '"Windows"', |
|
|
"Referer": "https://deepinfra.com/", |
|
|
"Origin": "https://deepinfra.com", |
|
|
|
|
|
|
|
|
"X-Forwarded-For": random_ip, |
|
|
"X-Real-IP": random_ip, |
|
|
"Forwarded": f"for={random_ip};proto=https", |
|
|
|
|
|
|
|
|
"DNT": "1", |
|
|
"Pragma": "no-cache", |
|
|
"Cache-Control": "no-cache", |
|
|
"Accept-Encoding": "gzip, deflate, br, zstd", |
|
|
"Accept-Language": "en-US,en;q=0.9,fr;q=0.8,de;q=0.7", |
|
|
"Upgrade-Insecure-Requests": "1", |
|
|
"Sec-Fetch-Dest": "document", |
|
|
"Sec-Fetch-Mode": "navigate", |
|
|
"Sec-Fetch-Site": "none", |
|
|
"Sec-Fetch-User": "?1", |
|
|
|
|
|
|
|
|
"X-Deepinfra-Source": request.headers.get("X-Deepinfra-Source", "web-embed"), |
|
|
"Content-Type": "application/json", |
|
|
} |
|
|
|
|
|
shuffled_urls = random.sample(API_URLS, len(API_URLS)) |
|
|
|
|
|
async def stream_generator(): |
|
|
last_error = None |
|
|
for url in shuffled_urls: |
|
|
logging.info( |
|
|
f"Attempting to connect to: {url} with spoofed IP {random_ip} and UA {user_agent}" |
|
|
) |
|
|
try: |
|
|
async with httpx.AsyncClient() as client: |
|
|
async with client.stream( |
|
|
"POST", url, headers=headers, json=body, timeout=None |
|
|
) as response: |
|
|
response.raise_for_status() |
|
|
logging.info(f"Successfully connected. Streaming from: {url}") |
|
|
async for chunk in response.aiter_bytes(): |
|
|
yield chunk |
|
|
return |
|
|
except (httpx.RequestError, httpx.HTTPStatusError) as e: |
|
|
last_error = e |
|
|
logging.warning( |
|
|
f"Failed to connect to {url}: {e}. Trying next URL." |
|
|
) |
|
|
continue |
|
|
if last_error: |
|
|
logging.error(f"All API endpoints failed. Last error: {last_error}") |
|
|
|
|
|
return StreamingResponse(stream_generator(), media_type="text-event-stream") |
|
|
|