|
1 | | -# |
2 | | -# Copyright (C) 2024 RapidSilicon |
3 | | -# Authorized use only |
4 | | -# |
5 | 1 | import argparse |
6 | 2 | import os |
7 | 3 | import sys |
| 4 | +import signal |
8 | 5 | from flask import Flask, request, jsonify |
9 | 6 | from flasgger import Swagger |
10 | 7 | from submodule.rs_device_manager import RsDeviceManager |
|
19 | 16 | from api.utils import attrs_api |
20 | 17 | from api.project import project_api |
21 | 18 |
|
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 | + |
25 | 74 | 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') |
29 | 78 | parser.add_argument('--port', type=int, default=5000, help='Specify TCP Port to use for REST server') |
30 | 79 | parser.add_argument('--debug', default=False, action='store_true', help='Enable/Disable debug mode') |
31 | 80 | 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') |
34 | 83 | args = parser.parse_args() |
35 | 84 |
|
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) |
38 | 87 |
|
39 | 88 | # Check if the device_file exists |
40 | | - if os.path.exists(args.device_file) == False: |
| 89 | + if not os.path.exists(args.device_file): |
41 | 90 | log(f"Device file '{args.device_file}' does not exist.", RsLogLevel.ERROR) |
42 | 91 | sys.exit(1) |
43 | 92 |
|
44 | 93 | # Parse Device XML file into Device List |
45 | 94 | devicemanager = RsDeviceManager.get_instance() |
46 | 95 | devicemanager.load_xml(args.device_file) |
47 | 96 |
|
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 |
85 | 98 | log("App server is running...") |
86 | 99 |
|
87 | | - # Start Rest API server |
| 100 | + # Start the Flask app |
88 | 101 | app.run(debug=args.debug, port=args.port) |
89 | 102 |
|
90 | 103 | if __name__ == "__main__": |
|
0 commit comments