Using flask inside class

前端 未结 3 1589
攒了一身酷
攒了一身酷 2020-12-08 09:36

I have application with many threads. One of them is flask, which is used to implement (axillary) API. It used with low load and never exposed to the Internet, so build-in f

相关标签:
3条回答
  • 2020-12-08 10:16

    To complete Kostas Pelelis's answer, because I had some difficulty to find the why the Response wasn't directly using the Action returned value.

    Here is another version of FLASK class without decorators :

    class EndpointAction(object):
    
    def __init__(self, action):
        self.action = action
    
    def __call__(self, *args):
        # Perform the action
        answer = self.action()
        # Create the answer (bundle it in a correctly formatted HTTP answer)
        self.response = flask.Response(answer, status=200, headers={})
        # Send it
        return self.response
    
    class FlaskAppWrapper(object):
    
    def add_all_endpoints(self):
        # Add root endpoint
        self.add_endpoint(endpoint="/", endpoint_name="/", handler=self.action)
    
        # Add action endpoints
        self.add_endpoint(endpoint="/add_X", endpoint_name="/add_X", handler=self.add_X)
        # you can add more ... 
    
    def add_endpoint(self, endpoint=None, endpoint_name=None, handler=None):
        self.app.add_url_rule(endpoint, endpoint_name, EndpointAction(handler)) 
        # You can also add options here : "... , methods=['POST'], ... "
    
    # ==================== ------ API Calls ------- ====================
    def action(self):
        # Dummy action
        return "action" # String that will be returned and display on the webpage
        # Test it with curl 127.0.0.1:5000
    
    def add_X(self):
        # Dummy action
        return "add_X"
        # Test it with curl 127.0.0.1:5000/add_X
    
    0 讨论(0)
  • 2020-12-08 10:18

    so I just came across the library Flask-Classful

    which was really simple comparatively
    To create a simple web app inside a class is this

    from flask import Flask
    from flask_classful import FlaskView
    
    app = Flask(__name__)
    
    class TestView(FlaskView):
    
        def index(self):
        # http://localhost:5000/
            return "<h1>This is my indexpage</h1>"
    
    TestView.register(app,route_base = '/')
    
    if __name__ == '__main__':
        app.run(debug=True) 
    

    Handling multiple route and dynamic route is also simple

    class TestView(FlaskView):
    
        def index(self):
        # http://localhost:5000/
            return "<h1>This is my indexpage</h1>"
    
        def secondpage(self):
        # http://localhost:5000/secondpage
            return "<h1>This is my second</h1>"
        
        def thirdpage(self,name):
        # dynamic route
        # http://localhost:5000/thirdpage/sometext
            return "<h1>This is my third page <br> welcome"+name+"</h1>"
    
    TestView.register(app,route_base = '/')
    

    Adding own route name with a different method that is also possible

    from flask_classful import FlaskView,route
    
    class TestView(FlaskView):
    
        def index(self):
        # http://localhost:5000/
            return "<h1>This is my indexpage</h1>"
    
    
        @route('/diffrentname')
        def bsicname(self):
        # customized route
        # http://localhost:5000/diffrentname
            return "<h1>This is my coustom route</h1>"
    TestView.register(app,route_base = '/')
    
    

    This gives the potential to create separate class and handlers for a separate dependent and independent process and just import them as a package to run on the main file or wrapper file

    from package import Classname
    Classname.register(app,route_base = '/')
    

    which is really simple and object-oriented

    0 讨论(0)
  • 2020-12-08 10:27

    Although this works it doesn't feel compliant with the Flask style guide. If you need to wrap a Flask application inside your project, create a separate class to your needs and add functions that should be executed

    from flask import Flask, Response
    
    
    class EndpointAction(object):
    
        def __init__(self, action):
            self.action = action
            self.response = Response(status=200, headers={})
    
        def __call__(self, *args):
            self.action()
            return self.response
    
    
    class FlaskAppWrapper(object):
        app = None
    
        def __init__(self, name):
            self.app = Flask(name)
    
        def run(self):
            self.app.run()
    
        def add_endpoint(self, endpoint=None, endpoint_name=None, handler=None):
            self.app.add_url_rule(endpoint, endpoint_name, EndpointAction(handler))
    
    
    def action():
        # Execute anything
    
    a = FlaskAppWrapper('wrap')
    a.add_endpoint(endpoint='/ad', endpoint_name='ad', handler=action)
    a.run()
    

    Some things to note here:

    • EndpointAction is supposed to be a wrapper that will execute your function and generate an empty 200 response. If you want you can edit the functionality
    • The endpoint handler can be anything that has a __call__ method defined
    • The endpoint name should be unique as it represents a view name
    • Adding endpoints after the application is not possible as the thread will block once the application starts. You can enable it by running the application on a separate thread but changing the URL map on the fly is not advised, neither thread safe
    0 讨论(0)
提交回复
热议问题