Flask: Controlling HTTP methods allowed

The objective of this post is to explain how control the allowed HTTP methods on the URLs specified for a Flask web server.


Introduction

The objective of this post is to explain how control the allowed HTTP methods on the URLs specified for a Flask web server.

Flask is a web micro framework for Python [1] which allows us to create and deploy simple web applications very easily. You can read an introduction on Flask on this previous post.

 

The code

First of all, we need to import the Flask class from the flask module, so all the functionality we need becomes available. We will also import the request object from the flask module, which we will use later to check the method of an incoming HTTP request.

Then, we create an instance of the Flask class. In the constructor, we pass the name of the module of our application, using the __name__ global variable.

from flask import Flask
from flask import request
app = Flask(__name__)

Now, we will specify a route that only answers to HTTP GET requests. Although this is redundant since, by default, routes only answer to HTTP GET methods [1], we will do it to illustrate the functionality.

So, we will define a handler function for a route to be listening on the /get URL that is only triggered for GET requests. We specify the methods allowed by providing the methods argument to the route decorator [1].

@app.route('/get', methods = ['GET'])
def getHandler():
    return 'GET handler'

To define a route that only listens to HTTP POST methods, we just need to change the methods argument to POST. So, we will now define a handling function for a route that will be listening on the /post URL that is only triggered for POST requests.

@app.route('/post', methods = ['POST'])
def postHandler():
    return 'POST handler'

Note that the methods argument receives a list of values. So, we can specify multiple allowed methods. In this case, since we will only define one handler function, we can check the received HTTP method inside the code by using the imported request object [2]. The request object is an instance of a Request subclass [2].

So, we will just define a URL called /getpost which will return a different message depending if the request was a POST or a GET. In order for our route to support both methods, we just pass a list with the names of the two methods in the methods argument.

Inside the code of the handling function, to check the method of the incoming HTTP request, we just use the method attribute of the request object. So, as shown bellow, we compare the value of this attribute with the name of the method in a conditional sentence.

@app.route('/getpost', methods = ['POST', 'GET'])
def postGetHandler():
    if request.method == 'POST':
        return 'request via POST'
    else:
        return 'request via GET'

Finally, to tell our application to run, we just call the run method on the Flask object we instantiated before, passing as arguments the host and the port where it will be listening. We will be specifying port 8090, so you must use it to send the HTTP requests when testing the code.

app.run(host='0.0.0.0', port= 8090)

The final complete code can be seen below.


from flask import Flask
from flask import request

app = Flask(__name__)

@app.route('/get', methods = ['GET'])
def getHandler():
    return 'GET handler'

@app.route('/post', methods = ['POST'])
def postHandler():
    return 'POST handler'

@app.route('/getpost', methods = ['POST', 'GET'])
def postGetHandler():
    if request.method == 'POST':
        return 'request via POST'
    else:
        return 'request via GET'

app.run(host='0.0.0.0', port= 8090)


Testing the code

Since we are going to test different HTTP methods, the easiest way is to use a tool like Postman, which allows us to specify the HTTP method. This is a very powerful and versatile tool and I really recommend it for this kind of tests with HTTP requests.

To test this, we can do all of the following HTTP requests on the local host: 127.0.0.1:8090 . In postman, you don’t need to put the http:// before the IP:port. So, a request will have the following format: 127.0.0.1:8090/FlaskRouteURL.

So, start by running the Python script we previously defined. You can do it, for example, in IDLE, the Python IDE.

Then, open Postman and make a HTTP GET request on the /get URL. You should receive the message we defined in the code, as seen in figure 1.

flask-postman-get-request

Figure 1 – Flask HTTP GET method allowed.

Now, if we change the method to POST and make the HTTP request on the same URL, we will get a “Method not allowed” message, as shown in figure 2.

Flask Postman method not allowed.png

Figure 2 – Flask HTTP POST method not allowed.

Now, if we change to the /post URL and make a POST request, it will send us the message defined in the code, as shown in figure 3.

Flask Postman POST Request.png

Figure 3 – Flask HTTP POST method allowed.

If we now try a GET request, it will also output a “Method not allowed” message, as shown in figure 4.

flask-postman-get-method-not-allowed

Figure 4 – Flask HTTP GET method not allowed.

Now if we send a HTTP request with the GET method on the /getpost URL, we will receive the message indicating the request was via GET method, as seen in figure 5.

Postman Flask GET Request.png

Figure 5 – Flask HTTP GET on multiple method URL.

Finally, if we send a HTTP request with the POST method on that same URL, we will receive a message indicating the request was via POST method, as seen in figure 6.

Postman Flask POST Request.png

Figure 6 – Flask HTTP POST on multiple method URL.


References

[1] http://flask.pocoo.org/docs/0.12/quickstart/

[2] http://flask.pocoo.org/docs/0.12/api/#flask.request

Advertisements
This entry was posted in Python and tagged , , , , , , , , . Bookmark the permalink.

2 Responses to Flask: Controlling HTTP methods allowed

  1. Pingback: Flask: Parsing JSON data | techtutorialsx

  2. Pingback: ESP8266: Posting JSON data to a Flask server on the cloud | techtutorialsx

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s