rkihacker commited on
Commit
6b64125
·
verified ·
1 Parent(s): 9214547

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +19 -5
main.py CHANGED
@@ -4,6 +4,7 @@ from fastapi.responses import StreamingResponse
4
  import json
5
  import random
6
  import logging
 
7
 
8
  # Configure logging to output to stdout
9
  logging.basicConfig(
@@ -20,26 +21,42 @@ API_URLS = [
20
  "https://stage.api.deepinfra.com/v1/openai/chat/completions",
21
  ]
22
 
 
 
 
 
 
 
 
23
  @app.post("/v1/openai/chat/completions")
24
  async def proxy_deepinfra(request: Request):
25
  """
26
  Proxies chat completion requests to the DeepInfra API.
27
  It randomizes the order of API URLs and uses the next as a fallback.
 
28
  """
29
  try:
30
  body = await request.json()
31
  except json.JSONDecodeError:
32
  raise HTTPException(status_code=400, detail="Invalid JSON in request body")
33
 
 
 
 
34
  headers = {
35
  'sec-ch-ua-platform': request.headers.get('sec-ch-ua-platform', '"Windows"'),
36
  'Referer': request.headers.get('Referer', 'https://deepinfra.com/'),
37
  'sec-ch-ua': request.headers.get('sec-ch-ua', '"Chromium";v="140", "Not=A?Brand";v="24", "Google Chrome";v="140"'),
38
  'sec-ch-ua-mobile': request.headers.get('sec-ch-ua-mobile', '?0'),
39
  'User-Agent': request.headers.get('User-Agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36'),
40
- 'accept': request.headers.get('accept', 'text-event-stream'),
41
  'X-Deepinfra-Source': request.headers.get('X-Deepinfra-Source', 'web-embed'),
42
  'Content-Type': request.headers.get('Content-Type', 'application/json'),
 
 
 
 
 
43
  }
44
 
45
  shuffled_urls = random.sample(API_URLS, len(API_URLS))
@@ -47,7 +64,7 @@ async def proxy_deepinfra(request: Request):
47
  async def stream_generator():
48
  last_error = None
49
  for url in shuffled_urls:
50
- logging.info(f"Attempting to connect to: {url}")
51
  try:
52
  async with httpx.AsyncClient() as client:
53
  async with client.stream("POST", url, headers=headers, json=body, timeout=None) as response:
@@ -60,12 +77,9 @@ async def proxy_deepinfra(request: Request):
60
  last_error = e
61
  logging.warning(f"Failed to connect to {url}: {e}. Trying next URL.")
62
  continue
63
-
64
  if last_error:
65
  logging.error(f"All API endpoints failed. Last error: {last_error}")
66
  # In a streaming response, we can't easily raise an HTTPException after starting.
67
  # The connection will simply close, which the client will see as a failed request.
68
 
69
  return StreamingResponse(stream_generator(), media_type="text-event-stream")
70
-
71
- # The `if __name__ == "__main__":` block is removed as Gunicorn will run the app.
 
4
  import json
5
  import random
6
  import logging
7
+ import ipaddress
8
 
9
  # Configure logging to output to stdout
10
  logging.basicConfig(
 
21
  "https://stage.api.deepinfra.com/v1/openai/chat/completions",
22
  ]
23
 
24
+ def generate_random_ip() -> str:
25
+ """Generate a random IPv4 address, avoiding reserved ranges."""
26
+ while True:
27
+ ip = ipaddress.IPv4Address(random.getrandbits(32))
28
+ if not (ip.is_private or ip.is_multicast or ip.is_reserved or ip.is_loopback):
29
+ return str(ip)
30
+
31
  @app.post("/v1/openai/chat/completions")
32
  async def proxy_deepinfra(request: Request):
33
  """
34
  Proxies chat completion requests to the DeepInfra API.
35
  It randomizes the order of API URLs and uses the next as a fallback.
36
+ Adds spoofed random IP headers.
37
  """
38
  try:
39
  body = await request.json()
40
  except json.JSONDecodeError:
41
  raise HTTPException(status_code=400, detail="Invalid JSON in request body")
42
 
43
+ # Generate a random spoofed IP
44
+ random_ip = generate_random_ip()
45
+
46
  headers = {
47
  'sec-ch-ua-platform': request.headers.get('sec-ch-ua-platform', '"Windows"'),
48
  'Referer': request.headers.get('Referer', 'https://deepinfra.com/'),
49
  'sec-ch-ua': request.headers.get('sec-ch-ua', '"Chromium";v="140", "Not=A?Brand";v="24", "Google Chrome";v="140"'),
50
  'sec-ch-ua-mobile': request.headers.get('sec-ch-ua-mobile', '?0'),
51
  'User-Agent': request.headers.get('User-Agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36'),
52
+ 'accept': request.headers.get('accept', 'text/event-stream'),
53
  'X-Deepinfra-Source': request.headers.get('X-Deepinfra-Source', 'web-embed'),
54
  'Content-Type': request.headers.get('Content-Type', 'application/json'),
55
+
56
+ # Spoofed IP headers
57
+ 'X-Forwarded-For': random_ip,
58
+ 'X-Real-IP': random_ip,
59
+ 'Forwarded': f'for={random_ip};proto=https',
60
  }
61
 
62
  shuffled_urls = random.sample(API_URLS, len(API_URLS))
 
64
  async def stream_generator():
65
  last_error = None
66
  for url in shuffled_urls:
67
+ logging.info(f"Attempting to connect to: {url} with spoofed IP {random_ip}")
68
  try:
69
  async with httpx.AsyncClient() as client:
70
  async with client.stream("POST", url, headers=headers, json=body, timeout=None) as response:
 
77
  last_error = e
78
  logging.warning(f"Failed to connect to {url}: {e}. Trying next URL.")
79
  continue
 
80
  if last_error:
81
  logging.error(f"All API endpoints failed. Last error: {last_error}")
82
  # In a streaming response, we can't easily raise an HTTPException after starting.
83
  # The connection will simply close, which the client will see as a failed request.
84
 
85
  return StreamingResponse(stream_generator(), media_type="text-event-stream")