Bussiere
Bussiere

Reputation: 1144

Embedding flask inside a class with decorators

I'am trying to use a flask inside a class, but i would like to use decorators

i've seen this subject Using flask inside class

But so far so good no use of decorators inside, if no choice i will use this solution.

For the moment my code look like this :

class DM():
    def __init__(self, path=""):
        self.cors = CORS(self.app, resources={r"/*": {"origins": "*"}})
        self.host = "0.0.0.0"
        self.port = 9001

    class app(Flask):
        pass

    def PrintException(self):
        exc_type, exc_obj, tb = sys.exc_info()
        f = tb.tb_frame
        lineno = tb.tb_lineno
        filename = f.f_code.co_filename
        linecache.checkcache(filename)
        line = linecache.getline(filename, lineno, f.f_globals)
        return 'EXCEPTION IN ({}, LINE {} "{}"): {}'.format(
            filename, lineno, line.strip(), exc_obj
        )

    @app.route("/product", methods=["POST", "GET", "OPTION"])
    def addProduct(self):
        try:
            data = request.data
            document = json.loads(data.decode("utf-8"))
            return jsonify({"status":"ok","_id":str(document)})
        except Exception as e:
            return jsonify({"status": "ko", "exception": self.PrintException() + " " + str(e),"document":document})


    @app.after_request
    def after_request(self,response):
        response.headers.add("Access-Control-Allow-Origin", "*")
        response.headers.add("Access-Control-Allow-Headers", "Content-Type,Authorization")
        response.headers.add("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE,OPTIONS")
        return response
    def run(self):
        self.app.run(self.host, self.port)

but i have this error :

    @app.route("/product", methods=["POST", "GET", "OPTION"])
TypeError: route() missing 1 required positional argument: 'rule'

edit :

And i can't use self in decorators :

class DM():
    def __init__(self, path=""):
        self.app = Flask(__name__)
        self.cors = CORS(self, resources={r"/*": {"origins": "*"}})
        self.host = "0.0.0.0"
        self.port = 9001


    def PrintException(self):
        exc_type, exc_obj, tb = sys.exc_info()
        f = tb.tb_frame
        lineno = tb.tb_lineno
        filename = f.f_code.co_filename
        linecache.checkcache(filename)
        line = linecache.getline(filename, lineno, f.f_globals)
        return 'EXCEPTION IN ({}, LINE {} "{}"): {}'.format(
            filename, lineno, line.strip(), exc_obj
        )

    @app.route("/product", methods=["POST", "GET", "OPTION"])
    def addProduct(self):
        try:
            data = request.data
            document = json.loads(data.decode("utf-8"))
            return jsonify({"status":"ok","_id":str(document)})
        except Exception as e:
            return jsonify({"status": "ko", "exception": self.PrintException() + " " + str(e),"document":document})

    @app.after_request
    def after_request(self,response):
        response.headers.add("Access-Control-Allow-Origin", "*")
        response.headers.add("Access-Control-Allow-Headers", "Content-Type,Authorization")
        response.headers.add("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE,OPTIONS")
        return response
    def run(self):
        self.app.run(self.host, self.port)

Regards

Upvotes: 5

Views: 6589

Answers (1)

Olzhas Arystanov
Olzhas Arystanov

Reputation: 986

I'm not sure what exactly you want to achieve with your inheritance approach, but anyway, here is an idea that might help. Instead of using flask app inside a class, you may want to consider a factory approach. Code in your example may look as follows:

def create_application(app_name, config_filename, host, port):

    app = Flask(app_name)
    app.config_from_pyfile(config_filename)

    cors = CORS(app, resources={r"/*": {"origins": "*"}})

    @app.route("/product", methods=["POST", "GET", "OPTION"])
    def addProduct():
        try:
            data = request.data
            document = json.loads(data.decode("utf-8"))
            return jsonify({"status":"ok","_id":str(document)})
        except Exception as e:
            return jsonify({"status": "ko", "exception": self.PrintException() + " " + str(e),"document":document})

    @app.after_request
    def after_request(response):
        response.headers.add("Access-Control-Allow-Origin", "*")
        response.headers.add("Access-Control-Allow-Headers",
                             "Content-Type,Authorization")
        response.headers.add("Access-Control-Allow-Methods",
                             "GET,PUT,POST,DELETE,OPTIONS")
        return response

This method will allow you to make necessary customizations passing different arguments to your factory function or different config files. And you still can you use decorators here

Upvotes: 3

Related Questions