Skip to content

Lab 4 - REST APIsπŸ”—

Lab 4.1 Set up GitHub Repository
Lab 4.2 Explore REST APIs with API Simulator and Postman
Lab 4.3 Integrate a REST API in a Python Application

4.1 Set up GitHub RepositoryπŸ”—

ObjectivesπŸ”—

    Part 1: Join the GitHub Classroom
    Part 2: Clone the Remote Repository

InstructionsπŸ”—

Part 1. Join the GitHub ClassroomπŸ”—

  1. Follow the GitHub assignment link posted in Canvas. If you did not complete the setup in Lab 2.2 you will need to authorize GitHub Classroom to link with your account and select your name from the list of students.

  2. Accept the assignment and refresh the page until it says your repository has been created. Click the link to proceed to the repository.

  3. Select the "Code" dropdown and copy the HTTPS URL. Store it somewhere for use in the next step.

Note

If you’ve configured your VM to use SSH to connect to GitHub instead of HTTPS, click on the Code dropdown, select the SSH tab, and copy the URL from there instead.

Part 2. Clone the Remote RepositoryπŸ”—

  1. On the DEVASC VM, create a new folder called graphhopper in ~/labs/devnet-src directory.

    devasc@labvm:~$ mkdir ~/labs/devnet-src/graphhopper
    
  2. Change into the graphhopper directory.

    devasc@labvm:~$ cd labs/devnet-src/graphhopper/
    
  3. Use git clone to clone a copy of your Lab 4 repository into the graphhopper directory. Use the URL to the GitHub Classroom repository you copied at the end of Part 1, not the one in the command below.

    Warning

    DON’T MISS THE EXTRA PERIOD AT THE END OF THE COMMAND!

    devasc@labvm:~/labs/devnet-src/graphhopper$ git clone https://github.com/Ontario-Tech-NITS/lab-4-rest-apis-<username>.git .
    Cloning into '.'...
    Username for 'https://github.com': <username>
    Password for 'https://<username>@github.com': 
    remote: Enumerating objects: 12, done.
    remote: Counting objects: 100% (12/12), done.
    remote: Compressing objects: 100% (10/10), done.
    remote: Total 12 (delta 1), reused 2 (delta 0), pack-reused 0 (from 0)
    Receiving objects: 100% (12/12), 4.70 KiB | 1.18 MiB/s, done.
    Resolving deltas: 100% (1/1), done.
    

    Note

    If you’ve configured your VM to use SSH to connect to GitHub, use the SSH URL that you copied in step 1, rather than the HTTPS link.

  4. Verify that the local folder now contains the files from the GitHub repository.

    devasc@labvm:~/labs/devnet-src/graphhopper$ ls -la
    total 24
    drwxrwxr-x  4 devasc devasc 4096 Feb 11 03:33 .
    drwxr-xr-x 16 devasc devasc 4096 Feb 11 03:31 ..
    -rw-rw-r--  1 devasc devasc 1297 Feb 11 03:33 add100RandomBooks.py
    drwxrwxr-x  7 devasc devasc 4096 Feb 11 03:33 .git
    drwxrwxr-x  2 devasc devasc 4096 Feb 11 03:33 .github
    -rw-rw-r--  1 devasc devasc  773 Feb 11 03:33 README.md
    
  5. Verify that the remote repository values were automatically set correctly.

    devasc@labvm:\~/labs/devnet-src/mapquest\$ git remote -v
    origin https://github.com/Ontario-Tech-NITS/lab-4-rest-apis-\<username\>.git (fetch)
    origin https://github.com/Ontario-Tech-NITS/lab-4-rest-apis-\<username\>.git (push)
    
  6. Use git status to verify you are on the main branch and that you are don't have anything to commit.

    devasc@labvm: :\~/labs/devnet-src/unittest\$ git status
    On branch main
    Your branch is up to date with \'origin/main\'.
    
    nothing to commit, working tree clean
    

4.2 Explore REST APIs with API Simulator and PostmanπŸ”—

ObjectivesπŸ”—

    Part 1: Explore API Documentation Using the API Simulator
    Part 2: Use Postman to Make API Calls to the API Simulator
    Part 3: Use Python to Add 100 Books to the API Simulator

BackgroundπŸ”—

The DEVASC VM includes a School Library API simulator with API documentation and an associated database. You can use the simulator offline to explore APIs and test their functionality.

In this lab, you will learn how to use the School Library API simulator to make API calls to list, add, and delete books. Later, you will use Postman to make these same API calls.

InstructionsπŸ”—

Part 1: Explore API Documentation Using the API SimulatorπŸ”—

To understand how to make calls to a REST API, developers typically start by studying the API documentation. The format for requests, responses, headers, and parameter for REST APIs are typically documented using the OpenAPI Specification (formerly Swagger Specification).

Step 1: Open the Chromium Web BrowserπŸ”—

  1. Double-click the Chromium Web Browser icon on the desktop.

Step 2: Connect to the School Library Web SiteπŸ”—

  1. If the browser does not automatically open the School Library website, in the address bar type: library.demo.local and press return to go there.

Step 3: Go to the API docs pageπŸ”—

  1. The web site defaults to the Our Books tab and displays a list of books. In the upper right corner where it states, Click here for API docs, click the word here to go to the API documentation web page.

    You will now see a list of APIs in the /api/v1 Default namespace.

  2. Notice the downward arrow to the far right. Clicking anywhere on the /api/v1 bar will minimize the API list and turn the arrow facing right. Click again on the same bar to re-display the API list.

    Notice the lock to the far right of several of the APIs. The lock indicates that these APIs require a token to be used.

Step 4: List books using the GET /books APIπŸ”—

  1. Click anywhere on the bar for the GET /books API. This API returns a list of books in the school library.

    • Parameters - There are several optional API parameters. These can be used to filter, sort, or paginate the output. These will be referred to later in this lab.
    • Response content type - Click application/json to see a list of the different types of data formats the information can be viewed. Leave the selection as application/json.
    • Code - The code displays 200 by default, which indicates the API request from the sever was a success as displayed in the Description. (You have not sent an API request yet.)

Step 5: Use the Try it out feature in the API documentationπŸ”—

One of the more powerful features of the OpenAPI Specification is the ability to test an API call to see if you constructed it correctly. You can also review the response to see if it is what you expected. You will see this same testing feature in API documentation for Cisco, Canvas, and other organizations that use this OpenAPI Specification feature.

  1. In the GET /books API documentation, click the Try it out button.

  2. Notice that you now have the option to enter information for the optional parameters. Leave the parameters blank and click the Execute button.

    In the Responses section you will see:

    • Curl: The curl command you can use to access the same information for the /books API.
    • Request URL: This URL is used in the API request, which can be used to request the same information using curl, Postman, and Python.
    • Code: This is the HTTP response code. 200 indicates a successful call.
    • Response body: List of books in JSON format.
    • Response headers: Information about the API returned from the server.

    In the Response body you will see a list of books in JSON format:

    [
        {
            "id": 0,
            "title": "IP Routing Fundamentals",
            "author": "Mark A. Sportack"
        },
        {
            "id": 1,
            "title": "Python for Dummies",
            "author": "Stef Maruch Aahz Maruch"
        },
        {
            "id": 2,
            "title": "Linux for Networkers",
            "author": "Cisco Systems Inc."
        },
        {
            "id": 3,
            "title": "NetAcad: 20 Years Of Online-Learning",
            "author": "Cisco Systems Inc."
        }
    ]
    

Step 6: Use the curl command in a terminal windowπŸ”—

The GET /books API provides information to access the content displayed in the response body using curl. curl is a command line tool to transfer data to or from a server, using any of the supported protocols including HTTP and HTTPS.

  1. Select the curl command, right-click and Copy it to your clipboard:

  2. Open a terminal window. Right-click and Paste the contents from the clipboard into the terminal and press Enter. Notice this provides the same information as the library's OpenAPI interface.

    devasc@labvm:~$ curl -X GET "http://library.demo.local/api/v1/books" -H "accept: application/json"
    [
        {
            "id": 0,
            "title": "IP Routing Fundamentals",
            "author": "Mark A. Sportack"
        },
        {
            "id": 1,
            "title": "Python for Dummies",
            "author": "Stef Maruch Aahz Maruch"
        },
        {
            "id": 2,
            "title": "Linux for Networkers",
            "author": "Cisco Systems Inc."
        },
        {
            "id": 3,
            "title": "NetAcad: 20 Years Of Online-Learning",
            "author": "Cisco Systems Inc."
        }
    ]
    devasc@labvm:~$
    

Step 7: List books with their ISBN using the GET /books APIπŸ”—

  1. Return to the School Library API web site's GET /books API.

  2. In the Parameters section, select the down arrow next to the includeISBN parameter and select true.

  3. Click Execute.

    Notice the following changes in Responses:

    • Curl now includes the parameter for ISBN.
      curl -X GET "http://library.demo.local/api/v1/books?includeISBN=true" -H "accept: application/json"
    • Request URL now includes the parameter for ISBN.
      http://library.demo.local/api/v1/books?includeISBN=true
    • Response body has the same list of books as shown previously but now includes the book's ISBN.

    To minimize the scrolling, when you are done with an API you can close that specific API window by clicking anywhere on the title bar. Now you can see all the APIs more easily.

Step 8: Get a token using the POST /loginViaBasic APIπŸ”—

  1. Click the API POST /loginViaBasic.

  2. Notice there are no parameters. Click Try it out, and then click Execute.

  3. A Sign in box will prompt you for a username and password. Enter the following information and click Sign in:

    • Username: cisco
    • Password: Cisco123!
  4. The token will be displayed in the Response body. Select the information between the quotes, right-click and Copy the information into your clipboard. Your token will differ from the one shown below.

    {
    "token": "cisco|KZZzteQbC5iV3HKEzB7hCJ6qHQXen4rLGh72YJKeVfs"
    }
    
  5. Scroll up to the top of the School Library API page and click the green Authorize button. The Available authorizations dialogue box will appear.

  6. Right-click and Paste the token after Value and click Authorize. Notice the Name is X-API-KEY. This information along with the token will be used later in Postman.

  7. Close the Available authorizations dialogue box and return to the list of APIs. Notice the locks by several of the APIs have now changed. These APIs are now available for you to use.

  8. Click the bar for the API POST /loginViaBasic to close the window.

Step 9: Add books using the POST /books APIπŸ”—

  1. Click the API POST /books.

    Notice under Parameters that the payload is required. This means that this API requires information for this parameter in the format specified by the Parameter content type, which is JSON.

  2. Click Try it out.

  3. Modify the id, title and author with the information shown below.

    {
    "id": 4,
    "title": "IPv6 Fundamentals",
    "author": "Rick Graziani"
    }
    
  4. Click Execute.

  5. Verify that the post was successful in the Server response.

    A Code of 200 means the post was a success. You should see the book you added in the Response body along with a new id. You will also see updated information for curl and the Request URL.

    Note

    If you got a 401 code, check the Response body text. Most likely you received an error: Invalid API key response. This is because you did not enter all the characters for your API key, or possibly, you added an unnecessary space. Return to the previous step and repeat the authorization process.

    To add another book, modify the id, title and author with the information shown below.

    {
    "id": 5,
    "title": "31 Days Before Your CCNA Exam",
    "author": "Allan Johnson"
    }
    
  6. Click Execute.

  7. Verify that the post was successful in the Server response. A Code of 200 means the post was a success. You should see the book you added in the Response body along with a new id. You will also see updated information for curl and the Request URL.

  8. Click the bar for the API POST /books to close the window.

  9. You can verify the books were added to the Our Books page. Return to the School Library tab in your browser (http://library.demo.local) and refresh the page. Be careful not to close the School Library API tab. If you do, then you will need to reauthenticate.

Step 10: List books using the GET /books APIπŸ”—

  1. Return to the School Library API tab in the browser. Click the GET /books API.

  2. Click Try it out. If you see Cancel button in red, then you are already in Try it out mode.

  3. Click Execute.

  4. Under Server response in the Response body, you will now see the two books you added. Notice they each have a unique id.

    [
        {
            "id": 0,
            "title": "IP Routing Fundamentals",
            "author": "Mark A. Sportack"
        },
        {
            "id": 1,
            "title": "Python for Dummies",
            "author": "Stef Maruch Aahz Maruch"
        },
        {
            "id": 2,
            "title": "Linux for Networkers",
            "author": "Cisco Systems Inc."
        },
        {
            "id": 3,
            "title": "NetAcad: 20 Years Of Online-Learning",
            "author": "Cisco Systems Inc."
        },
        {
            "id": 4,
            "title": "IPv6 Fundamentals",
            "author": "Rick Graziani"
        },
        {
            "id": 5,
            "title": "31 Days Before Your CCNA Exam",
            "author": "Allan Johnson"
        }
    ]
    
  5. Click the bar for the GET /books API to close the window.

Step 11: List a specific book using the GET /books{id} APIπŸ”—

  1. Click the GET /books{id} API. Notice this API requires the id as a parameter.

  2. To the right of Parameters, click the Try it out button.

  3. Under Parameters, enter 4 for the required id.

  4. Click Execute. Notice the information provided by Curl and Request URL.

    • Curl - This is the curl command to perform the same function using curl.
    • Request URL - This is the URL that can be used to get the same information using Postman and Python.
  5. Verify that the get was successful in the Server response. A Code of 200 means the post was a success. In the Response body you will see the book you requested with the id of 4.

    {
    "id": 4,
    "title": "IPv6 Fundamentals",
    "author": "Rick Graziani"
    }
    
  6. Click the bar for the GET /books{id} API to close the window.

Step 12: Delete a specific book using the DELETE /books{id} APIπŸ”—

  1. Click the DELETE /books{id} API. Notice this API requires the id as a parameter.

  2. Click Try it out.

  3. Under Parameters, enter 4.

  4. Click Execute.

  5. Verify that the delete was successful in the Server response. A Code of 200 means the post was a success. In the Response body you will see the book you deleted with the id of 4.

    {
    "id": 4,
    "title": "IPv6 Fundamentals",
    "author": "Rick Graziani"
    }
    
  6. Click the bar for the DELETE /books{id} API to close the window.

Step 13: List books using the GET /books APIπŸ”—

  1. Click the GET /books API.

  2. Click Try it out. If you see Cancel button in red, then you are already in Try it out mode.

  3. Click Execute.

  4. Under Server response in the Response body, you will no longer see the book with id 4.

    [
    {
        "id": 0,
        "title": "IP Routing Fundamentals",
        "author": "Mark A. Sportack"
    },
    {
        "id": 1,
        "title": "Python for Dummies",
        "author": "Stef Maruch Aahz Maruch"
    },
    {
        "id": 2,
        "title": "Linux for Networkers",
        "author": "Cisco Systems Inc."
    },
    {
        "id": 3,
        "title": "NetAcad: 20 Years Of Online-Learning",
        "author": "Cisco Systems Inc."
    },
    {
        "id": 5,
        "title": "31 Days Before Your CCNA Exam",
        "author": "Allan Johnson"
    }
    ]
    

    Note

    Do not close the School Library API tab in the Chromium browser. You will use the API documentation in the next part.

Part 2: Use Postman to Make API Calls to the API SimulatorπŸ”—

In this Part, you will use Postman to make the same API calls you made in the Student Library API documentation. Postman is a useful tool when an API developer web site is not available while providing the ability to easily save, organize, and reuse APIs.

Step 1: Open PostmanπŸ”—

  1. Double-click the Postman icon on the desktop. Normally, you would sign in to Postman, however, it is not necessary to get an account and login to Postman for labs in this course.

Step 2: List the books using the GET /books APIπŸ”—

  1. In the main window next to the Launchpad tab, click the plus icon "+" to create an Untitled Request. By default, this will be a GET request.

    Note

    An Untitled Request tab may already be open. If so, you can just use this tab.

  2. Click the down arrow next to GET to view the different API operations including GET, POST, and DELETE. Leave the selection on GET.

  3. Enter request URL.

  4. Return to the School Library API tab in Chromium and, if necessary, expand the GET /books API.

  5. Under Request URL, select, right-click and Copy the URL to your clipboard: http://library.demo.local/api/v1/books

    Return to Postman and paste the URL next to GET where it states, "Enter request URL".

    Note

    If pasting adds a line below the URL, remove the extra line.

  6. Click Send. To verify that the API request was a success, you will now see a response that include the Status code 200 OK in green.

    200 OK in Postman

  7. Scroll down to the Body section to see the response. Notice that the default is Pretty and json.

    [
        {
            "id": 0,
            "title": "IP Routing Fundamentals",
            "author": "Mark A. Sportack"
        },
        {
            "id": 1,
            "title": "Python for Dummies",
            "author": "Stef Maruch Aahz Maruch"
        },
        {
            "id": 2,
            "title": "Linux for Networkers",
            "author": "Cisco Systems Inc."
        },
        {
            "id": 3,
            "title": "NetAcad: 20 Years Of Online-Learning",
            "author": "Cisco Systems Inc."
        },
        {
            "id": 5,
            "title": "31 Days Before Your CCNA Exam",
            "author": "Allan Johnson"
        }
    ]
    

    Note

    You can save the JSON output to a file using the Save Response button above the output. This is not required for this lab.

Step 3: Get a Token using the POST /loginViaBasic APIπŸ”—

  1. In the main Postman window, click the plus icon "+" next to the active tab to create a new Untitled Request.

  2. Click the down arrow next to GET and select POST.

  3. Enter request URL.

    1. Return to the School Library API tab in Chromium and expand the POST /loginViaBasic API, if necessary.

    2. Under Request URL, select, right-click and Copy the URL to your clipboard: http://library.demo.local/api/v1/loginViaBasic

      Note

      If the Request URL is no longer showing, then you probably closed and re-opened the School Library API documentation page and are no longer authenticated. Click Try it out, then Execute, and then re-authenticate with username cisco and password Cisco123!.

    3. Return to Postman and paste the URL next to POST where it states, "Enter request URL".

      Note

      If pasting adds a line below the URL, remove the extra line.

  4. Click Authorization. Within this area, complete the following:

    1. In the drop-down list for Type, choose Basic Auth.

    2. For the Username and Password fields, fill in the following:

      • Username: cisco
      • Password: Cisco123!
  5. Click Send.

  6. If necessary, scroll down to the Body section to see your new token. Your token will be different than the one shown here.

        {
            "token": "cisco|5xSUHYFDvIAoCRv0LqWVSDcjJAwWjg18vMml6u2lm1I"
        }
    

Step 4: Add a book using the POST /books APIπŸ”—

Now you will add the IPv6 Fundamentals book you deleted in Part 2 when using the Try it out feature in the School Library API documentation.

  1. In the main Postman window, click the plus icon "+" next to the active tab to create a new Untitled Request.

    Postman New Request

  2. Click the down arrow next to GET and select POST.

  3. Enter request URL.

    1. Return to the School Library API tab in Chromium and expand the POST /books API.

    2. Under Request URL, select, right-click and Copy the URL to your clipboard: http://library.demo.local/api/v1/books

      Note

      If the Request URL is no longer showing, then you probably canceled Try it out. Click Try it out, and then Execute to show the Request URL.

    3. Return to Postman and paste the URL next to POST where it states, "Enter request URL".

      Note

      If pasting adds a line below the URL, remove the extra line.

  4. Click Authorization. Within this area, complete the following:

    Authorization tab in Postman

    1. In the drop-down list for Type, choose API Key.

    2. In the Key field, enter X-API-KEY.

      Note

      Recall that you saw X-API-KEY in the School Library API web page when you got a token selecting the green Authorize button.

    3. Return to the Post tab in Postman and copy the token you received in Step 3. Be sure to include everything within the quotation marks. Your token will be different than the one shown here.

      Example:
      cisco|5xSUHYFDvIAoCRv0LqWVSDcjJAwWjg18vMml6u2lm1I
      
    4. Go back to the second Post tab in Postman. Paste the token in the Value field

  5. In the same row with the Authorization tab, click Body. This section will allow you to choose the format of your input.

    • Click the raw radio button.
    • Click Text and change this option to JSON.
  6. In the input area you will see the number 1, for "line 1". Enter the following JSON object.

    {
    "id": 4,
    "title": "IPv6 Fundamentals",
    "author": "Rick Graziani",
    "isbn": "978 158144778"
    }
    
  7. Click Send.

  8. To verify that the API request was a success, you will now see a response that include the Status code 200 OK in green.

Step 5: Verify the additional book with the Get /books APIπŸ”—

  1. Return to the first GET tab. As you can see, Postman makes it easy to switch between different API calls.

  2. Click Send.

  3. To verify that the API request was a success, you will now see a response that include the Status code 200 OK in green.

  4. Click Body to see the response. Notice that the default is Pretty and json.

    [
        {
            "id": 0,
            "title": "IP Routing Fundamentals",
            "author": "Mark A. Sportack"
        },
        {
            "id": 1,
            "title": "Python for Dummies",
            "author": "Stef Maruch Aahz Maruch"
        },
        {
            "id": 2,
            "title": "Linux for Networkers",
            "author": "Cisco Systems Inc."
        },
        {
            "id": 3,
            "title": "NetAcad: 20 Years Of Online-Learning",
            "author": "Cisco Systems Inc."
        },
        {
            "id": 4,
            "title": "IPv6 Fundamentals",
            "author": "Rick Graziani"
        }
        {
            "id": 5,
            "title": "31 Days Before Your CCNA Exam",
            "author": "Allan Johnson"
        },
    ]
    

Step 6: Use additional parameters with the Get /books APIπŸ”—

  1. Go to the School Library API web site. Scroll up to GET /books API and expand it, if necessary.

    Notice the parameters that are available:

    • includeISBN: Includes in the results the ISBN numbers. Default=false

    • sortBy: Sort results using the specified parameter. Default=id

    • author: Return only books by the given Author.

    • page: Used to specify a page number.

  2. Click Try it out. If you see a Cancel button in red, then you do not need to select this button.

  3. Under parameters:

    • Click includeISBN and select true
    • Click sortBy and select author
  4. Click Execute.

  5. In the Response body you will see the list of books now sorted by author and including the ISBNs.

    [
        {
            "id": 5,
            "title": "31 Days Before Your CCNA Exam",
            "author": "Allan Johnson"
        },
        {
            "id": 2,
            "title": "Linux for Networkers",
            "author": "Cisco Systems Inc.",
            "isbn": "000-0000000123"
        },
        {
            "id": 3,
            "title": "NetAcad: 20 Years Of Online-Learning",
            "author": "Cisco Systems Inc.",
            "isbn": "000-0000001123"
        },
        {
            "id": 0,
            "title": "IP Routing Fundamentals",
            "author": "Mark A. Sportack",
            "isbn": "978-1578700714"
        },
        {
            "id": 4,
            "title": "IPv6 Fundamentals",
            "author": "Rick Graziani",
            "isbn": "978 1587144778"
        },
        {
            "id": 1,
            "title": "Python for Dummies",
            "author": "Stef Maruch Aahz Maruch",
            "isbn": "978-0471778646"
        }
    ]
    

    Notice that the Request URL now includes the parameters. You will see this again in Postman.

    Example of Parameters

  6. Return to Postman and go to the first API tab, GET http://library.demo.local/api/v1/books. You will now include some of the parameters from the School Library API web site.

  7. Click Params. You will see under Query Params input boxes for KEY and VALUE. Enter the following information:

    • Under KEY, enter includeISBN and under Value enter true Notice a check mark will automatically be included to the left of the value and a new row added.

    • Under KEY, enter sortBy and under Value enter author

      Notice that when entering these query parameters, it has updated the original URL next to the GET. This is the same Request URL you saw in the School Library API web site for this same API call. This is the URL Postman will be using, with these query parameters when making the API call.

      Postman Request URL

  8. Click Send.

    Notice in the Body, it now shows the same list of books, sorted by author and including the ISBNs that you saw in the School Library API web site.

    [
        {
            "id": 5,
            "title": "31 Days Before Your CCNA Exam",
            "author": "Allan Johnson"
        },
        {
            "id": 2,
            "title": "Linux for Networkers",
            "author": "Cisco Systems Inc.",
            "isbn": "000-0000000123"
        },
        {
            "id": 3,
            "title": "NetAcad: 20 Years Of Online-Learning",
            "author": "Cisco Systems Inc.",
            "isbn": "000-0000001123"
        },
        {
            "id": 0,
            "title": "IP Routing Fundamentals",
            "author": "Mark A. Sportack",
            "isbn": "978-1578700714"
        },
        {
            "id": 4,
            "title": "IPv6 Fundamentals",
            "author": "Rick Graziani",
            "isbn": "978 1587144778"
        },
        {
            "id": 1,
            "title": "Python for Dummies",
            "author": "Stef Maruch Aahz Maruch",
            "isbn": "978-0471778646"
        }
    ]
    

Part 3: Use Python to Add 100 Books to the API SimulatorπŸ”—

You could use the OpenAPI Specification Try It tool or Postman to add as many books as you want. However, you would have to add them one at a time. A better solution would be to write a program to add the books. In this Part, you will simulate the process of adding 100 books by using the Python faker library.

Step 1: Open Visual Studio (VS) Code and navigate to the graphhopper directoryπŸ”—

  1. Open VS Code from the Menu button or by double-clicking the icon on the desktop.

  2. Click File > Open Folder..., navigate to the labs/devnet-src/graphhopper folder, and click Open.

Note

If VS Code asks if you trust the authors of the files in the folder, choose Yes, I trust the authors

Step 2: Investigate the libraries used by add100RandomBooks.py programπŸ”—

  1. In VS Code EXPLORER pane on the left, click add100RandomBooks.py to open it, if necessary.

  2. At the top, notice the "shebang" that sets the interpreter to Python 3 and then the three libraries that are imported.

    #!/usr/bin/env python3
    
    import requests
    import json
    from faker import Faker
    
  3. You will use the Python requests library throughout this course. The requests library is required if you want to use Python to make API requests using GET, POST, DELETE and other HTTP methods.

  4. Faker is a Python library that generates 'fake' data for you. This program uses the Python faker library to generate random book titles, authors, and ISBNs. You can search the internet for more information on faker library. However, complete the following steps to see all the 252 methods for the faker library.

    1. Open a terminal window and start python3.

      devasc@labvm:~/labs/devnet-src/graphhopper$ 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.
      
    2. From faker import the Faker module (case sensitive).

      >>> from faker import Faker
      
    3. Assign the Faker() module to a variable called fake.

      >>> fake = Faker()
      
    4. To see all the methods, enter fake. (don’t miss the period) and then press the tab key twice. Notice the method fake.name(), which you will use in the next step. In the next step and later in this lab, you will also use the three highlighted methods (prefaced with fake.).: catch_phrase(), isbn13(), and name().

      Faker output

Step 3: Practice generating random data using the faker libraryπŸ”—

  1. Enter the following to generate a fake name. Your output will be a different fake name each time you execute the command.

    >>> print('My name is {}.'.format(fake.name()))
    My name is Katherine Ross.
    >>>
    
  2. Later in the program, a loop is used to iterate through these three methods to create entries for the School Library. Enter the following to generate 10 random names. After the "…" you will need to press return a second time. Note the leading spaces on the second line.

    >>> for i in range(10):
    ...     print(fake.name())
    ...
    Kevin Moyer
    Mr. Christopher Green MD
    Spencer Jensen
    Whitney Guzman
    Nicole Scott
    Tammy Lewis
    Craig Edwards
    Michael Diaz
    Ryan Mccoy
    Terry Rocha
    >>>
    
  3. Quit the Python interpreter when done investigating the faker library.

    >>> quit()
    

Step 4: Review the function variablesπŸ”—

Return to VS Code. The two functions in the program use three variables to get an authorization token from the School Library API service.

Step 5: Review the getAuthToken functionπŸ”—

  1. The getAuthToken function uses three variables to build a request. The r variable invokes the POST method for the loginViaBasic API and stores the token value if the call is successful. Notice the use of an f-string to build the request URL.

    def getAuthToken():
        authCreds = (LOGIN, PASSWORD)
        r = requests.post(
            f"{APIHOST}/api/v1/loginViaBasic",
            auth = authCreds
        )
    
  2. If the call is unsuccessful (HTTP status code is not equal to 200), an exception is raised and printed to the terminal window. Again, notice the use of an f-string to build the exception message. You can test the exception code by changing the one of the variables in Step 4.

    if r.status_code == 200:
        return r.json()["token"]
    else:
        raise Exception(f"Status code {r.status_code} and text {r.text}, while trying to Auth.")
    

Step 6: Review the addBook functionπŸ”—

  1. Similar to the addAuthToken function, the addBook function uses the three variables shown in Step 4 to build a request. The r variable invokes the POST method for the books API. The data comes from a variable called book, which is specified in the final part of the program.

    def addBook(book, apiKey):
        r = requests.post(
            f"{APIHOST}/api/v1/books",
            headers = {
                "Content-type": "application/json",
                "X-API-Key": apiKey
                },
            data = json.dumps(book)
        )
    
  2. If the call is unsuccessful, an exception is raised and printed to the terminal window. You can test it by changing the one of the variables in Step 4.

        if r.status_code == 200:
            print(f"Book {book} added.")
        else:
            raise Exception(f"Error code {r.status_code} and text {r.text}, while trying to add book {book}.")
    

Step 7: Review the code that invokes the two functionsπŸ”—

  1. The addAuthToken function is invoked and the results are stored in the variable apiKey.

    apiKey = getAuthToken()
    
  2. The Faker() module is set to a variable named fake. A for loop then iterates 100 times. The i variable is used later in the loop to set the value for the id key for each new book from 4 up to and not including 105.

    Note

    If you want to keep the two previous books added previously in this lab, change range to (6, 107).

    fake = Faker()
    for i in range(4, 105):
    
  3. Next, three variables hold the value of methods invoked from the Faker() module: catch_phrase(), name(), and isbn13().

    fakeTitle = fake.catch_phrase()
    fakeAuthor = fake.name()
    fakeISBN = fake.isbn13()
    
  4. Recall that the payload parameter for the books API requires JSON in the following format:

    {
    "id": 0,
    "title": "string",
    "author": "string"
    }
    
  5. The book variable is built using the three required keys for the payload parameter and values from the three fake variables.

    book = {"id": i, "title": fakeTitle, "author": fakeAuthor, "isbn": fakeISBN}
    
  6. Finally, the addBook function is called passing the book and apiKey variables. Because addBook is part of the loop, it will be called 100 times, one time each for book ID 4 through 104.

Step 8: Run and verify the add100RandomBooks.py programπŸ”—

  1. Enter the Python 3 command to run the add100RandomBooks.py program. You should get output similar to the following although your book titles and ISBN numbers will be different fake values.

    devasc@labvm:~/labs/devnet-src/graphhopper$ python3 add100RandomBooks.py
    Book {'id': 4, 'title': 'Assimilated client-server frame', 'author': 'Chelsea Mitchell', 'isbn': '978-0-411-83123-3'} added.
    Book {'id': 5, 'title': 'Adaptive tangible conglomeration', 'author': 'Edward Ryan', 'isbn': '978-1-64406-014-8'} added.
    <output omitted>
    Book {'id': 103, 'title': 'Fundamental uniform data-warehouse', 'author': 'Dennis David', 'isbn': '978-1-68465-896-1'} added.
    Book {'id': 104, 'title': 'Organic 4thgeneration functionalities', 'author': 'Nicole Gilbert', 'isbn': '978-0-13-176202-2'} added.
    
  2. Return to the Chromium browser and refresh the http://library.demo.local/ webpage. You should now see your 100 new books added.

    Note

    If you got to the API documentation page instead of the main page (http://library.demo.local/api/v1/docs) and use Try It out, you will only get a list of the first 10 books. You can enter a value from 2 to 10 the page parameter to see the other books.

4.3 Integrate a REST API in a Python ApplicationπŸ”—

ObjectivesπŸ”—

    Part 1: Get an API Key
    Part 2: Add your API key to your OS environment
    Part 3: Build the Graphhopper Geocoding Application
    Part 4: Build the Graphhopper Routing Application
    Part 5: Test Full Application Functionality

Background / ScenarioπŸ”—

In this lab, you will create an application in Visual Studio Code (VS Code) that retrieves JSON data from the Graphhopper Directions API, parses the data, and formats it for output to the user. You will use the GET Route request from the Graphhopper Directions API. Review the Directions API documentation here: https://docs.graphhopper.com/

InstructionsπŸ”—

Part 1: Get an API KeyπŸ”—

Before building the application, you need to complete the following steps to get a Graphhopper API key.

  1. Go to: https://www.graphhopper.com/.

  2. Click Sign Up at the top of the page.

  3. Fill out the form to create a new account. For Company, enter Cisco Networking Academy Student.

  4. After verifying your email account and log into Graphhopper, click API Keys at the top of the page. Click Add API Key to add a new API key. Name the new key Lab 4 – REST APIs. Click Add Key to create the new API key. Note: Check the SPAM folder for the confirmation email from Graphhopper if you have not received the confirmation email.

  5. Copy your API Key to a text file for future use. This will be the key you use for the rest of this lab.

Part 2: Add your API key to your OS environmentπŸ”—

Although it’s possible to hardcode your API key directly into your application, that is not good security practice. Anyone who views your source code could see your API key. This is especially important if your source code is pushed to a cloud-based Git repository like GitHub. Instead, you will store your key in an environment variable in your operating system. The environment variable is only accessible while logged in to the VM, and it ensures you won’t accidentally leak your API key.

  1. Open the terminal and create a new environment variable called GRAPHHOPPER_API_KEY with the value of the key you obtained in Part 1. Standard practice is to use all capital letters for environment variables. Make sure that you type the variable name and key accurately. Note that you are redirecting this command to be appended (>>) to the .bashrc file. This is to ensure that this variable persists even after you close the terminal. Make sure you use your own key, not the one in the example below.

    devasc@labvm:~$ echo "export GRAPHHOPPER_API_KEY=12345678-abcd-1234-9876-a1b2c3d4e5f6" >> ~/.bashrc
    
  2. Close all open terminal windows and relaunch the terminal. That includes closing and relaunching VS Code if you have it open.

  3. Verify that your export was successful by echoing the variable on the command line (note the $ in front of the variable name. devasc@labvm:~$ echo $GRAPHHOPPER_API_KEY 12345678-abcd-1234-9876-a1b2c3d4e5f6

Part 3: Build the Graphhopper Geocoding ApplicationπŸ”—

In this part, you will create a Python script to send a URL request to the Graphhopper Geocoding API. You will then test your API calls. Throughout the rest of this lab, you will build your script in parts, saving the file with a new name each time. This will help with learning the pieces of the application as well as provide you a series of scripts that you can return to if you run into any problems in the current version of your application.

Step 1: Create a New File in VS CodeπŸ”—

You can use any tools you want to enter in Python commands and execute the Python code. However, this lab will demonstrate building the application in VS Code.

  1. Open VS Code. There is a shortcut on the Desktop, for your convenience.

  2. Select File > Open Folder...

  3. Navigate to the ~/labs/devnet-src/graphhopper directory and click Open.

    Note

    If VS Code asks if you trust the authors of the files in the folder, choose Yes, I trust the authors

  4. Select File > New File…

  5. Select Python File from the dropdown menu that appears

  6. Select File > Save as… and name the file directions_api1.py and click Save.

    Note

    Be sure to name your files exactly as given in each step. The autograder will be running you code and will be looking for specific files by their filename.

Step 2: Importing modules for the applicationπŸ”—

To begin your script for parsing JSON data, you will need to import some modules from the Python library. The environ function from the os module will allow you to get environment variables from your operating system (for retrieving your API key). The urllib.parse module provides a variety of functions that will enable you to parse and manipulate the components of URLs. The requests module is the heart of working with REST APIs in Python and provides functions for communicating with the REST API server using HTTP.

You can read more about the requests module, including all supported methods, here: https://requests.readthedocs.io/en/latest/

  1. Add the following import statements at the top of your script.

    import os
    import requests
    import urllib.parse
    
  2. Select Terminal > New Terminal to open a Terminal inside VS Code.

  3. Save and run your script. You should get no errors. You should save and run your scripts often to test code functionality.

    devasc@labvm:~/labs/devnet-src/graphhopper$ python3 directions_api1.py
    devasc@labvm:~/labs/devnet-src/graphhopper$
    

Step 3: Build the URL for the request to the Graphhopper Geocoding APIπŸ”—

The first step in creating your API request is to construct the URL that your application will use to make the call. Initially, the URL will be the combination of the following variables:

  • GEOCODE_URL: the Geocoding URL to request longitude and latitude information for a given address or location
  • ROUTE_URL: the Routing URL to request routing information from the point of origin to the destination
  • KEY: the Graphhopper API key you retrieved from the Graphhopper website

  • Create some constants that will be used in several places in your code. Best practice is to use all capital letters for constants in python.

    GEOCODE_URL = "<https://graphhopper.com/api/1/geocode>?"  
    ROUTE_URL = "<https://graphhopper.com/api/1/route>?"  
    KEY = os.environ.get("GRAPHHOPPER_API_KEY", None)
    

    Note

    The os.environ.get method retrieves the API key that you stored as an environment variable in Step 2. This keeps the actual key value secured and out of your source code

  • Create the loc1 and loc2 variables, which will specify the point of origin and the destination, respectively. These parameters will also be included in the URL sent to Graphhopper.

    loc1 = "Toronto, ON"
    loc2 = "Ottawa, ON"
    
  • Using the GEOCODE_URL, loc1, and KEY, create a URL to retrieve the origin's longitude and latitude. 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 into acceptable characters (e.g. space into β€œ+” and a comma into β€œ%2C”). For the url variable, we will use the origin location variable loc1 and limit to one set of the latitude and longitude coordinates, and the Graphhopper API key. You will replace the loc1 variable when creating a Geocoding function later in the lab.

    url = GEOCODE_URL + urllib.parse.urlencode({"q":loc1, "limit": "1", "key":KEY})
    
  • Create variables to hold the reply of the requested URL and print the returned JSON data. The replydata variable holds the data from the reply of the Graphhopper URL. The json_data variable holds a Python’s Dictionary representation of the json reply of the get method of the requests module. The requests.get will make the API call to the Graphhopper Geocoding API. The print statement will be used temporarily to check the returned data. You will replace this print statement with more sophisticated display options later in the lab.

    replydata = requests.get(url)
    json_data = replydata.json()
    json_status = replydata.status_code
    print(json_data)
    

Step 4: Test the URL request and commit the changesπŸ”—

  1. Save and run your directions_api1.py script and verify it works.

  2. Troubleshoot your code, if necessary. Although your output might be slightly different, you should get a JSON response similar to the following. Notice that the output is a dictionary with two key/value pairs. The value for the key hits is a list that includes additional dictionaries and lists. The key point includes the lat and lng key/value pair that you will use later in the lab.

    devasc@labvm:~/labs/devnet-src/graphhopper$ python3 directions_api1.py 
    {'hits': [{'point': {'lat': 43.6534817, 'lng': -79.3839347}, 'extent': [-79.6392832, 43.5796082, -79.1132193, 43.8554425], 
    'name': 'Toronto', 'country': 'Canada', 'countrycode': 'CA', 'state': 'Ontario', 'osm_id': 324211, 'osm_type': 'R', 
    'osm_key': 'place', 'osm_value': 'city'}], 'locale': 'default'}
    devasc@labvm:~/labs/devnet-src/graphhopper$
    
  3. Change the loc1 variable. Rerun the script to get different results. To ensure the results you want, it is best to include both the city and the province for cities in Canada. When referring to cities in other countries, you can usually use either the English name for the city and country or the native name.

  4. Make sure to change the loc1 variable back to β€œToronto, ON” before moving on to the next step

  5. Add the updated directions_api1.py file to the staging area then commit the changes to the local repository using the message β€œAdded the geocoding API code”.

    devasc@labvm:~/labs/devnet-src/graphhopper$ git add directions_api1.py
    devasc@labvm:~/labs/devnet-src/graphhopper$ git commit -m "Added the geocoding API code"
    

Step 5: 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.

  1. Click File > Save As… and save your script as directions_api2.py.

  2. Delete the print(json_data) statement as you no longer need to test that the request is properly formatted.

  3. Add the statements below, which will do the following:

    • Use the status_code property to determine the HTTP status code returned in the response.
    • Start an if loop that checks for a successful call, which is indicated by a returned value of 200. If the request is successful, add a print statement to display the constructed Geocoding request URL. The \n adds a blank line before displaying the URL.
    if json_status == 200:
        print("Geocoding API URL for " + loc1 + ":\n" + url)
    

    Note

    Later in this lab, you will add elif and else statements for different status_code values.

Step 6: Display the JSON data in JSONViewπŸ”—

  1. Save and run your code. It should print out the Geocoding URL for Toronto, ON.

    devasc@labvm:~/labs/devnet-src/graphhopper$ python3 directions_api2.py 
    Geocoding API URL for Toronto, ON:
    https://graphhopper.com/api/1/geocode?q=Toronto%2C+ON&limit=1&key=12345678-abcd-1234-9876-a1b2c3d4e5f6
    
  2. Copy and paste the URL returned from your Python application, into the address field in the Chromium web browser in your VM.

    Note

    The Chromium web browser installed in the VM has an extension called JSONVue installed, which formats JSON to make it easier to read.

  3. The results only have two root dictionaries: hits and locale. Expand hits and investigate the rich data. Continue to expand the result as necessary until latitude and longitude coordinates for the origin or destination are displayed.

    {
        "- hits":[
            "-"{
            "- point":{
                "lat":43.6534817, <---
                "lng":-79.3839347 <---
            },
            "+ extent":[
                "…"
            ],
            "name":"Toronto",
            "country":"Canada",
            "countrycode":"CA",
            "state":"Ontario",
            "osm_id":324211,
            "osm_type":"R",
            "osm_key":"place",
            "osm_value":"city"
            }"-"
        ],
        "locale":"default"
    }
    

Step 7: Build the Geocoding functionπŸ”—

So far, you have created a URL requesting the latitude and longitude of a starting location and received the information from the API request. What about the information for the destination? You can reuse the same code for the second location by using a function. In this step, you will create a function that accepts the location inputs and return the status_code value of the Geocoding API URL, longitude, and latitude of the location, and additional Graphhopper information regarding the location.

  1. The example here uses the following parameters as the location input into the Geocoding function (already in your code).

    loc1 = "Toronto, ON"
    loc2 = "Ottawa, ON"
    
  2. Delete the GEOCODE_URL constant because it will be moved into the new geocoding function.

  3. Delete all of the lines of code starting at url = all the way to the end of the file. You should only have the import statements, the two remaining constants (ROUTE_URL and KEY), and the loc1 and loc2 variables remaining.

  4. At the bottom of the Python file, create a function called geocoding() that will accept two arguments: location and key. Remember that all code that is part of this function needs to be indented below this line!

    def geocoding(location, key):
    
  5. Add a constant called GEOCODE_URL that will be the address of the Graphhopper Geocoding API. Remember, this line and all subsequent lines in this function need to be indented under the geocoding() function.

    GEOCODE_URL = "<https://graphhopper.com/api/1/geocode>?"
    
  6. Create a variable called url that will be set to the GEOCODING_URL constant, concatenated with the location and key, and limit of 1 result. These values will be properly formatted by the urllib.parse.urlencode() method.

    url = GEOCODE_URL + urllib.parse.urlencode({"q":location, "limit": "1", "key":key})
    
  7. Leave one blank line, then enter the following code that will send the HTTPS request and store the results in a variable called json_data (after parsing the JSON data into a Python dictionary). It will also store the HTTP status code in a variable called json_status. Remember, all three lines should be indented under the geocoding() function.

    replydata = requests.get(url)
    json_data = replydata.json()
    json_status = replydata.status_code
    
  8. Leave another blank line, then use the following print statement to output the URL used to send the request. This is useful for debugging purposes.

    print("Geocoding API URL for " + location + ":\n" + url)
    
  9. Leave another blank line, and enter the following code, which verifies that the HTTP response code received from the API call is 200 (success). If it is a success, the latitude and longitude values are extracted from the results and stored in variable. If the HTTP response code is anything other than 200, the latitude and longitude values are set to null.

    if json_status == 200:
        lat = (json_data["hits"][0]["point"]["lat"])
        lng = (json_data["hits"][0]["point"]["lng"])
    else:
        lat = "null"
        lng = "null"
    
  10. Leave another blank line and return the HTTP status code, the latitude, and the longitude values to the function caller.

    return json_status,lat,lng
    

Step 8: Test your new Geocoding functionπŸ”—

  1. To use the function, you will create two variables to call the geocoding function and store the values returned from the function. Copy and paste the following lines to the end of the application. The geocoding function takes the input variable values for loc1 and key and returns the tuple with the values of the json_status, lat, and lng variables. The function is called again for loc2. These lines should NOT be indented.

    orig = geocoding(loc1, KEY)
    print(orig)
    dest = geocoding(loc2, KEY)
    print(dest)
    
  2. Save and run your directions_api2.py script and verify it works. Troubleshoot your code, if necessary.

    You should get output similar to the following. Notice your key and the origin and destination are embedded in the URL request. Notice the returned results from the function as a tuple with the status, latitude and longitude values.

    devasc@labvm:~/labs/devnet-src/graphhopper$ python3 directions_api2.py
    Geocoding API URL for Toronto, ON:
    https://graphhopper.com/api/1/geocode?q=Toronto%2C+ON&limit=1&key=12345678-abcd-1234-9876-a1b2c3d4e5f6
    (200, 43.6534817, -79.3839347)
    Geocoding API URL for Ottawa, ON:
    https://graphhopper.com/api/1/geocode?q=Ottawa%2C+ON&limit=1&key=12345678-abcd-1234-9876-a1b2c3d4e5f6
    (200, 45.4208777, -75.6901106)
    devasc@labvm:~/labs/devnet-src/graphhopper$
    

Step 9: Display additional informationπŸ”—