DevNet Associate (DEVASC v1.0) Skills Assessment Answers

DEVASC v1.0 Skills Assessment

Objectives

  • Part 1: Collect Required API Documentation
  • Part 2: Code a Webex Teams Bot

Background / Scenario

Python can be used to integrate API calls from different services. In this Skills Assessment, you will edit and modify Python code for a Webex Teams bot that integrates Webex, MapQuest, and ISS APIs. The code continuously checks for messages in a user specified Webex Teams room that begins with a forward slash (/) followed by a city name (e.g. /Washington, DC). When such a message is found, the city name is extracted and used with the MapQuest API service to get the GPS coordinates for the specified city. Next, thesecoordinates are used with the ISS API to find the date and time of the next time the ISS will fly over. Finally, a message is sent back to the Webex Teams room informing the user about the next flyover of the ISS for the queried city.

When completed, the Webex Teams bot will:

• Ask the user for their access token or to use the hard-coded access token.
• Display a list of the user’s Webex Teams rooms.
• Ask the user which Webex Teams room to monitor for queries starting with “/”.
• Extract the city name of a message starting with “/” (e.g. /Washington, DC -> Washington, DC).
• Request the latitude and longitude of a specified city using the MapQuest API.
• Request the next flyover date and time using the ISS API.
• Send the next ISS flyover information back to the specified Webex Teams room.

Required Resources

• 1 PC with operating system of your choice
• MapQuest and Webex Teams developer access and API keys
• Virtual Box or VMWare
• DEVASC Virtual Machine
• The devasc-sa.py student script.

Note: To protect application environments like Webex Teams from bots or malicious access attempts, most APIs rate limit availability. If you make a large number of the same API calls, your API call may be blocked for a specific amount of time. The timeout is usually less than 5 minutes.

Instructions

Part 1: Collect Required API Documentation

In this Part, you will collect information from the Webex, MapQuest, and ISS API documentation. This information will be required in Part 2 when you are coding the Webex Teams bot. You will also investigate the Python time library that you will use to convert epoch timestamps to a human readable date and time.

Step 1: Launch the DEVASC VM.

Although you can complete this Skills Assessment in other environments, these instructions are for the DEVASC VM only. Instructions for other environments are not included.

Step 2: Investigate the documentation for Webex Teams rooms and message APIs.

a. Login to your developer account for Webex.

b. Locate and copy your personal access token. What is the lifetime for your token? _____________

c. Find the URL that will list all the rooms to which you belong. Record the HTTP method and URL:
______________________________________________________________________________

d. Find the URL that list all the messages for a specified room. Record the HTTP method and URL:
______________________________________________________________________________

e. Find the URL that will create a message for a specified room. Record the HTTP method and URL.
______________________________________________________________________________

Step 3: Investigate the locations key for the MapQuest address API.

a. Login to your developer account for MapQuest.

b. Locate and copy your Consumer Key. When does your key expire? __________________

The Webex Teams bot will use location data returned by a call to the MapQuest address API.

c. Open Chromium and paste in the following URL, replacing your_api_key with your MapQuest key:

https://www.mapquestapi.com/geocoding/v1/address?key=your_api_key&location=Washington,DC

d. Notice that the MapQuest locations key includes keys for latitude and longitude for the location you entered. Record the lat and lng values returned by MapQuest for Washington, D.C in the code below.

{
   "info": {
       "statuscode": 0,
       "copyright": {
           "text": "© 2020 MapQuest, Inc.",
           "imageUrl": "http://api.mqcdn.com/res/mqlogo.gif",
           "imageAltText": "© 2020 MapQuest, Inc."
       },
       "messages": []
   },
   "options": {
       "maxResults": -1,
       "thumbMaps": true,
       "ignoreLatLngInput": false
   },
   "results": [
       {
            "providedLocation": {
                 "location": "Washington,DC"
       },
      "locations": [
          {
            "street": "",
            "adminArea6": "",
            "adminArea6Type": "Neighborhood",
            "adminArea5": "Washington",
            "adminArea5Type": "City",
            "adminArea4": "District of Columbia",
            "adminArea4Type": "County",
            "adminArea3": "DC",
            "adminArea3Type": "State",
            "adminArea1": "US",
            "adminArea1Type": "Country",
            "postalCode": "",
            "geocodeQualityCode": "A5XAX",
            "geocodeQuality": "CITY",
            "dragPoint": false,
            "sideOfStreet": "N",
            "linkId": "282772166",
            "unknownInput": "",
            "type": "s",
            "latLng": {
                "lat": 38.892062,
                "lng": -77.019912
            },
            "displayLatLng": {
                "lat": ______________,
                "lng": ______________
            },
<output omitted>
             }
          ]
      }
   ]
}
Step 4: Investigate the documentation for the ISS pass times API.

a. Search for “ISS API documentation” on the internet.

b. On the ISS API documentation website, click the API documentation for ISS Pass Times.

c. What are the two required parameters (called query strings on the website) for the ISS pass times API?
______________________________________________________________________________

d. What are the optional parameters for the ISS pass times API?
______________________________________________________________________________

e. What is the URL for the ISS pass times API?
______________________________________________________________________________

Step 5: Investigate the response key for the ISS pass times API.

a. Open Postman and create a new Untitled Request.

b. Paste in the ISS pass times URL.

c. Replace the latitude and longitude values with the values for Washington, D.C.

d. Click Send. You should get output similar to the following, although your time values will be different. By default, the ISS pass times API returns the next 5 passes over the specified location.

{
  "message": "success",
  "request": {
    "altitude": 100,
    "datetime": 1592669962,
    "latitude": ______________,
    "longitude": _____________,
    "passes": 5
  },
  "response": [
    {
      "duration": 602,
      "risetime": 1592672814
    },
    {
      "duration": 649,
      "risetime": 1592678613
    },
    {
      "duration": 423,
      "risetime": 1592684494
    },
    {
      "duration": 475,
      "risetime": 1592733041
    },
    {
      "duration": 651,
      "risetime": 1592738727
    }
  ]
}
Step 6: Investigate epoch timestamps and how to convert them to a human readable format.

In Part 2, you will use the ctime function of the Python time library to convert epoch time into a human readable date and time. That date and time will then be incorporated in a message that the Webex Teams bot posts to a room.

Search the internet for documentation of the Python time library to answer the following questions.
Preferably, you should review documentation from python.org although answers can be found elsewhere.

a. In relation to computer time, what does the term “epoch” mean?
______________________________________________________________________________

b. What function of the time library will return the epoch time on a given platform?
______________________________________________________________________________

c. You can see the year, month, day, hour, and so on for the start of the epoch with the following Python code. Open a terminal, start Python 3, import the time library, and then replace <function> with the function you found above.

[email protected]:~$ python3
Python 3.8.2 (default, Apr 27 2020, 15:53:34)
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import time
>>> print(str(___________________))
time.struct_time(tm_year=1970, tm_mon=1, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=0,
tm_wday=3, tm_yday=1, tm_isdst=0)
>>>

d. The DEVASC VM epoch start time is the same as for Unix. When does the epoch start?
______________________________________________________________________________

e. The risetime in Step 4 is expressed in the number of seconds since the epoch time. What time function will convert the risetime to a human readable format?
______________________________________________________________________________

f. What is the date for the first risetime in Step 4?

>>> print(str(__________________________)))
<Date and Time is printed here>
>>>

Part 2: Code a Webex Teams Bot

Note: You will need the devasc-sa.py script open and ready to edit for this Part. Obtain this script from your instructor.

In this Part, you will use your understanding of Python and REST APIs along with the API documentation you gathered in Part 1 to finish the code for the Webex Teams bot.

Hint: Save the original file as a different name in case you need to start over. Comment out the code you are not yet testing. As you work through the following steps, save and run your script often. Use temporary print statements to verify that your variables contain the data you expect.

Step 1: Import libraries for API requests, JSON formatting, and epoch time conversion.
Step 2: Complete the if statement to ask the user for the Webex access token.

For this step, you are provided with the first user prompt and the else portion of an if/else statement. You need to code the if portion of the statement that will execute if the user says “N” or “n” to using the hardcoded access token. The if statement checks the value of choice, then if “N” or “n” are entered, asks the user for the value of the token. The user-entered value is then stored in the accessToken variable. The accessToken variable should be constructed just like the version of the else statement.

Step 3: Provide the URL to the Webex Teams room API.

Use your documentation from Part 1 to specify the correct Webex Teams room API that will return a list of the rooms that you are a member of and store them in the r variable.

Step 4: Finish the loop to print the type and title of each room.

The list of rooms stored in the r variable is converted to JSON and stored in the rooms variable. Add a print statement that will display each room type and title.

Step 5: Provide the URL to the Webex Teams messages API.

Use your documentation from Part 1 to specify the correct Webex Teams messages API. Every second, the bot will make a call to this API and print the latest message posted to the room.

Step 6: Provide your MapQuest API consumer key.

You documented this key in Part 1.

Step 7: Provide the URL to the MapQuest address API.
Step 8: Provide the MapQuest key values for latitude and longitude.

Use your documentation in Part 1 to specify the correct format to store the values for the latitude and longitude keys.

Step 9: Provide the URL to the ISS pass times API.

Use your documentation from Part 1 to specify the correct ISS pass times API.

Step 10: Provide the ISS key values for risetime and duration.

Use your documentation in Part 1 to specify the correct format to store the values for the risetime and duration keys.

Step 11: Convert the risetime epoch value to a human readable date and time.

In Part 1, you researched the time library. Use your knowledge to convert the epoch value for risetime into a human readable data and time format.

Step 12: Complete the code to format the response message.

Use the variables that have been specified to format the response message that will be sent to the Webex Teams room. For example, a posted message in the room would look like the following where the location, risetime, and duration are shown in bold.

In Austin, Texas the ISS will fly over on Thu Jun 18 18:42:36 2020 for 242 seconds.

Step 13: Complete the code to post the message to the Webex Teams room.

The final step in the Webex Teams bot program is to format the API POST message that will send the responseMessage to the Webex Teams room. Provide each of the required variables and the URL for the Webex Teams message API to complete the code.

Step 14: Run your program, test it, and troubleshoot as necessary.

a. In your Webex Teams client, create a room with a name of your choice, such as My DEVASC SA Room.

b. Post a message, such as Hello room!, to populate the room with at least one message.

c. Run your program and choose My DEVASC SA Room as the room the Webex Teams bot will monitor.

d. In the My DEVASC SA Room, post a location in the format /location. Messages that begin with a forward slash initiate the Webex Team bot to do its work. For example, the following should occur when Austin, Texas is entered.

In a terminal window:

[email protected]:~/$ python3 devasc-sa_sol.py
Do you wish to use the hard-coded Webex token? (y/n)y
List of rooms:
Type: 'group' Name: My DEVASC SA Room
<rest of rooms listed>
Which room should be monitored for /location messages? My DEVASC SA Room
Found rooms with the word My DEVASC SA Room
My DEVASC SA Room
Found room : My DEVASC SA Room
Received message: Hello room!
Received message: Hello room!
Received message: Hello room!
Received message: Hello room!
<continues to print every 1 second>

In Webex Teams My DEVASC SA Room, add a location.

/Austin, Texas

In the terminal window, the following prints:

Received message: /Austin, Texas
Location: Austin, Texas
Location GPS coordinates: 30.264979, -97.746598
Sending to Webex Teams: In Austin, Texas the ISS will fly over on Sat Jun 20 20:18:29 2020 for 645 seconds.
Received message: In Austin, Texas the ISS will fly over on Sat Jun 20 20:18:29 2020 for 645 seconds.
Received message: In Austin, Texas the ISS will fly over on Sat Jun 20 20:18:29 2020 for 645 seconds.
Received message: In Austin, Texas the ISS will fly over on Sat Jun 20 20:18:29 2020 for 645 seconds.
Received message: In Austin, Texas the ISS will fly over on Sat Jun 20 20:18:29 2020 for 645 seconds.
<continues to print every 1 second>

In Webex Teams, to following displays.

In Austin, Texas the ISS will fly over on Sat Jun 20 20:18:29 2020 for 645 seconds.

e. In your terminal window, enter Ctrl+C to exit the program.

Student Script

Below is the content of the devasc-sa.py script. However, we recommend that you use the devasc-sa.py file you obtain from your instructor. Copying and pasting the following script from a PDF or Word document can be problematic.

WARNING: You are responsible for correcting the code formatting errors if you choose to copy and paste the following

###############################################################
# This program:
# - Asks the user to enter an access token or use the hard coded access token.
# - Lists the user's Webex Teams rooms.
# - Asks the user which Webex Teams room to monitor for "/location" requests.
# - Monitors the selected Webex Team room every second for "/location" messages.
# - Discovers GPS coordinates for the "location" using MapQuest API.
# - Discovers the date and time of the next ISS flyover over the "location" using the
ISS API
# - Formats and sends the results back to the Webex Team room.
#
# The student will:
# 1. Import libraries for requests, json, and time.
# 2. Complete the if statement to ask the user for the Webex access token.
# 3. Provide the URL to the Webex Teams room API.
# 4. Create a loop to print the type and title of each room.
# 5. Provide the URL to the Webex Teams messages API.
# 6. Provide your MapQuest API consumer key.
# 7. Provide the URL to the MapQuest address API.
# 8. Provide the MapQuest key values for latitude and longitude.
# 9. Provide the URL to the ISS pass times API.
# 10. Provide the ISS key values risetime and duration.
# 11. Convert the risetime epoch value to a human readable date and time.
# 12. Complete the code to format the response message.
# 13. Complete the code to post the message to the Webex Teams room.
###############################################################

# 1. Import libraries for requests, json, and time.

<!!!REPLACEME with code for libraries>

# 2. Complete the if statement to ask the user for the Webex access token.
choice = input("Do you wish to use the hard-coded Webex token? (y/n) ")

<!!!REPLACEME with if statements to ask user for the Webex Teams Access Token!!!>
else:
      accessToken = "Bearer <!!!REPLACEME with hard-coded token!!!>"

# 3. Provide the URL to the Webex Teams room API.
r = requests.get( "<!!!REPLACEME with URL!!!>",
                  headers = {"Authorization": accessToken}
                )

#####################################################################################
# DO NOT EDIT ANY BLOCKS WITH r.status_code
if not r.status_code == 200:
    raise Exception("Incorrect reply from Webex Teams API. Status code: {}. Text:
{}".format(r.status_code, r.text))
######################################################################################

# 4. Create a loop to print the type and title of each room.
print("List of rooms:")
rooms = r.json()["items"]
for room in rooms:
    <!!!REPLACEME with print code to finish the loop>

######################################################################################
#
# SEARCH FOR WEBEX TEAMS ROOM TO MONITOR
# - Searches for user-supplied room name.
# - If found, print "found" message, else prints error.
# - Stores values for later use by bot.
# DO NOT EDIT CODE IN THIS BLOCK
######################################################################################
#

while True:
    roomNameToSearch = input("Which room should be monitored for /location messages?
")
    roomIdToGetMessages = None

    for room in rooms:
        if(room["title"].find(roomNameToSearch) != -1):
        print ("Found rooms with the word " + roomNameToSearch)
        print(room["title"])
        roomIdToGetMessages = room["id"]
        roomTitleToGetMessages = room["title"]
        print("Found room : " + roomTitleToGetMessages)
        break

if(roomIdToGetMessages == None):
    print("Sorry, I didn't find any room with " + roomNameToSearch + " in it.")
    print("Please try again...")
else:
    break

######################################################################################
# WEBEX TEAMS BOT CODE
# Starts Webex bot to listen for and respond to /location messages.
######################################################################################

while True:
    time.sleep(1)
    GetParameters = {
                         "roomId": roomIdToGetMessages,
                         "max": 1
                    }
# 5. Provide the URL to the Webex Teams messages API.
    r = requests.get("<!!!REPLACEME with URL!!!>",
                         params = GetParameters,
                         headers = {"Authorization": accessToken}
                    )

    if not r.status_code == 200:
          raise Exception( "Incorrect reply from Webex Teams API. Status code: {}. Text:
{}".format(r.status_code, r.text))

    json_data = r.json()
    if len(json_data["items"]) == 0:
         raise Exception("There are no messages in the room.")
    messages = json_data["items"]
    message = messages[0]["text"]
    print("Received message: " + message)

    if message.find("/") == 0:
        location = message[1:]
# 6. Provide your MapQuest API consumer key.
        mapsAPIGetParameters = {
                                     "location": location,
                                     "key": "<!!!REPLACEME with your MapQuest API Key!!!>"
                                }
# 7. Provide the URL to the MapQuest address API.
        r = requests.get("<!!!REPLACEME with URL!!!>",
                              params = mapsAPIGetParameters
                         )
        json_data = r.json()

        if not json_data["info"]["statuscode"] == 0:
            raise Exception("Incorrect reply from MapQuest API. Status code:
{}".format(r.statuscode))

        locationResults = json_data["results"][0]["providedLocation"]["location"]
        print("Location: " + locationResults)

# 8. Provide the MapQuest key values for latitude and longitude.
        locationLat = json_data["<!!!REPLACEME!!!> with path to latitude key!!!>"]
        locationLng = json_data["<!!!REPLACEME!!!> with path to longitude key!!!>"]
        print("Location GPS coordinates: " + str(locationLat) + ", " +
str(locationLng))

        issAPIGetParameters = {
                                    "lat": locationLat,
                                    "lon": locationLng
                              }
# 9. Provide the URL to the ISS pass times API.
        r = requests.get("<!!!REPLACEME with URL!!!>",
                              params = issAPIGetParameters
                        )

        json_data = r.json()

        if not "response" in json_data:
             raise Exception("Incorrect reply from open-notify.org API. Status code:
{}. Text: {}".format(r.status_code, r.text))

# 10. Provide the ISS key values risetime and duration.
        risetimeInEpochSeconds = json_data["<!!!REPLACEME!!!> with path to risetime
key!!!>"]
        durationInSeconds = json_data["<!!!REPLACEME!!!> with path to duration
key!!!>"]

# 11. Convert the risetime epoch value to a human readable date and time.
        risetimeInFormattedString = <!!!REPLACEME with conversion code!!!>

# 12. Complete the code to format the response message.
#     Example responseMessage result: In Austin, Texas the ISS will fly over on Thu
Jun 18 18:42:36 2020 for 242 seconds.
        responseMessage = "In {} the ISS will fly over on {} for {}
seconds.".format(<!!!REPLACEME with required variables!!!>)

print("Sending to Webex Teams: " +responseMessage)
# 13. Complete the code to post the message to the Webex Teams room.
         HTTPHeaders = {
                               "Authorization": <!!!REPLACEME!!!>,
                               "Content-Type": "application/json"
                       }
         PostData = {
                               "roomId": <!!!REPLACEME!!!>,
                               "text": <!!!REPLACEME!!!>
                      }
         r = requests.post( "<!!!REPLACEME with URL!!!>",
                               data = json.dumps(<!!!REPLACEME!!!>),
                               headers = <!!!REPLACEME!!!>
                          )
         if not r.status_code == 200:
                 raise Exception("Incorrect reply from Webex Teams API. Status code: {}.
Text: {}".format(r.status_code, r.text))

 

 


Related Articles

guest
2 Comments
Inline Feedbacks
View all comments
Icha
Icha
9 days ago

hi, there are no answers :(

Irakli
Irakli
2 months ago

Hello when will be the answers avaible ?