How to return a JSON response from a Flask API
Many candidates are rejected or down-leveled in technical interviews due to poor performance in behavioral or cultural fit interviews. Ace your interviews with this free course, where you will practice confidently tackling behavioral interview questions.
Flask is a framework that is widely used to create APIs in Python. Flask is a simple yet powerful web framework that is designed to help us get started quickly and easily, with the ability to scale up to complex applications.
Flask is often referred to as micro because it was built with a simple but extensible core.
In this shot, we are going to learn how to create a simple REST API that returns a simple JSON object, with the help of Flask.
APIs
An API is a contract between an information provider and an information user that establishes the content required by the consumer and the content required by the producer.
Restful APIs
REST stands for Representational State Transfer. A RESTFUL API allows for interaction with RESTFUL web services by conforming to the constraints of REST architectural style.
Let’s create a minimal app to test it.
Installation
Run these commands in the terminal to install Flask:
pip install pipenv pipenv shell pipenv install Flask
Code
The following code will be part of the file app.py :
from flask import Flask,jsonify,request app = Flask(__name__) @app.route('/') def Home(): info = < "school" : 'Federal University Of Technology Owerri', "department" : "Biochemistry", 'level': "500L" >return jsonify(info) # returning a JSON response if __name__=='__main__': app.run(debug=True)
Explanation
In the code above, we return the info variable, which is in JSON format.
The jsonify() function in Flask serializes data to JavaScript Object Notation (JSON) format.
Return a Valid JSON Response in Flask
We will learn, with this explanation, about JSON support in Flask and how to create an API and return it in JSON response with the help of jsonify() in Flask.
Return a Valid JSON Response With the Help of jsonify() in Flask
While using JSON with Flask is pretty simple because the type of the JSON object can be mapped to Python types, and we can access it like a dictionary or array. If you are familiar with JSON’s basics, then you should be able to understand this.
Now we will need to set up a Flask app. We are just doing some basic things to create an app, and then we will create a single route.
We will specify a root for Get_Trucks() method that is route(‘truck/api/’,methods=[‘GET’]) inside the decorator. And inside the Get_Trucks() method, we will declare a list of dictionaries that is called Trucks and return it directly.
@app.route('truck/api/',methods=['GET']) def Get_Trucks(): Trucks=[ 'id':1,'year':2017,'model':''>, 'id':2,'year':2019,'model':''>, 'id':3,'year':2020,'model':''>, 'id':4,'year':2016,'model':''> ] return Trucks
Now, we will look at two cases: the first is returning an array of objects, and the second is just returning one object by itself or one dictionary.
Let’s go ahead and take a look at the second one. The code will be the same except for a function named Truck_Details() .
from flask import Flask app=Flask(__name__) @app.route('/truck/api/',methods=['GET']) def Get_Trucks(): Trucks=[ 'id':1,'year':2017,'model':''>, 'id':2,'year':2019,'model':''>, 'id':3,'year':2020,'model':''>, 'id':4,'year':2016,'model':''> ] return Trucks @app.route('/truck-details/api/',methods=['GET']) def Truck_Details(): Details= 'id':2,'year':2019,'model':''> return Details if __name__=='__main__': app.run(debug=True)
Now, we will run the Flask app and go to the browser. Let’s test this first route.
When we hit Enter, we get the type error where we can read that the view function did not return a valid response because we’re trying to send a Python list to the browser.
We can fix this very quickly by importing one more thing from Flask: jsonify() . This is a built-in flask; we do not need to use a third-party module.
We will go to where we are returning our list or array and wrap it in jsonify() . Let’s save this and test our route again, and now we are getting a valid JSON response.
If we look at this in the network inspector, we can see this has a content type of application is JSON.
Let’s look at returning a single object from the Flask without using jsonify() . Let’s take a look at it in the browser.
It works because we are using an upgraded version. If you use the Flask version 1.1.0 or higher, it will automatically convert the dictionary to JSON when it is returning it in a view , but if your version of the Flask is less than 1.1.0, then you can do the same thing as we did to returning multiple objects.
If we look at the right side, we can see that the content type is JSON, and we are just using a Chrome extension called JSON view to prettify the response data.
from flask import Flask,jsonify app=Flask(__name__) @app.route('/truck/api/',methods=['GET']) def Get_Trucks(): Trucks=[ 'id':1,'year':2017,'model':''>, 'id':2,'year':2019,'model':''>, 'id':3,'year':2020,'model':''>, 'id':4,'year':2016,'model':''> ] return jsonify(Trucks) @app.route('/truck-details/api/',methods=['GET']) def Truck_Details(): Details= 'id':2,'year':2019,'model':''> return Details if __name__=='__main__': app.run(debug=True)
Hello! I am Salman Bin Mehmood(Baum), a software developer and I help organizations, address complex problems. My expertise lies within back-end, data science and machine learning. I am a lifelong learner, currently working on metaverse, and enrolled in a course building an AI application with python. I love solving problems and developing bug-free software for people. I write content related to python and hot Technologies.
Returning JSON responses with Flask
My most common use case for Flask is making APIs. And I like my APIs to respond with JSON. Flask comes with a jsonify() function that returns JSON as a Flask Response object.
The reason to use jsonify() over a regular json.dumps() is that jsonify() sets the Content-Type HTTP header to application/json . Whereas the output of json.dumps() is just plain text.
An example of responding with JSON is shown below. You can pass a dict or a list to the jsonify() function. This is then transformed to a JSON string.
from flask import Flask, jsonify app = Flask(__name__) @app.route('/chopstick/') def chopstick(): chopstick = 'color': 'bamboo', 'left_handed': True > return jsonify(chopstick) if __name__ == '__main__': app.run()
The above example returns the following JSON object if we call the /chopstick/ endpoint.
$ curl localhost:5000/chopstick/ "color": "bamboo", "left_handed": true >
Alternatively you can use keyword arguments as well with jsonify() . So the following produces the same end result.
@app.route('/chopstick/') def chopstick(): return jsonify( color='bamboo', left_handed=True )
Adding status codes to a JSON response
This jsonify() is nice and all, but it doesn’t give us the opportunity the set a status code for the response we are returning.
Lets say for example that we want the /chopstick/ endpoint to work with a chopstick id. In case the id isn’t found in the URI we want to return a 400 status for a bad request.
So to illustrate, let say the chopstick function is responsible for handling both the /chopstick/ and /chopstick/<id> routes. If the chopstick_id is None , so not present in the URI, we return a 400 status with a appropriate error message.
@app.route('/chopstick/') @app.route('/chopstick/<int:chopstick_id>') def chopstick(chopstick_id=None): if not chopstick_id: return # status 400 - bad request return jsonify( id=chopstick_id, color='bamboo', left_handed=True, )
To do so we can use the make_response() function in Flask. We still make use of jsonify() in combination with this make_response() so that the error message is a correct JSON string.
from flask import Flask, jsonify, make_response app = Flask(__name__) @app.route('/chopstick/') @app.route('/chopstick/<int:chopstick_id>') def chopstick(chopstick_id=None): if not chopstick_id: message = jsonify(message='"chopstick_id" missing') return make_response(message, 400) return jsonify( id=chopstick_id, color='bamboo', left_handed=True, ) if __name__ == '__main__': app.run()
If we now curl the endpoint without an ID we see the error message with the 400 status code as response.
$ curl -i localhost:5000/chopstick/ HTTP/1.0 400 BAD REQUEST Content-Type: application/json Content-Length: 44 Server: Werkzeug/1.0.1 Python/3.8.5 Date: Sun, 25 Oct 2020 09:04:22 GMT "message": "\"chopstick_id\" missing" >
And ofcourse, the chopstick itself is returned with status 200 if we do specify an ID in the URI.
$ curl -i localhost:5000/chopstick/5 HTTP/1.0 200 OK Content-Type: application/json Content-Length: 60 Server: Werkzeug/1.0.1 Python/3.8.5 Date: Sun, 25 Oct 2020 09:05:57 GMT "color": "bamboo", "id": 5, "left_handed": true >
Flask Version
$ flask --version Python 3.8.5 Flask 1.1.2 Werkzeug 1.0.1