zephyr-backend/backend.py
2025-06-28 12:10:21 +08:00

118 lines
3.4 KiB
Python

import os
import traceback
from matplotlib import pyplot as plt
from modules import cosmic
from modules import tidi
from modules import saber
from modules import radar
from modules import balloon
from quart import Quart, jsonify, request
from quart_cors import cors
from typing import get_args
import sys
import matplotlib.font_manager as fm
import ping
app = Quart(__name__, static_folder="./res")
app = cors(app, send_origin_wildcard=True, allow_origin="*")
# limit the whole app not to use over 8G ram
# use resource module to do this
# resource.setrlimit(resource.RLIMIT_AS, (8 * 1024 * 1024 * 1024, -1))
plt.switch_backend('agg')
fm.fontManager.addfont("./SimHei.ttf")
with open("./passcode.txt", "r") as f:
code = f.read()
if code:
code = code.strip()
else:
code = "0101"
@app.before_request
def auth():
# check for method
# if it is OPTIONS, do not check for auth
if request.method == "OPTIONS" or not request.path.startswith("/api"):
return
if request.path.startswith("/api/ping"):
return
_code = request.headers.get("Authorization")
if _code != code:
return "Unauthorized", 401
# Global error handler for all exceptions
@app.errorhandler(Exception)
async def handle_exception(e):
"""Global error handler that catches all exceptions"""
# Get the error details
error_class = e.__class__.__name__
error_message = str(e)
# Get stack trace
stack_trace = traceback.format_exc()
# Log the error (you might want to use a proper logger)
print(f"Exception occurred: {error_class} - {error_message}")
print(f"Stack Trace: {stack_trace}")
# Determine appropriate status code
status_code = 500 # Default to internal server error
# Return a consistent error response
response = {
"success": False,
"error": {
"type": 500,
"message": error_message
}
}
# Only include stack trace in debug mode (not in production)
if app.debug:
response["error"]["stack_trace"] = stack_trace.split('\n')
return jsonify(response), status_code
@app.route('/')
async def return_index_html():
return await app.send_static_file("index.html")
@app.route("/<path:path>")
async def index(path):
# check if there is path in static folder
# if not, return index.html
if app.static_folder:
# check if the file exists
if os.path.exists(os.path.join(app.static_folder, path)):
#
return await app.send_static_file(path)
return await app.send_static_file("index.html")
app.register_blueprint(balloon.balloon_module, url_prefix="/api/balloon")
app.register_blueprint(radar.radar_module, url_prefix="/api/radar")
app.register_blueprint(saber.saber_module, url_prefix="/api/saber")
app.register_blueprint(tidi.tidi_module, url_prefix="/api/tidi")
app.register_blueprint(cosmic.cosmic_module, url_prefix="/api/cosmic")
# allow cors
ping.setup_websocket(app)
if __name__ == '__main__':
# get args '--prod'
args = sys.argv
print(os.getcwd())
# read from ENV Z_PORT
env_port = os.getenv("Z_PORT")
port = 5000 if env_port is None else int(env_port)
if 'debug' in args:
app.run("0.0.0.0", port=port, debug=True)
else:
app.run("0.0.0.0", port=port, debug=False)