pythonflask

Handling singleton object with Flask


how to access objects within flask routes, if they are not defined in the same file. i want to split the following script in to multiple files with blueprints. how can the controller object be accessed?

from flask import Flask, Response


class Controller:
    def __init__(self) -> None:
        self._running = False

    def run(self):
        self._running = True

    def stop(self):
        self._running = False

    def is_running(self):
        return "running" if self._running else "stopped"


app = Flask(__name__)
controller = Controller()


@app.route("/run")
def run():
    controller.run()
    return Response(controller.is_running(), status=200)


@app.route("/stop")
def stop():
    controller.stop()
    return Response(controller.is_running(), status=200)


app.run()

the code can be split in two parts: server.py

from flask import Flask, Response
from routes import simple_page


class Controller:
    def __init__(self) -> None:
        self._running = False

    def run(self):
        self._running = True

    def stop(self):
        self._running = False

    def is_running(self):
        return "running" if self._running else "stopped"


app = Flask(__name__)
controller = Controller()
app.register_blueprint(simple_page)
app.run()

routes.py

from flask import Blueprint, current_app


simple_page = Blueprint("simple_page", __name__, template_folder="templates")


@simple_page.route("/run")
def run():
    controller.run()
    return Response(controller.is_running(), status=200)


@simple_page.route("/stop")
def stop():
    controller.stop()
    return Response(controller.is_running(), status=200)

the controller object is obviously not defined in the routes.py i tried these:

global controller
controller Controller()
# server.py
app["config"] = controller
# routes.py
from flask import current_app
app = currentapp
controller = app["config"]
#circular import error. importing the object itself
from server import controller

Solution

  • controller.py

    class Controller:
        def __init__(self) -> None:
            self._running = False
    
        def run(self):
            self._running = True
    
        def stop(self):
            self._running = False
    
        def is_running(self):
            return "running" if self._running else "stopped"
    
    
    singletonController = Controller()
    

    server.py

    from flask import Flask, Response
    
    from controller import singletonController
    
    
    app = Flask(__name__)
    controller = singletonController
    
    
    @app.route("/run")
    def run():
        controller.run()
        return Response(controller.is_running(), status=200)
    
    
    @app.route("/stop")
    def stop():
        controller.stop()
        return Response(controller.is_running(), status=200)
    
    
    app.run()
    

    Please note the from controller import singletonController statement.

    and later on controller = singletonController assignment.

    This works. Is it something that you are looking for ?