File size: 3,349 Bytes
14f29a8
3d1cd49
14f29a8
 
 
3d1cd49
 
 
 
14f29a8
3d1cd49
 
 
7d3733b
 
3d1cd49
 
14f29a8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3d1cd49
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14f29a8
 
 
 
 
 
301d461
3d1cd49
 
 
 
 
 
 
 
301d461
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3d1cd49
 
 
 
301d461
14f29a8
3d1cd49
301d461
 
 
66723c5
 
301d461
 
3d1cd49
 
 
85ec322
3d1cd49
 
 
eb00981
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
from flask import Flask, request, Response, stream_with_context, jsonify
import requests
import random
import os
from functools import wraps

app = Flask(__name__)

# Target API base URL
TARGET_API = "https://openrouter.ai"

# Path mappings
PATH_MAPPINGS = {
    "/api/v1/chat": "/api/v1/chat",
    "/api/v1/models": "/api/v1/models"
}

# Get API keys from environment variable
def get_api_keys():
    api_keys_str = os.environ.get('API_KEYS', '')
    if not api_keys_str:
        return []
    return [key.strip() for key in api_keys_str.split(',') if key.strip()]

# Get authentication token from environment variable
AUTH_TOKEN = os.environ.get('AUTH_TOKEN', '666')

# Authentication decorator for POST requests
def require_auth(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if request.method == 'POST':
            auth_header = request.headers.get('Authorization')
            if not auth_header or auth_header != f"Bearer {AUTH_TOKEN}":
                return jsonify({"error": "Unauthorized"}), 401
        return f(*args, **kwargs)
    return decorated_function


@app.route('/<path:path>', methods=['GET', 'POST'])
@require_auth
def proxy(path):
    # Construct the full path
    full_path = f"/{path}"

    # Apply path mapping if matches
    for original_path, new_path in PATH_MAPPINGS.items():
        if full_path.startswith(original_path):
            full_path = full_path.replace(original_path, new_path, 1)
            break

    # Construct target URL
    target_url = f"{TARGET_API}{full_path}"

    # Forward the request to the target API
    headers = {key: value for key, value in request.headers if key != 'Host'}

    # Get API keys and select a random one if available
    api_keys = get_api_keys()
    if api_keys:
        random_key = random.choice(api_keys)
        headers['Authorization'] = f"Bearer {random_key}"

    # Handle POST requests with streaming
    if request.method == 'POST':
        response = requests.post(
            target_url,
            headers=headers,
            json=request.get_json(silent=True),
            params=request.args,
            stream=True
        )

        # Create a streaming response for POST
        def generate():
            for chunk in response.iter_content(chunk_size=8192):
                yield chunk

        # Create flask streaming response
        proxy_response = Response(
            stream_with_context(generate()),
            status=response.status_code
        )
        # Forward response headers
        for key, value in response.headers.items():
            if key.lower() not in ('content-length', 'transfer-encoding', 'connection'):
                proxy_response.headers[key] = value
    
        return proxy_response

    # Handle GET requests without streaming
    elif request.method == 'GET':
        response = requests.get(
            target_url,
            headers=headers,
            params=request.args
        )

        # Create a regular response for GET
        proxy_response = Response(
            response.content,
            status=response.status_code,
            mimetype=response.headers.get('Content-Type')
        )
        return proxy_response

@app.route('/', methods=['GET'])
def index():
    return "APP is running."


if __name__ == '__main__':
    app.run(host='0.0.0.0', port=7860)