Skip to content

Commit be1d9ca

Browse files
committed
adding signal handlers on backend
1 parent 94140f9 commit be1d9ca

File tree

1 file changed

+66
-53
lines changed

1 file changed

+66
-53
lines changed

backend/restapi_server.py

Lines changed: 66 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
1-
#
2-
# Copyright (C) 2024 RapidSilicon
3-
# Authorized use only
4-
#
51
import argparse
62
import os
73
import sys
4+
import signal
85
from flask import Flask, request, jsonify
96
from flasgger import Swagger
107
from submodule.rs_device_manager import RsDeviceManager
@@ -19,72 +16,88 @@
1916
from api.utils import attrs_api
2017
from api.project import project_api
2118

22-
#
23-
# Main entry point
24-
#
19+
# Create Flask app
20+
app = Flask(__name__)
21+
app.url_map.strict_slashes = False
22+
23+
# Set up Swagger for API documentation
24+
swagger_template = {
25+
"swagger": "2.0",
26+
"info": {
27+
"title": "RPE Backend API",
28+
"description": "The RPE Backend APIs consumed by the RPE frontend for power and thermal estimation of Rapid Silicon devices.",
29+
"version": "0.1.0"
30+
}
31+
}
32+
swagger = Swagger(app, template=swagger_template)
33+
34+
# Register API blueprints with the Flask app
35+
app.register_blueprint(device_api)
36+
app.register_blueprint(clock_api)
37+
app.register_blueprint(dsp_api)
38+
app.register_blueprint(fabric_le_api)
39+
app.register_blueprint(bram_api)
40+
app.register_blueprint(io_api)
41+
app.register_blueprint(peripherals_api)
42+
app.register_blueprint(attrs_api)
43+
app.register_blueprint(project_api)
44+
45+
# Hook up request signal to log requests from the UI
46+
@app.before_request
47+
def before_request():
48+
log(f"{request.method} {request.url}")
49+
50+
@app.after_request
51+
def after_request(response):
52+
log(f"{request.method} {request.url} {response.status_code} - DONE")
53+
return response
54+
55+
# Graceful shutdown function
56+
def shutdown_server():
57+
log("Shutting down server...")
58+
func = request.environ.get('werkzeug.server.shutdown')
59+
if func is not None:
60+
func()
61+
else:
62+
log("Server shutdown function not found.", RsLogLevel.ERROR)
63+
64+
# Signal handler for smooth shutdown
65+
def signal_handler(signal_received, frame):
66+
log(f"Signal {signal_received} received, initiating shutdown...")
67+
shutdown_server()
68+
sys.exit(0)
69+
70+
# Register the signal handler for SIGINT (Ctrl+C) and SIGTERM
71+
signal.signal(signal.SIGINT, signal_handler)
72+
signal.signal(signal.SIGTERM, signal_handler)
73+
2574
def main():
26-
# create and parse command line args
27-
parser = argparse.ArgumentParser(description='Rapid Power Estimator Rest API Server command-line arguments.')
28-
parser.add_argument('device_file', type=str, help='Path to the input device xml file')
75+
# Parse command-line arguments
76+
parser = argparse.ArgumentParser(description='Rapid Power Estimator REST API Server command-line arguments.')
77+
parser.add_argument('device_file', type=str, help='Path to the input device XML file')
2978
parser.add_argument('--port', type=int, default=5000, help='Specify TCP Port to use for REST server')
3079
parser.add_argument('--debug', default=False, action='store_true', help='Enable/Disable debug mode')
3180
parser.add_argument('--logfile', type=str, default="rpe.log", help='Specify log file name')
32-
parser.add_argument('--maxbytes', type=int, default=2048, help='Specify maximun log file size in kilobytes before rollover')
33-
parser.add_argument('--backupcount', type=int, default=20, help='Specify no. of backup log files')
81+
parser.add_argument('--maxbytes', type=int, default=2048, help='Specify maximum log file size in kilobytes before rollover')
82+
parser.add_argument('--backupcount', type=int, default=20, help='Specify number of backup log files')
3483
args = parser.parse_args()
3584

36-
# setup app logger
37-
log_setup(filename=args.logfile, max_bytes=args.maxbytes*1024, backup_count=args.backupcount)
85+
# Set up logger
86+
log_setup(filename=args.logfile, max_bytes=args.maxbytes * 1024, backup_count=args.backupcount)
3887

3988
# Check if the device_file exists
40-
if os.path.exists(args.device_file) == False:
89+
if not os.path.exists(args.device_file):
4190
log(f"Device file '{args.device_file}' does not exist.", RsLogLevel.ERROR)
4291
sys.exit(1)
4392

4493
# Parse Device XML file into Device List
4594
devicemanager = RsDeviceManager.get_instance()
4695
devicemanager.load_xml(args.device_file)
4796

48-
# create flask app object
49-
app = Flask(__name__)
50-
app.url_map.strict_slashes = False
51-
52-
# auto generate restapi documentation
53-
template = {
54-
"swagger": "2.0",
55-
"info": {
56-
"title": "RPE Backend API",
57-
"description": "The RPE Backend APIs which consumed by the RPE frontend for power and thermal estimation of the Rapid Silicon devices.",
58-
"version": "0.1.0"
59-
}
60-
}
61-
swagger = Swagger(app, template=template)
62-
63-
# bind device api objects onto the flask app
64-
app.register_blueprint(device_api)
65-
app.register_blueprint(clock_api)
66-
app.register_blueprint(dsp_api)
67-
app.register_blueprint(fabric_le_api)
68-
app.register_blueprint(bram_api)
69-
app.register_blueprint(io_api)
70-
app.register_blueprint(peripherals_api)
71-
app.register_blueprint(attrs_api)
72-
app.register_blueprint(project_api)
73-
74-
# hook up request signal to log request by UI
75-
@app.before_request
76-
def before_request():
77-
log(f"{request.method} {request.url}")
78-
79-
@app.after_request
80-
def after_request(response):
81-
log(f"{request.method} {request.url} {response.status_code} - DONE")
82-
return response
83-
84-
# log app server started
97+
# Log server start message
8598
log("App server is running...")
8699

87-
# Start Rest API server
100+
# Start the Flask app
88101
app.run(debug=args.debug, port=args.port)
89102

90103
if __name__ == "__main__":

0 commit comments

Comments
 (0)