main.py 2.96 KB
Newer Older
1
from flask import Flask, request, Response, jsonify
Timothy J. Baek's avatar
Timothy J. Baek committed
2
3
4
5
6
7
8
from flask_cors import CORS


import requests
import json


9
10
from apps.web.models.users import Users
from constants import ERROR_MESSAGES
Timothy J. Baek's avatar
Timothy J. Baek committed
11
from utils.utils import extract_token_from_auth_header
12
from config import OLLAMA_API_BASE_URL, WEBUI_AUTH
Timothy J. Baek's avatar
Timothy J. Baek committed
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

app = Flask(__name__)
CORS(
    app
)  # Enable Cross-Origin Resource Sharing (CORS) to allow requests from different domains

# Define the target server URL
TARGET_SERVER_URL = OLLAMA_API_BASE_URL


@app.route("/", defaults={"path": ""}, methods=["GET", "POST", "PUT", "DELETE"])
@app.route("/<path:path>", methods=["GET", "POST", "PUT", "DELETE"])
def proxy(path):
    # Combine the base URL of the target server with the requested path
    target_url = f"{TARGET_SERVER_URL}/{path}"
Timothy J. Baek's avatar
Timothy J. Baek committed
28
    print(path)
Timothy J. Baek's avatar
Timothy J. Baek committed
29
30
31
32
33

    # Get data from the original request
    data = request.get_data()
    headers = dict(request.headers)

Timothy J. Baek's avatar
Timothy J. Baek committed
34
    # Basic RBAC support
35
    if WEBUI_AUTH:
36
37
38
39
        if "Authorization" in headers:
            token = extract_token_from_auth_header(headers["Authorization"])
            user = Users.get_user_by_token(token)
            if user:
Timothy J. Baek's avatar
Timothy J. Baek committed
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
                # Only user and admin roles can access
                if user.role in ["user", "admin"]:
                    if path in ["pull", "delete", "push", "copy", "create"]:
                        # Only admin role can perform actions above
                        if user.role == "admin":
                            pass
                        else:
                            return (
                                jsonify({"detail": ERROR_MESSAGES.ACCESS_PROHIBITED}),
                                401,
                            )
                    else:
                        pass
                else:
                    return jsonify({"detail": ERROR_MESSAGES.ACCESS_PROHIBITED}), 401
55
56
57
58
59
60
61
            else:
                return jsonify({"detail": ERROR_MESSAGES.UNAUTHORIZED}), 401
        else:
            return jsonify({"detail": ERROR_MESSAGES.UNAUTHORIZED}), 401
    else:
        pass

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
    try:
        # Make a request to the target server
        target_response = requests.request(
            method=request.method,
            url=target_url,
            data=data,
            headers=headers,
            stream=True,  # Enable streaming for server-sent events
        )

        target_response.raise_for_status()

        # Proxy the target server's response to the client
        def generate():
            for chunk in target_response.iter_content(chunk_size=8192):
                yield chunk

        response = Response(generate(), status=target_response.status_code)

        # Copy headers from the target server's response to the client's response
        for key, value in target_response.headers.items():
            response.headers[key] = value

        return response
    except Exception as e:
        return jsonify({"detail": "Server Connection Error", "message": str(e)}), 400
Timothy J. Baek's avatar
Timothy J. Baek committed
88
89
90
91


if __name__ == "__main__":
    app.run(debug=True)