from flask import Flask from typing import Callable, Dict from src.server.file_manager import create_filemanager_blueprint from gunicorn.app.base import BaseApplication import multiprocessing class Server(BaseApplication): """ Server class for managing a Flask web application with Gunicorn integration. This class extends BaseApplication to provide a configurable server environment for Flask applications. It supports custom template functions, dynamic worker/thread configuration, and flexible server options. Attributes: debug (bool): Enables or disables debug mode for the Flask app. host (str): The hostname or IP address to bind the server to. port (int): The port number to listen on. app (Flask): The Flask application instance. application (Flask): Alias for the Flask application instance. options (dict): Gunicorn server options such as bind address, reload, threads, and access log. Methods: __init__(self, debug=True, host="0.0.0.0", port=8080, template_functions=None, workers=..., access_log=True, options=None): Initializes the Server instance with the specified configuration and registers template functions. register_template_function(self, name, func): Registers a Python function to be available in Jinja2 templates. load_config(self): Loads configuration options from self.options into the Gunicorn config object. load(self): Returns the Flask application instance managed by the server. register_route(self, route, func, defaults=None): """ def __init__( self, debug: bool = True, host: str = "0.0.0.0", port: int = 8080, template_functions: Dict[str, Callable] = None, workers: int = multiprocessing.cpu_count() // 2 + 1, access_log: bool = True, options=None, ): if template_functions is None: template_functions = {} self.debug = debug self.host = host self.port = port self.app = Flask(__name__) self.application = self.app self.app.secret_key = "your_secret_key" self.options = options or { "bind": f"{self.host}:{self.port}", "reload": self.debug, "threads": workers, "accesslog": "-" if access_log else None, } super().__init__() for name, func in template_functions.items(): self.register_template_function(name, func) def register_template_function(self, name, func): """ Register a function to be available in Jinja2 templates. This method adds a Python function to the Jinja2 environment's globals, making it available for use in all templates rendered by the application. Parameters: ---------- name : str The name under which the function will be accessible in templates func : callable The Python function to register Examples: -------- >>> server.register_template_function('format_date', lambda d: d.strftime('%Y-%m-%d')) >>> # In template: {{ format_date(some_date) }} """ self.app.jinja_env.globals.update({name: func}) def load_config(self): """ Loads configuration options from self.options into self.cfg. This method filters out options that are not in self.cfg.settings or have None values. The filtered options are then set in the configuration object (self.cfg) with lowercase keys. Returns: None """ config = { key: value for key, value in self.options.items() if key in self.cfg.settings and value is not None } for key, value in config.items(): self.cfg.set(key.lower(), value) def load(self): """ Returns the application instance associated with the server. Returns: Application: The application object managed by the server. """ return self.application def register_route(self, route, func, defaults=None): """ Registers a new route with the Flask application. Args: route (str): The URL route to register. func (callable): The view function to associate with the route. defaults (dict, optional): A dictionary of default values for the route variables. Defaults to None. Returns: None """ self.app.add_url_rule(route, func.__name__, func, defaults=defaults)