Please click here to check my first part [part-1] of this blog
In previous section we have discussed about
- About web Framework
- About Flask framework
- HTTP methods used in Flask framework
- A minimal Flask application
- A new approach using OOP's with Flask Framework
Now we are going to discuss further deep going into the concept
In the previous part we have discussed about the Flask framework which can be worked using classes and object, but not quitely.
We have just created a FlaskAppWrapper class which takes the flask app and allows us to add the endpoints and routing.
The FlaskAppWrapper class make sure functionality of add_endpoint method which is used to routing the method with appropriate endpoint given as an arguments passed to it.
In this section we are going to discuss about
- Routing
- Dynamic Routing
- EndpointHandler class
- How EndpointHandler class helps in routing
Routing
App routing is used to map the specific URL with the associated function that is intended to perform some task.
The associated function is called handler in our case.
The add_endpoint method add the new endpoint for a given handler should be a callable function executed when you invoke the url with a given endpoint should be callable type rather you pass any arguments to it or not uses add_url_rule(<url_rule>, <endpoint>, <view_function>) which we have discussed before in the previous section which is used to perform routing for flask application.
Here,
-
<url_rule>is the endpoint -
<endpoint>is the endpoint name which rather is the name of the handler and -
<view_function>is the associated function, rather say handler which is executed when we call the URL with the registered endpoint.
If you pass any arguments to that callable handler, you have the request.view_args method which should be imported from the flask module which will will store the arguments.
Dynamic routing
Here we use a concept of Dynamic routing. Flask provides the functionality of the dynamic routing.
It is the process of getting dynamic data(variable names) in the URL and then using it.
In Flask you can have use following converters to convert dynamic input from the URL.
- string
- int
- float
- path ( It is simple a string but also accepts shashles in the URL)
- uuid
Dynamic URL's in Flask play an important role in the ability to create unique URL's that aren't hard-coded into our application.
EndpointHandler class
To pass the arguments, we have to create another class name EndpointHandler which is responsible for executing the handler according to the endpoint.
class EndpointHandler(object):
def __init__(self, action):
self.action = action
def __call__(self, *args, **kwargs):
response = self.action(*args, **kwargs)
return response
Let's save in handler.py file.
In the above code we have created EndpointHandler class where the instance of that class is callable. Callable in the sense that instance of the class act's similar to the function. The __call__ method makes the instance callable and executes what inside the __call__ method.
Here in the class EndpointHandler takes the action which will be the any function or any method from class.
Let's test with any built-in function in python.
There are so many built-in function in python such as print, list, len etc..
Let's try with print as an argument of an instance of the class.
handler = EndpointHandler(print)
handler("Hello world")
The output will be like this
C:\>python handler.py
Hello world
That means print function is an action of handler which is an instance of a class and it is callable and prints anything we pass as an arguments. That means that handler instance has the functionality of the print function and acts as the same function we passed into it.
We have to check whether it works on user defined function.
Let's take an example of the function called action shown below.
def action(a,b):
"""
This action is an example function which takes the two parameter a and b of Integer type and returns the sum of a and b
"""
return a + b
Now Let's make an instance of the class name handler and pass the action function as arguments in class.
handler = EndpointHandler(action)
result = handler(5, 6)
print(result)
You will get the output as the sum of 5 and 6 which is 11. That means we have concluded that the EndpointHandler class is the callable class which takes the associative function which is stored in the action parameter, performs the same functionality with the action.
How EndpointHandler class will help in Routing in flask?
We have the EndpointHandler class which we have discussed in the previous part of the blog is shown below, the only change is we are going to pass the endpoint of EndpointHandler
class FlaskAppWrapper(object):
def __init__(self, app, **configs):
self.app = app
self.configs(**configs)
def configs(self, **configs):
for config, value in configs:
self.app.config[config.upper()] = value
def add_endpoint(self, endpoint=None, endpoint_name=None, handler=None, methods=['GET'], *args, **kwargs):
self.app.add_url_rule(endpoint, endpoint_name, EndpointHandler(handler), methods=methods, *args, **kwargs)
def run(self, **kwargs):
self.app.run(**kwargs)
There are some changes should be done in EndpointHandler class when you are working in flask shown below.
from flask import request, make_response
class EndpointHandler(object):
def __init__(self, action):
self.action = action
def __call__(self, *args, **kwargs):
response = self.action(*args, **request.view_args)
return make_response(response)
where,
request.view_argsA dict of view arguments that matched the request. If an exception happened when matching, this will beNone.make_responseConvert the return value from a view function to an instance of response_class.
Now, We have to test our FlaskAppWrapper with a new function called action and we are going to pass name argument to it
def action(name):
"""
This function takes `name` argument and returns `Hello name`.
"""
return "Hello " + name
Now we are going to define the flask app and we are going to register the action function.
flask_app = Flask(__name__)
app = FlaskAppWrapper(flask_app)
# register the action function to app
app.add_endpoint('/action/<string:name>', 'action', action)
if __name__ == '__main__':
app.run(debug=True)
The whole code looks like
from flask import Flask, request, make_response
class EndpointHandler(object):
def __init__(self, action):
self.action = action
def __call__(self, *args, **kwargs):
response = self.action(*args, **request.view_args)
return make_response(response)
class FlaskAppWrapper(object):
def __init__(self, app, **configs):
self.app = app
self.configs(**configs)
def configs(self, **configs):
for config, value in configs:
self.app.config[config.upper()] = value
def add_endpoint(self, endpoint=None, endpoint_name=None, handler=None, methods=['GET'], *args, **kwargs):
self.app.add_url_rule(endpoint, endpoint_name, EndpointHandler(handler), methods=methods, *args, **kwargs)
def run(self, **kwargs):
self.app.run(**kwargs)
def action(name):
"""
This function takes `name` argument and returns `Hello <name>`.
"""
return "Hello " + name
flask_app = Flask(__name__)
app = FlaskAppWrapper(flask_app)
# register the action function to app
app.add_endpoint('/action/<string:name>', 'action', action)
if __name__ == '__main__':
app.run(debug=True)
The code above shown works like this
Firstly, I have imported some requirements from
Flaskframework.We have created the
EndpointHandlerclass which is responsible for managing to pass the extra arguments or parameters to be passed when anactionis invoked.Then we have worked with the
FlaskAppWrapperclass and we have discussed about it in the previous part and we made some changes which is menctioned in the above discussion.To test the
FlaskAppWrapperclass we have defined theactionfunction which takes thenameas the parameter and returns the string asHello <name>.We have defined the
flask_appas the instance of theFlaskclass and thisflask_appinstance is given to ourFlaskAppWrapperclass and this instance is stored inapp.We have registered the
actionfunction to theappinstance using theadd_endpointmethod by giving the appropriateendpointto theactionfunction. In this case/action/<string:name>is the endpoint for theactionfunction that means, when we invoked the Flask app url with the endpoint above executes theactionfunction which we have registered and we are going to see in the output section.We are going to run the file using
app.run()method and we see the output
We save the above code as example6.py and run using the command
C://> python example6.py
And then we are going to click on the url shown below.
We are heading over to http://127.0.0.1:5000/action/Tejas in any search engines (I'm using Google) and we get the output as shown below
We have observed that after heading to the url above, You get the output as Hello Tejas and Tejas is the name I have passed over the action function.
We will check with other name say Subash.
Head over to http://127.0.0.1:5000/action/Subash the output is as shown below
A broad example
Now we will test our application by adding many actions to our FlaskAppWrapper class.
The whole code looks like
from flask import Flask, request, make_response
class EndpointHandler(object):
def __init__(self, action):
self.action = action
def __call__(self, *args, **kwargs):
response = self.action(*args, **request.view_args)
return make_response(response)
class FlaskAppWrapper(object):
def __init__(self, app, **configs):
self.app = app
self.configs(**configs)
def configs(self, **configs):
for config, value in configs:
self.app.config[config.upper()] = value
def add_endpoint(self, endpoint=None, endpoint_name=None, handler=None, methods=['GET'], *args, **kwargs):
self.app.add_url_rule(endpoint, endpoint_name, EndpointHandler(handler), methods=methods, *args, **kwargs)
def run(self, **kwargs):
self.app.run(**kwargs)
def action1(name):
"""
This function takes `name` argument and returns `Hello name`.
"""
return "Hello " + name
def action2():
"""
This function returns "Action2 invoked"
"""
return "Action2 invoked"
def action3(number):
"""
This function returns the cube of the number
"""
return "Cube of {0} is {1}".format(number, number**3)
flask_app = Flask(__name__)
app = FlaskAppWrapper(flask_app)
# register all action functions to app
app.add_endpoint('/action1/<string:name>', 'action1', action1)
app.add_endpoint('/action2/', 'action2', action2)
app.add_endpoint('/action3/<int:number>', 'action3', action3)
if __name__ == '__main__':
app.run(debug=True)
From above code, we have registered the 3 action functions to our app.
action1takes thenameparameter from the endpoint and returnsHello <name>.action2returnsAction2 invoked.action3takes thenumberparameter from the endpoint and returns the cube of the number.
After running the above code we get the output shown below
- Heading over http://127.0.0.1:5000/action1/Tejas We get the output as shown below
- Heading over http://127.0.0.1:5000/action2/ we get the output as
- Heading over http://127.0.0.1:5000/action3/10 we get the output as
Same url, different endpoints and different functions are invoked and executed.
We are going to declare that any number of actions can be registered in our app and I conclude that the FlaskAppWrapper class works as good as the Flask application and this is the approach I have researched.
Summary
We have discussed in this part about
- Routing and Dynamic Routing in Flask
- Handling the flask endpoint using
EndpointHandlerclass - Discussed and made some changes in the
FlaskAppWrapperclass. - Tested the updated code with the concept of
Dynamic routing.






Top comments (0)