|
|
from flask import Flask, request, Response, stream_with_context |
|
|
import requests |
|
|
import os |
|
|
import json |
|
|
|
|
|
app = Flask(__name__) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
TARGET_API = os.getenv("TARGET_API", "https://api-inference.huggingface.co") |
|
|
|
|
|
|
|
|
REAL_AUTH_KEY = os.getenv("REAL_AUTH_KEY") |
|
|
|
|
|
|
|
|
PROXY_ACCESS_KEY = os.getenv("PROXY_ACCESS_KEY") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_path_mappings(): |
|
|
mappings_str = os.getenv("PATH_MAPPINGS", '{}') |
|
|
try: |
|
|
return json.loads(mappings_str) |
|
|
except json.JSONDecodeError: |
|
|
print("Warning: Invalid JSON in PATH_MAPPINGS. Using empty mappings.") |
|
|
return {} |
|
|
|
|
|
PATH_MAPPINGS = get_path_mappings() |
|
|
|
|
|
|
|
|
@app.route('/<path:path>', methods=['GET', 'POST', 'PUT', 'DELETE', 'PATCH']) |
|
|
def proxy(path): |
|
|
|
|
|
|
|
|
if not REAL_AUTH_KEY or not PROXY_ACCESS_KEY: |
|
|
error_msg = {"error": "Authentication is not configured on the proxy server."} |
|
|
return Response(json.dumps(error_msg), status=500, mimetype='application/json') |
|
|
|
|
|
|
|
|
auth_header = request.headers.get('Authorization') |
|
|
expected_auth_header = f"Bearer {PROXY_ACCESS_KEY}" |
|
|
|
|
|
|
|
|
if auth_header != expected_auth_header: |
|
|
error_msg = {"error": "Invalid or missing proxy access key."} |
|
|
return Response(json.dumps(error_msg), status=401, mimetype='application/json') |
|
|
|
|
|
|
|
|
full_path = f"/{path}" |
|
|
|
|
|
|
|
|
|
|
|
for original_path, new_path in PATH_MAPPINGS.items(): |
|
|
if full_path == original_path: |
|
|
full_path = new_path |
|
|
break |
|
|
|
|
|
target_url = f"{TARGET_API}{full_path}" |
|
|
|
|
|
|
|
|
|
|
|
headers = {key: value for key, value in request.headers if key.lower() not in ['host', 'authorization']} |
|
|
|
|
|
|
|
|
headers['Authorization'] = f"Bearer {REAL_AUTH_KEY}" |
|
|
|
|
|
|
|
|
try: |
|
|
|
|
|
response = requests.request( |
|
|
method=request.method, |
|
|
url=target_url, |
|
|
headers=headers, |
|
|
params=request.args, |
|
|
data=request.get_data(), |
|
|
stream=True |
|
|
) |
|
|
except requests.exceptions.RequestException as e: |
|
|
error_msg = {"error": f"Failed to connect to target service: {e}"} |
|
|
return Response(json.dumps(error_msg), status=502, mimetype='application/json') |
|
|
|
|
|
|
|
|
|
|
|
def generate(): |
|
|
for chunk in response.iter_content(chunk_size=1): |
|
|
yield chunk |
|
|
|
|
|
|
|
|
proxy_response = Response( |
|
|
stream_with_context(generate()), |
|
|
status=response.status_code |
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection'] |
|
|
for key, value in response.headers.items(): |
|
|
if key.lower() not in excluded_headers: |
|
|
proxy_response.headers[key] = value |
|
|
|
|
|
return proxy_response |
|
|
|
|
|
|
|
|
@app.route('/', methods=['GET']) |
|
|
def index(): |
|
|
return "Proxy service is running." |
|
|
|
|
|
|
|
|
if __name__ == '__main__': |
|
|
|
|
|
app.run(host='0.0.0.0', port=7860, debug=False) |