| 1 | import threading |
| 2 | from flask import Flask, request |
| 3 | from helpers import runtime, dotenv, process |
| 4 | from helpers.print_style import PrintStyle |
| 5 | |
| 6 | from api.tunnel import Tunnel, stop |
| 7 | |
| 8 | # initialize the internal Flask server |
| 9 | app = Flask("app") |
| 10 | app.config["JSON_SORT_KEYS"] = False # Disable key sorting in jsonify |
| 11 | |
| 12 | |
| 13 | def run(): |
| 14 | # Suppress only request logs but keep the startup messages |
| 15 | from werkzeug.serving import WSGIRequestHandler |
| 16 | from werkzeug.serving import make_server |
| 17 | |
| 18 | PrintStyle().print("Starting tunnel server...") |
| 19 | |
| 20 | class NoRequestLoggingWSGIRequestHandler(WSGIRequestHandler): |
| 21 | def log_request(self, code="-", size="-"): |
| 22 | pass # Override to suppress request logging |
| 23 | |
| 24 | # Get configuration from environment |
| 25 | tunnel_api_port = runtime.get_tunnel_api_port() |
| 26 | host = ( |
| 27 | runtime.get_arg("host") or dotenv.get_dotenv_value("WEB_UI_HOST") or "localhost" |
| 28 | ) |
| 29 | server = None |
| 30 | lock = threading.Lock() |
| 31 | tunnel = Tunnel(app, lock) |
| 32 | |
| 33 | # handle api request |
| 34 | @app.route("/", methods=["POST"]) |
| 35 | async def handle_request(): |
| 36 | return await tunnel.handle_request(request=request) # type: ignore |
| 37 | |
| 38 | try: |
| 39 | server = make_server( |
| 40 | host=host, |
| 41 | port=tunnel_api_port, |
| 42 | app=app, |
| 43 | request_handler=NoRequestLoggingWSGIRequestHandler, |
| 44 | threaded=True, |
| 45 | ) |
| 46 | |
| 47 | process.set_server(server) |
| 48 | # server.log_startup() |
| 49 | server.serve_forever() |
| 50 | finally: |
| 51 | # Clean up tunnel if it was started |
| 52 | if tunnel: |
| 53 | stop() |
| 54 | |
| 55 | |
| 56 | # run the internal server |
| 57 | if __name__ == "__main__": |
| 58 | runtime.initialize() |
| 59 | dotenv.load_dotenv() |
| 60 | run() |