1.3.3.1 Lab - Parsing JSON With A Python Application
1.3.3.1 Lab - Parsing JSON With A Python Application
Objectives
• Obtain a MapQuest API Key.
• Import necessary modules.
• Create API request variables and construct a URL.
• Add user input functionality.
• Add a quit feature so that the user can end the application.
• Display trip information for time, distance, and fuel usage.
• Iterate through the JSON data to extract and output the directions.
• Display error messages for invalid user input.
Background / Scenario
In this lab, you will create an application that retrieves JSON data from the MapQuest Directions API, parses
the data, and formats it for output to the user. You will use the GET Route request from the MapQuest
Directions API. Review the GET Route Directions API documentation here:
https://developer.mapquest.com/documentation/directions-api/route/get/
Note: If the above link no longer works, search for “MapQuest API Documentation”.
Required Resources
• Computer with Python installed according to the Lab - PC Setup for Workshop.
• Access to the Internet.
© 2017 - 2018 Cisco and/or its affiliates. All rights reserved. Cisco Confidential Page 1 of 14 www.netacad.com
Lab - Parsing JSON with a Python Application
=============================================
Start out going north on 6th St/US-50 E/US-1 N toward Pennsylvania Ave/US-1 Alt N.
(1.28 km)
Turn right onto New York Ave/US-50 E. Continue to follow US-50 E (Crossing into
Maryland). (7.51 km)
Take the Balt-Wash Parkway exit on the left toward Baltimore. (0.88 km)
Merge onto MD-295 N. (50.38 km)
Turn right onto W Pratt St. (0.86 km)
Turn left onto S Calvert St/MD-2. (0.43 km)
Welcome to BALTIMORE, MD. (0.00 km)
=============================================
Note: To see the JSON for the above output, you will need to replace your_api_key with the MapQuest API
key you obtain in Step 3.
© 2017 - 2018 Cisco and/or its affiliates. All rights reserved. Cisco Confidential Page 2 of 14 www.netacad.com
Lab - Parsing JSON with a Python Application
b. Combine the four variables main_api, orig, dest, and key to format the requested URL. Use the
urlencode method to properly format the address value. This function builds the parameters part of the
URL and converts possible special characters in the address value (e.g. space into “+” and a comma into
“%2C”).
url = main_api + urllib.parse.urlencode({"key": key, "from":orig, "to":dest})
c. Create a variable to hold the reply of the requested URL and print the returned JSON data. The
json_data variable holds a Python’s Dictionary representation of the json reply of the get method of the
requests module. The print statement is used to check the returned data.
json_data = requests.get(url).json()
print(json_data)
© 2017 - 2018 Cisco and/or its affiliates. All rights reserved. Cisco Confidential Page 3 of 14 www.netacad.com
Lab - Parsing JSON with a Python Application
[output omitted]
>>>
b. Change the orig and dest variables. Rerun the script to get different results.
Step 7: Print the URL and check the status of the JSON request.
Now that you know the JSON request is working, you can add some more functionality to the application.
a. Save your script as 08_json-parse2.py.
b. Delete the print(json_data) statement as you no longer need to test that the request is properly
formatted.
c. Add the statements below, which will do the following:
o Print the constructed URL so that the user can see the exact request made by the application.
o Parse the JSON data to obtain the statuscode value.
o Start an if loop that checks for a successful call, which a value of 0. Add a print statement to display
the statuscode value and its meaning. The \n adds a blank line below the output.
print("URL: " + (url))
json_data = requests.get(url).json()
json_status = json_data["info"]["statuscode"]
if json_status == 0:
print("API Status: " + str(json_status) + " = A successful route call.\n")
Later in this lab, you will add elif and else statements for different statuscode values.
>>>
© 2017 - 2018 Cisco and/or its affiliates. All rights reserved. Cisco Confidential Page 4 of 14 www.netacad.com
Lab - Parsing JSON with a Python Application
json_data = requests.get(url).json()
json_status = json_data["info"]["statuscode"]
if json_status == 0:
print("API Status: " + str(json_status) + " = A successful route call.\n")
© 2017 - 2018 Cisco and/or its affiliates. All rights reserved. Cisco Confidential Page 5 of 14 www.netacad.com
Lab - Parsing JSON with a Python Application
Destination: quit
>>>
Step 13: Parse and display some data about the trip.
a. Copy your URL into your web browser. If you collapse all the JSON data, you will see that there are two
root dictionaries: route and info.
b. Expand the route dictionary and investigate the rich data. There are values to indicate whether the route
has toll roads, bridges, tunnels, highways, closures, or crosses into other countries. You should also see
values for distance, the total time the trip will take, and fuel usage, as highlighted below. To parse and
display this, specify the route dictionary and select key/value pair you want to print.
© 2017 - 2018 Cisco and/or its affiliates. All rights reserved. Cisco Confidential Page 6 of 14 www.netacad.com
Lab - Parsing JSON with a Python Application
Destination: Baltimore
URL:
https://www.mapquestapi.com/directions/v2/route?to=Baltimore&key=Your_api_key&from=Was
hington
API Status: 0 = A successful route call.
=============================================
Directions from Washington to Baltimore
Trip Duration: 00:49:19
Miles: 38.089
Fuel Used (Gal): 1.65
=============================================
Starting Location: q
>>>
g. MapQuest uses the imperial system and there is not a request parameter to change data to the metric
system. Therefore, you should probably convert your application to display metric values, as shown
below.
print("Kilometers: " + str((json_data["route"]["distance"])*1.61))
print("Fuel Used (Ltr): " + str((json_data["route"]["fuelUsed"])*3.78))
=============================================
Directions from Washington to Baltimore
Trip Duration: 00:49:19
Kilometers: 61.32329
Fuel Used (Ltr): 6.236999999999999
=============================================
Starting Location: q
>>>
i. Use the "{:.2f}".format argument to format the float values to 2 decimal places before converting them to
string values, as shown below. Each statement should be on one line.
print("Kilometers: " +
str("{:.2f}".format((json_data["route"]["distance"])*1.61)))
print("Fuel Used (Ltr): " +
str("{:.2f}".format((json_data["route"]["fuelUsed"])*3.78)))
© 2017 - 2018 Cisco and/or its affiliates. All rights reserved. Cisco Confidential Page 7 of 14 www.netacad.com
Lab - Parsing JSON with a Python Application
URL:
https://www.mapquestapi.com/directions/v2/route?key=Your_api_key&to=Baltimore&from=Was
hington
API Status: 0 = A successful route call.
=============================================
Directions from Washington to Baltimore
Trip Duration: 00:49:19
Kilometers: 61.32
Fuel Used (Ltr): 6.24
=============================================
Starting Location: q
>>>
© 2017 - 2018 Cisco and/or its affiliates. All rights reserved. Cisco Confidential Page 8 of 14 www.netacad.com
Lab - Parsing JSON with a Python Application
© 2017 - 2018 Cisco and/or its affiliates. All rights reserved. Cisco Confidential Page 9 of 14 www.netacad.com
Lab - Parsing JSON with a Python Application
c. Expand the first dictionary in the maneuvers list. Each dictionary contains a narrative key with a value,
such as “Start out going north...”, as shown below. You need to parse the JSON data to extract the value
for the narrative key to display inside your application.
Step 16: Add a for loop to iterate through the maneuvers JSON data.
Complete the following steps to update your application:
a. Save your script as 08_json-parse6.py.
b. Add a for loop below the second double line print statement. The for loop iterates through each
maneuvers list and does the following:
1) Prints the narrative value.
2) Converts miles to kilometers with *1.61.
3) Formats the kilometer value to print only two decimal places with the "{:.2f}".format function.
c. Add a print statement that will display a double line before the next request for a starting location, as
shown below.
Note: The second double line print statement is not indented within the for loop. It therefore is part of the
previous if statement that checks the statuscode parameter.
print("Fuel Used (Ltr): " + str("{:.2f}".format((json_data["route"]["fuelUsed"])*3.78)))
print("=============================================")
for each in json_data["route"]["legs"][0]["maneuvers"]:
print((each["narrative"]) + " (" + str("{:.2f}".format((each["distance"])*1.61) + " km)"))
print("=============================================\n")
© 2017 - 2018 Cisco and/or its affiliates. All rights reserved. Cisco Confidential Page 10 of 14 www.netacad.com
Lab - Parsing JSON with a Python Application
Starting Location: q
>>>
if json_status == 0:
print("API Status: " + str(json_status) + " = A successful route call.\n")
a. But what happens if the statuscode is not equal to 0? For example, the user might enter an invalid
location or might not enter one or more locations. If so, then the application displays the URL and asks for
a new starting location. The user has no idea what happened. Try the following values in your application.
You should see similar results.
Starting Location: Washington
Destination: Beijing
URL:
https://www.mapquestapi.com/directions/v2/route?to=Beijing&key=your_api_key&from=Washi
ngton
Starting Location: Washington
Destination: Balt
© 2017 - 2018 Cisco and/or its affiliates. All rights reserved. Cisco Confidential Page 11 of 14 www.netacad.com
Lab - Parsing JSON with a Python Application
URL:
https://www.mapquestapi.com/directions/v2/route?to=Balt&key=your_api_key&from=Washingt
on
Starting Location: Washington
Destination:
URL:
https://www.mapquestapi.com/directions/v2/route?to=&key=your_api_key&from=Washington
Starting Location: q
The elif statement prints if the statuscode value is 402 for an invalid location. The else statement prints
for all other statuscode values, such as no entry for one or more locations. The else statement ends the
if/else loop and returns the application to the while loop.
© 2017 - 2018 Cisco and/or its affiliates. All rights reserved. Cisco Confidential Page 12 of 14 www.netacad.com
Lab - Parsing JSON with a Python Application
Take the Balt-Wash Parkway exit on the left toward Baltimore. (0.88 km)
Merge onto MD-295 N. (50.38 km)
Turn right onto W Pratt St. (0.86 km)
Turn left onto S Calvert St/MD-2. (0.43 km)
Welcome to BALTIMORE, MD. (0.00 km)
=============================================
****************************************************************
Status Code: 402; Invalid user inputs for one or both locations.
****************************************************************
************************************************************************
Status Code: 602; Refer to:
https://developer.mapquest.com/documentation/directions-api/status-codes
************************************************************************
© 2017 - 2018 Cisco and/or its affiliates. All rights reserved. Cisco Confidential Page 13 of 14 www.netacad.com
Lab - Parsing JSON with a Python Application
************************************************************************
Status Code: 611; Refer to:
https://developer.mapquest.com/documentation/directions-api/status-codes
************************************************************************
Starting Location: q
>>>
© 2017 - 2018 Cisco and/or its affiliates. All rights reserved. Cisco Confidential Page 14 of 14 www.netacad.com