Skip to content

Pagination with Learners

Tip

This example shows how to paginate through all Learners in your Wyzed account. It's also a good example of how pagination works across other endpoints in the API.

Python 3 Example

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#!/usr/bin/python
import requests


# Replace these with the credentials and URL you got when installing the API
# integration in your Wyzed account.
CLIENT_ID = 'REPLACE_ME'
CLIENT_SECRET = 'REPLACE_ME'
BASE_URL = 'REPLACE_ME'


def get_access_token():
    """Fetch a fresh access token from the Wyzed API.

    Returns:
        access_token (str): A fresh access token.
    """

    print('Fetching access token...')

    # Define request data
    url = f'{BASE_URL}/oauth/token'
    headers = {
        'Content-Type': 'application/json',
        'Accept': 'application/json'
    }
    payload = {
        'grant_type': 'client_credentials',
        'client_id': CLIENT_ID,
        'client_secret': CLIENT_SECRET
    }

    # Make the request. Exit upon any errors. If it's an HTTP error then
    # extract the error message.
    try:
        response = requests.post(url, headers=headers, json=payload)
        response.raise_for_status()
    except requests.exceptions.HTTPError as e:
        # This is a standard HTTP error raised by response.raise_for_status().
        # In most cases an standard error response looks like this:
        # {
        #   "error": {
        #     "code": 400,
        #     "errors": [
        #       {
        #         "domain": "global",
        #         "message": "invalid client_id parameter",
        #         "reason": "badRequest"
        #       }
        #     ],
        #     "message": "invalid client_id parameter"
        #   }
        # }
        reason = response.json()['error']['message']
        raise SystemExit(f'Error getting access token: {reason}')
    except requests.exceptions.RequestException as e:
        # This could be a Timeout, TooManyRedirects or some other error
        raise SystemExit(e)

    print('...Access token successful!')
    return response.json()['access_token']


def list_learners(access_token, limit=2, cursor=None):
    """Fetches all learners via the Wyzed API.

    When there are more learners on the server than can fit in a single
    response, this method calls itself internally with the cursor for the next
    page of results, and keeps going until it's retreived them all. When done
    it'll return all learners, so you only need to call it once.

    Args:
        access_token: A valid access token.
        limit: Number of learners to fetch at once.
        cursor: Cursor from which to continue fetching another page.

    Returns:
        learners: A list of all learners from the provided cursor onwards. If
            you did not specify a cursor, then it will contain all learners.
    """

    # Define request data
    url = f'{BASE_URL}/learners'
    headers = {
        'Content-Type': 'application/json',
        'Accept': 'application/json',
        'Authorization': f'Bearer {access_token}'
    }
    payload = {
        'cursor': cursor,
        'limit': limit,
        'archived': False
    }

    # Make the request. Exit upon any errors. If it's an HTTP error then
    # extract the error message and include it in the exception we raise.
    try:
        response = requests.get(url, headers=headers, params=payload)
        response.raise_for_status()
    except requests.exceptions.HTTPError as e:
        # This is a standard HTTP error raised by response.raise_for_status().
        # We can extract the reason Wyzed gave like so:
        reason = response.json()['error']['message']
        raise SystemExit(f'Error getting access token: {reason}')
    except requests.exceptions.RequestException as e:
        # This could be a Timeout, TooManyRedirects or some other error
        raise SystemExit(e)

    # Parse the learners from the response
    response_json = response.json()
    learners = response_json.get('items', [])

    # Fetch the next page of results if there are more on the server. This is
    # where the method calls itself with the `cursor` parameter.
    if (response_json.get('more', False)
            and response_json.get('next_cursor', None)):
        learners += list_learners(
            access_token=access_token,
            cursor=response_json['next_cursor'],
            limit=limit)

    return learners


# Get access token
# In your own app you'll need to keep track of the token's expiration so you
# can refresh it before it expires.
access_token = get_access_token()

# Fetch all learners
# In your own app you'll need to handle the response status codes in case yof
# bad requests or expired tokens.
print('Fetching learners...')
learners = list_learners(access_token)
print('...Learners successful!')

# Output the number of results found and list all the learner names and email
# addresses.
print(f'{len(learners)} learners found.')
for i, learner in enumerate(learners):
    print(f"- {i + 1} of {len(learners)}. {learner['firstname']} "
          f"{learner['surname']} ({learner['email']})")

# Example Successful Output:
# Fetching access token...
# ...Access token successful!
# Fetching learners...
# ...Learners successful!
# 5 learners found.
# - 1 of 5. John Doe ([email protected])
# - 2 of 5. Karl Newland ([email protected])
# - 3 of 5. Andrew Appleseed ([email protected])
# - 4 of 5. Simon Rogers ([email protected])
# - 5 of 5. Erin Cheney ([email protected])