I'm creating an API using Flask and have the following code:
@app.route('/<major>/')
def major_res(major):
course_list = list(client.db.course_col.find({"major": (major.encode("utf8", "ignore").upper())}))
return json.dumps(course_list, sort_keys=True, indent=4, default=json_util.default)
When viewing /csci/
in the browser, the output looks like this:
[{ "course": "CSCI052", "description": "Fundamentals of Computer Science. A solid foundation in functional programming, procedural and data abstraction, recursion and problem-solving. Applications to key areas of computer science, including algorithms and complexity, computer architecture and organization, programming languages, finite automata and computability. This course serves the same role as HM 60 as a prerequisite for upper-division computer science courses at any of the Claremont Colleges. Prerequisite: 51.", "instructor": "Bull, Everett L.,, Jr.", "name": " Fundamentals of Computer Science", "number": 52, "school": "PO" }]
How do I return this dictionary so that each key and value are on their own line?
The Solution. There are two methods you can use to return JSON data in your Flask application's view: by returning a Python dictionary, or by using Flask's jsonify() method.
jsonify() is a helper method provided by Flask to properly return JSON data. jsonify() returns a Response object with the application/json mimetype set, whereas json. dumps() simply returns a string of JSON data. This could lead to unintended results.
Flask provides jsonify()
as a convenience:
from flask import jsonify
@app.route("/<major>/")
def major_res(major):
course_list = list(client.db.course_col.find({"major": major.upper()}))
return flask.jsonify(**course_list)
This will return the args of jsonify
as a JSON representation, and, unlike your code, will send the proper Content-Type
header: application/json
. Take note of what the docs say about the format:
This function's response will be pretty printed if the
JSONIFY_PRETTYPRINT_REGULAR
config parameter is set toTrue
or the Flask app is running in debug mode. Compressed (not pretty) formatting currently means no indents and no spaces after separators.
Responses will receive non-pretty-printed JSON when not in debug mode. This shouldn't be a problem since JSON for JavaScript consumption shouldn't need to be formatted (that's just extra data to be sent over the wire), and most tools format received JSON on their own.
If you'd like to still use json.dumps()
, you can send the proper mimetype by returning a Response
with current_app.response_class()
.
from flask import json, current_app
@app.route("/<major>/")
def major_res(major):
course_list = list(client.db.course_col.find({"major": major.upper() }))
return current_app.response_class(json.dumps(course_list), mimetype="application/json")
For more on the difference:
flask.json
module docsPrior to Flask 1.0, JSON handling was somewhat different. jsonify
would try to detect whether a request was AJAX and return pretty printed if it was not; this was removed because it was unreliable. jsonify
only allowed dicts as the top-level object for security reasons; this is no longer applicable in modern browsers.
If for some reason you need to over-ride flask.jsonify
(E.g., adding a custom json encoder) you can do so with the following method that implements the security fix @phpmycoder mentioned:
from json import dumps
from flask import make_response
def jsonify(status=200, indent=4, sort_keys=True, **kwargs):
response = make_response(dumps(dict(**kwargs), indent=indent, sort_keys=sort_keys))
response.headers['Content-Type'] = 'application/json; charset=utf-8'
response.headers['mimetype'] = 'application/json'
response.status_code = status
return response
@app.route('/<major>/')
def major_res(major):
course = client.db.course_col.find({"major": (major.encode("utf8", "ignore").upper())})
return jsonify(**course)
@app.route('/test/')
def test():
return jsonify(indent=2, sort_keys=False, result="This is just a test")
Response:
{
"course": "CSCI052",
"description": "Fundamentals of Computer Science. A solid foundation in functional programming, procedural and data abstraction, recursion and problem-solving. Applications to key areas of computer science, including algorithms and complexity, computer architecture and organization, programming languages, finite automata and computability. This course serves the same role as HM 60 as a prerequisite for upper-division computer science courses at any of the Claremont Colleges. Prerequisite: 51.",
"instructor": "Bull, Everett L.,, Jr.",
"name": " Fundamentals of Computer Science",
"number": 52,
"school": "PO"
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With