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
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
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
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__call__
method defined