Categories
Flask

Python Web Development with Flask — JSON Requests, Error Pages, and MongoDB

Spread the love

Flask is a simple web framework written in Python.

In this article, we’ll look at how to develop simple Python web apps with Flask.

Accepting JSON Requests

Flask can accept JSON request bodies out of the box.

For example, we can write:

from flask import Flask, jsonify, render_template, request
app = Flask(__name__)

@app.route('/add_numbers', methods=['POST'])
def add_numbers():
    content = request.json
    a = content['a']
    b = content['b']
    return jsonify(result=a + b)

to get the request JSON body with the request.json property.

Get Query Parameters

To get query parameters in our route function, we can use the request.args.get method:

from flask import Flask, jsonify, render_template, request
app = Flask(__name__)

@app.route('/add_numbers')
def add_numbers():
    a = request.args.get('a', 0, type=int)
    b = request.args.get('b', 0, type=int)
    return jsonify(result=a + b)

We get the value of the a and b URL parameters.

The 2nd argument is the default value of each.

And the type parameter has the data type to return.

So if we go to http://localhost:5000/add_numbers?a=1&b=2, we get:

{
  "result": 3
}

as the response.

Custom Error Pages

We can add custom error pages for various kinds of errors.

Common error codes that we run into include:

  • 404 — not found
  • 403 — accessing a disallowed resource
  • 410 — access a deleted item
  • 500 — internal server error

We can add error handlers for them by using the @app.errorhandler decorator.

For example, we can write:

app.py

from flask import Flask, render_template
app = Flask(__name__)

@app.errorhandler(404)
def page_not_found(e):
    return render_template('404.html'), 404

templates/404.html

<p>not found</p>

We pass in 404 ito the @app.errorhandler decorator to add a route function for the 404 errors.

We just render the template whenever we encounter a 404 error.

Therefore, we’ll see ‘not found’ when we go to a URL that’s not mapped to a route handler.

Returning API Errors as JSON

Also, we can return API errors as JSON.

To do that, we use the jsonify function.

For instance, we can write:

from flask import Flask, jsonify, abort
app = Flask(__name__)

@app.errorhandler(404)
def resource_not_found(e):
    return jsonify(error=str(e)), 404

@app.route("/cheese")
def get_one_cheese():
    resource = None

    if resource is None:
        abort(404, description="Resource not found")

    return jsonify(resource)

We have the get_one_cheese function that returns a 404 response if resource is None .

Since it’s none, we see the JSON.

The JSON response is created in the resource_not_found function, which is the handler for 404 errors.

We call jsonify in there with the error in the response.

abort will pass the error into the e parameter of resource_not_found .

So, we get:

{
  "error": "404 Not Found: Resource not found"
}

returned in the response body when we go to http://localhost:5000/cheese.

MongoDB with MongoEngine

We can manipulate MongoDB databases easily with MongoEngine.

To use it, we install:

pip install flask_mongoengine mongoengine

to install the required libraries.

Then we write:

from flask import Flask, jsonify
from flask_mongoengine import MongoEngine
import mongoengine as me

class Movie(me.Document):
    title = me.StringField(required=True)
    year = me.IntField()
    rated = me.StringField()
    director = me.StringField()
    actors = me.ListField()

class Imdb(me.EmbeddedDocument):
    imdb_id = me.StringField()
    rating = me.DecimalField()
    votes = me.IntField()

app = Flask(__name__)
app.config['MONGODB_SETTINGS'] = {
    "db": "myapp",
}
db = MongoEngine(app)

@app.route('/')
def hello_world():
    bttf = Movie(title="Back To The Future", year=1985)
    bttf.actors = [
        "Michael J. Fox",
        "Christopher Lloyd"
    ]
    bttf.imdb = Imdb(imdb_id="tt0088763", rating=8.5)
    bttf.save()
    return 'movie saved'

@app.route('/query')
def query():
    bttf = Movie.objects(title="Back To The Future")
    return jsonify(bttf)

to connect to the MongoDB database and do the database queries in our route.

Before we add our routes, we create the classes for the MongDB document schemas.

The classes are subclasses of the me.Document class.

me.StringField creates a string field.

me.ListField creates a list field.

me.DecimalField creates a floating-point number field.

And me.IntField creates an integer field.

Then we create our Flask app with the Flask clas.

And then we add the database connection settings to the MONGO_SETTINGS config.

Then we invoke the MongoEngine class with the app argument to let our routes connect to the database.

Then in hello_world we create a Movie document and call save to save it.

In the query route, we get the Movie that are saved with the title set to 'Back To The Future' .

Then we can jsonify on the result to return it as the JSON response.

Conclusion

We can accept a JSON body and query parameters in our requests.

Also, we can create custom error pages and use MongoDB databases with Flask.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *