Notes on areas you struggled:

Understanding and Using APIs

2.1 Construct a REST API request to accomplish a task given API documentation

2.2 Describe common usage patterns related to webhooks

2.3 Identify the constraints when consuming APIs

2.4 Explain common HTTP response codes associated with REST APIs

2.5 Troubleshoot a problem given the HTTP response code, request and API documentation

2.6 Identify the parts of an HTTP response (response code, headers, body)

2.7 Utilize common API authentication mechanisms: basic, custom token, and API keys

  • Basic Authentication: simple mechanism that involves sending a username and password with each API request.
  • To use it with an API, you’ll need to include an Authorization header in your request that contains the base64-encoded string of the username and password, separated by a colon.
import requests

url = 'https://api.example.com/get_data'
username = 'your_username'
password = 'your_password'

response = requests.get(url, auth=(username, password))
  • Custom Token Authentication is an authentication mechanism used in RESTful APIs that involves sending a custom token with each API request.
  • To use custom token authentication with an API, you’ll need to obtain a token from the API provider, and then include it as a header in your API requests.
import requests

url = 'https://api.example.com/get_data'
token = 'your_custom_token'

headers = {'Authorization': f'Token {token}'}
response = requests.get(url, headers=headers)
  • API Keys: are a common authentication mechanism used in RESTful APIs that involve sending a unique key with each api request.
  • To use API keys with an API, you need to obtain an API key from the API provider, and then include it as a parameter or header in your API requests.
import requests

url = 'https://api.example.com/get_data'
api_key = 'your_api_key'

params = {'api_key': api_key}
response = requests.get(url, params=params)

2.8 Compare common API styles (REST, RPC, synchronous, and asynchronous)

  • RESTful APIs: REST is a popular architectural style for building web APIs
  • RESTful APIs use HTTPS methods (GET, POST, PUT, DELETE) to represent different actions that can be taken on resources (Create, Read, Update, Delete)
  • RESTful APIs use JSON or XML to represent data
  • Well suited for systems that need to be easily scalable, maintainable and accessible to a wide variety of clients

  • RPC APIs: RPC is a style of API that allows a client to invoke a procedure or function on a remote server.
  • Typically use a specific protocol for encoding the request and response (e.g. grpc, or netconf).
  • Can be more efficient than RESTful APIs, since they allow for fine-grained control over the data being transmitted.
  • Can be more complex to implement and maintain.

  • Synchronous API: Designed to provide immediate reponses to client requests, blocking the client until the response is received.
  • Synchronous APIs are often used for simple operations that require immediate feedback.
  • Less scalable than asynchronous APIs, since they require a dedicated thread to handle each client request.
  • Best suited for situations when immediate feedback is needed.

  • Asynchronous APIs are designed to allow clients to submit requests and then receive a response later without blocking.
  • Often used for long-running operations that can be executed in the background, such as processing a large dataset.
  • Can be more scalable than synchronous APIs
  • Can be complicated to implement

2.9 Construct a Python script that calls a REST API using the requests library

  • Begin by importing the requests library
  • Define the URL, Params and headers that need to be included in the request
  • Make a get request to the api endpoint using the get() function in the requests library
  • Check the response code to see if it was successful, if so (and so is 200) then the JSON body (using the json) method of the ‘response’ object, and then loops over the list of users in the response and prints their information.
  • If the request was not successful prints an error
import requests

url = 'https://api.example.com/get_users'
params = {'page': 1, 'limit': 10}
headers = {'Authorization': 'Bearer YOUR_ACCESS_TOKEN'}

response = requests.get(url, params=params, headers=headers)

if response.status_code == 200:
    users = response.json()
    print(f"Total users: {len(users)}")
    for user in users:
        print(f"User {user['id']}: {user['name']} ({user['email']})")
else:
    print(f"Error: {response.status_code} - {response.text}")

Infrastructure and Automation

5.1 Describe the value of model driven programmability for infrastructure automation

5.2 Compare controller-level to device-level management

5.3 Describe the use and roles of network simulation and test tools (such as VIRL and pyATS)

5.4 Describe the components and benefits of CI/CD pipeline in infrastructure automation

5.5 Describe principles of infrastructure as code

5.6 Describe the capabilities of automation tools such as Ansible, Puppet, Chef, and Cisco NSO

5.7 Identify the workflow being automated by a Python script that uses Cisco APIs including ACI, Meraki, Cisco DNA Center, or RESTCONF

5.8 Identify the workflow being automated by an Ansible playbook (management packages, user management related to services, basic service configuration, and start/stop)

5.9 Identify the workflow being automated by a bash script (such as file management, app install, user management, directory navigation)

5.10 Interpret the results of a RESTCONF or NETCONF query

5.11 Interpret basic YANG models

5.12 Interpret a unified diff

5.13 Describe the principles and benefits of a code review process

5.14 Interpret sequence diagram that includes API calls