Application
The app.py module is the main entry point for the Remote OpenFAST Plotter application.
App Overview
The application is built using the Dash framework, which provides a reactive web interface for Python. The app.py module is responsible for:
Initializing the Dash application
Creating the server configuration
Loading the user interface components
Registering all callback functions
Starting the web server
Key Components
Application Initialization
The Dash application is initialized with necessary configuration:
app = dash.Dash(
__name__,
external_stylesheets=[
dbc.themes.BOOTSTRAP,
dbc.icons.BOOTSTRAP,
"https://fonts.googleapis.com/css2?family=Lato:wght@400;700&display=swap",
],
external_scripts=[
"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.4/MathJax.js?config=TeX-MML-AM_CHTML",
],
)
app.title = "OpenFAST Plotter"
app.config.suppress_callback_exceptions = True
Server Configuration
The server is configured with appropriate settings:
server = app.server # Expose the server variable for production
# Add custom response headers for security
@server.after_request
def apply_security_headers(response):
response.headers["X-Frame-Options"] = "SAMEORIGIN"
response.headers["X-XSS-Protection"] = "1; mode=block"
return response
Layout Setup
The application layout is loaded from the components module:
# Set the application layout from components
app.layout = create_layout()
Callbacks Registration
All interactive callbacks are registered using a modular approach:
# Register all callbacks
register_callbacks(app)
The register_callbacks function is imported from the callbacks module and registers all callback functions that enable the application’s interactivity.
Main Function
The main function initializes the application and starts the server:
def main():
"""Run the application server."""
# Parse command line arguments
parser = argparse.ArgumentParser(description='Start the OpenFAST Plotter server')
parser.add_argument('--host', type=str, default='127.0.0.1',
help='Host address (default: 127.0.0.1)')
parser.add_argument('--port', type=int, default=8050,
help='Port to run the server on (default: 8050)')
parser.add_argument('--debug', type=bool, default=True,
help='Run in debug mode (default: True)')
args = parser.parse_args()
# Start the server with automatic port retry
max_retries = 5
for retry in range(max_retries):
try:
app.run(host=args.host, port=args.port, debug=args.debug)
break
except OSError as e:
if 'Address already in use' in str(e) and retry < max_retries - 1:
print(f"Port {args.port} is in use, trying port {args.port + 1}")
args.port += 1
continue
raise
Command Line Arguments
The application accepts several command line arguments:
--host: The host interface to bind to (default: 127.0.0.1)--port: The port to run the server on (default: 8050)--debug: Whether to run in debug mode (default: True)
For example:
python app.py --host 0.0.0.0 --port 8051
Port Retry Logic
The application includes automatic port retry logic to handle cases where the default port is already in use:
The server attempts to start on the specified port
If that port is in use, it increments the port number and tries again
This process repeats up to a maximum number of retries
This feature enables the application to automatically find an available port when the default port is occupied.