Any web application frequently needs to process received from users. This data can be a query string, form data, and JSON objects (JavaScript Object Notation). Like any other web, the framework allows the user to access that requested data. This article will learn how to build a flask application with three routes to accept the data in query strings, form data, or JSON objects.
Requirements for this:
- Python installation in a local environment
- A production-ready tool Pipenv to get the best of all packaging worlds to the python world.
- Installation of a tool like Postman to test the API endpoints.
Setting up the Flask app:
We need to create a Flask app to demonstrate different methods of user requests. Although the demo app uses a relatively simple structure for viewing functions and routes, these can be applied to any organizing views, blueprints, or extensions like Flask-Via.
Steps involved in this:
Open the terminal and run the following command mkdir flask_request_example
to create a project directory. After that, navigate to the new directory through this command: cd flask_request_example
. Now open the terminal and install Flask by running this command pipenv install Flask
. This pipenv
command will create a virtualenv
and pipfile install flask
and a pipfile.lock
. Virtualenv activation is started by using the pipenv shell
command.
How to Access the Data Received in a Flask Request?
Incoming data in a flask app can be accessed by using the request object. The request object tool holds all incoming data from requests such as IP address, raw data, HTTP method, headers, mime type, referrer, and other things. To access the request object in Flask, we need to import it from the Flask library through this command from the flask import request. Once we got access to the request object, we can use it to view any function. Create an app.py
file using a code editor such as PyCharm or any other editor. Establish routes for query-example
, form-example
, and JSON- example
.
# import main Flask class and request object from flask import Flask, request # create the Flask app app = Flask(__name__) @app.route('/query-example') def query_example(): return 'Query String Example' @app.route('/form-example') def form_example(): return 'Form Data Example' @app.route('/json-example') def json_example(): return 'JSON Object Example' if __name__ == '__main__': # run app in debug mode on port 5000 app.run(debug=True, port=5000)
How to Start the App?
After completing app.py
creation, open the terminal and start the app through this command python app.py
. The app will start on port 5000, and each route can be viewed in the browser via the following links.
- https://127.0.0.1:5000/query-example (or localhost:5000/query-example)
- http://127.0.0.1:5000/form-example (or localhost:5000/form-example)
- http://127.0.0.1:5000/json-example (or localhost:5000/JSON-example)
This code will establish three routes, and each route will display the messages of “Query String Example,” “Form Data Example,” and “JSON Object Example” respectively.
How to Use Query Arguments to Pass Data to a Web Page?
URL arguments that we add to a query string are easy to pass data to a web app. Many of us most likely encountered a query string while browsing.
How Does a Query String Look?
A query string looks like this, example.com?arg1=value1&arg2=value2
.
It always starts with a question mark character and has two value pairs separated by an ampersand (&) sign. Any query string has an equal sign character and then a value character. Query strings are handy to pass data and do not need the user to take action. A query string can be generated somewhere in the app and attach to the URL. When a user makes a request, they get their required data automatically. Forms can also generate a query string through the GET method.
How Can a Query String Be Added to a URL?
First of all, we need to create a key that we want to add to the URL. Suppose we have a key of “language” and a value of “Python” to display the programming language name on the screen. It will work like this. Here is our link http://127.0.0.1:5000/ and after the query string, it becomes like this http://127.0.0.1:5000/query-example?language=Python. Navigating to that URL will now display a message of query string example.
Important points related to this:
We need to program the part that handles the query arguments as well. The code will read in the language key by using either request.args.get('language')
or request.args['language']
.
- By calling
request.args.get('language')
the application will continue to run if the language key does not exist in the URL. In that case, the result of the method will beNone
. - However, by calling
request.args['language']
, the app will show a 400 error if the language key does not exist in the URL.
So to avoid this problem, it is recommended to use request.args.get()
.
Code Example
Modify the query-example
route in app.py
through this code:
@app.route('/query-example') def query_example(): # if key doesn't exist, returns None language = request.args.get('language') return '''<h1>The language value is: {}</h1>'''.format(language)
Then run the app and navigate to the URL http://127.0.0.1:5000/query-example?language=Python. Browser will show the output in this way.
Output: The language value is: Python.
How to Use Form Data?
Form data is data that has been sent as a post request to any route. The form data will be passed to the app behind the scenes, hiding the data in the URL.
How does form data get passed to the app?
Form data can be passed by modifying the form-example
route in app.py
. This modification will allow us to accept both POST and GET requests and return them as a form.
# allow both GET and POST requests @app.route('/form-example', methods=['GET', 'POST']) def form_example(): return '''<form method="POST"> <div><label>Language: <input type="text" name="language"></label></div> <div><label>Framework: <input type="text" name="framework"></label></div> <input type="submit" value="Submit"> </form>'''
Apply the code, then runs the app and navigate to the respective URL http://127.0.0.1:5000/form-example. The browser will display a form with two input fields for language and the framework. If so, then press submits button. This form will perform a post request only to the same route that generated the form. In the view
function, we need to check if the request mode is GET or POST. If it is a GET request, then only we can display the form. Post request means that we want to process the incoming data.
How to handle both request types?
First we have to modify the form-example route in app.py
through this code example:
# allow both GET and POST requests @app.route('/form-example', methods=['GET', 'POST']) def form_example(): # handle the POST request if request.method == 'POST': language = request.form.get('language') framework = request.form.get('framework') return ''' <h1>The language value is: {}</h1> <h1>The framework value is: {}</h1>'''.format(language, framework) # otherwise handle the GET request return ''' <form method="POST"> <div><label>Language: <input type="text" name="language"></label></div> <div><label>Framework: <input type="text" name="framework"></label></div> <input type="submit" value="Submit"> </form>'''
After that, run the app and navigate to the URL http://127.0.0.1:5000/form-example. Fill out the language fields with the value of framework and python field with the value of Flask. Then press Submit. The browser will show an output like this.
Output:
The language value is: Python The framework value is: Flask
JSON data monitoring:
JSON is JavaScript Object Notation. JSON data can be constructed by a process that calls the route. A nested JSON object with an array of items looks like this. Through this structure, complex data can be passed as opposed to query strings and form data. Flask can also handle this format of data efficiently. To accept JSON data modify the form-example route in app.py
to accept POST requests and ignore all other requests such as GET.
{ "language" : "Python", "framework" : "Flask", "website" : "Scotch", "version_info" : { "python" : "3.9.0", "flask" : "1.1.2" }, "examples" : ["query", "form", "json"], "boolean_test" : true }
Code Example:
@app.route('/json-example', methods=['POST']) def json_example(): return 'JSON Object Example'
How to Send Custom Requests via Postman for JSON Objects?
Unlike query strings and form data to send a JSON object, Postman will send custom requests to URLs. Add the URL in the Postman and change the type to POST. On the body tab, change to raw and select JSON from the drop-down.
POST http://127.0.0.1:5000/json-example Body raw JSON
These settings are necessary to send JSON data via Postman and notify the Flask app that it receives JSON. Now copy the JSON into the text input. Send the request, and a JSON Object Example will be returned as the response. The response may come as a shock, but it is expected because the code for handling the JSON data is missing. Let us add that code.
Code to read the incoming JSON data:
Before we add the code we need to perform some settings. First we will assign everything from JSON object into a variable by using request.get_json()
functionality. This will convert the JSON object into Python data. Now assign the incoming request data into variables and return by making following modifications in the JSON-example route.
# GET requests will be blocked @app.route('/json-example', methods=['POST']) def json_example(): request_data = request.get_json() language = request_data['language'] framework = request_data['framework'] # two keys are needed because of the nested object python_version = request_data['version_info']['python'] # an index is needed because of the array example = request_data['examples'][0] boolean_test = request_data['boolean_test'] return ''' The language value is: {} The framework value is: {} The Python version is: {} The item at index 0 in the example list is: {} The boolean value is: {}'''.format(language, framework, python_version, example, boolean_test)
Why do JSON data requests fail?
JSON object requests primarily fail when the key that is accessed in the view function is missing. Before sending a request, make sure that the key is present in it to avoid such a situation. Once the presence of the key is conformed, run the app and send the JSON request using Postman.
# GET requests will be blocked @app.route('/json-example', methods=['POST']) def json_example(): request_data = request.get_json() language = None framework = None python_version = None example = None boolean_test = None if request_data: if 'language' in request_data: language = request_data['language'] if 'framework' in request_data: framework = request_data['framework'] if 'version_info' in request_data: if 'python' in request_data['version_info']: python_version = request_data['version_info']['python'] if 'examples' in request_data: if (type(request_data['examples']) == list) and (len(request_data['examples']) > 0): example = request_data['examples'][0] if 'boolean_test' in request_data: boolean_test = request_data['boolean_test'] return ''' The language value is: {} The framework value is: {} The Python version is: {} The item at index 0 in the example list is: {} The boolean value is: {}'''.format(language, framework, python_version, example, boolean_test)
Output:
The language value is: Python The framework value is: Flask The Python version is: 3.9 The item at index 0 in the example list is: query The boolean value is: false