Skip to content
jgregoriBb edited this page Dec 15, 2022 · 6 revisions

USAGE

Imports

Import the classes that you need! This will give you access to the methods in the different classes.

from Bb_rest_helper import Get_Config
from Bb_rest_helper import Auth_Helper
from Bb_rest_helper import Bb_Requests
from Bb_rest_helper import Bb_Utils

Get configuration files from a JSON file

While the values can be hardcoded, it is often a good idea to grab them dinamically from a configuration file, this is easier to maintain and more secure to manage.

Create an instance of the Get_Config class to get configuration values from a JSON file:

#create an instance of the Get_Config class.
config = Get_Config('./learn_config.json')
#the JSON file will have the following structure:
     {
    "url":" Your server URL",
    "key":" Your Key",
    "secret":" Your secret"
     }
#Get configuration values
learn_url = learn_config.get_url()
learn_key = learn_config.get_key()
learn_secret = learn_config.get_secret()

⚠️ Note that if the path of the configuration file is incorrect, the program will be terminated and an error will be logged. Make sure that your configuration files are in the right path.

Logging

Configure the logging, otherwise the application will run, but will not provide any info. To do so create an instance of the Bb_utils class and set the logging by using the set_logging method.

#Create an instance of the Bb_utils class
utils = Bb_utils()
#Set the logging, default does not require arguments
utils.set_logging()

Default logging level is DEBUG, but this can be changed by passing the desired level value to the set_logging method. it is also possible to change the path for the logs folder, but currently only within the the main folder of the application. Finally, logs are configured to rotate every hour, but this can also be changed by passing the "when" and "interval" arguments.

utils.set_logging('logging.WARNING','./different_folder',when = 'm', interval= 5)
# This example configures the logs to record at the WARNING level, to a different folder and to rotate every 5 min

Authentication

Get the authentication token by creating an instance of the Auth_Helper method, and then calling the relevant auth function:

#Learn
learn_auth = Auth_Helper(learn_url,learn_key,learn_secret)
learn_token = learn_auth.learn_auth()

#Alternatively you can just get the Learn token using
#the quick_auth one liner method included in Bb_Utils. 
#This method calls Get_Config for you.
utils = Bb_Utils()
quick_auth_learn = utils.quick_auth('./learn_config.json','Learn')

#With this method you have access to the token and the url for each platform
#So it will not be neccesary to hardcode the url or call Get_Config separately
learn_token = quick_auth_learn['token']
learn_url = quick_auth_learn['url']

Calls with the Bb_Requests class

Once authenticated, you can start making calls. In order to do so, start by creating an instance of the Bb_requests class

#Create an instance of the Bb_Requests class
reqs = Bb_Requests()

Create variables for the base_url (your server url), API endpoint url, and the request parameters. Note that from V2 you no longer need to pass an F String with the whole request url (base_url + endpoint)

#Learn GET Courses endpoint and params example
base_url = 'your server url'
courses_endpoint = '/learn/api/public/v3/courses'
params = {
     'limit':'10',
     'fields':'courseId,name,description,ultraStatus'
}

If you do not wish to use parameters, just dont pass anthing as params. The library has been updated to have an empty dictionary as a default, so you no longer need to pass '{}'

Then, select the http verb that you wish to use, the supported methods in the library are:

  • For GET requests, use Bb_GET
  • For POST requests, use Bb_POST
  • To upload a file to Learn, use Bb_POST_file this method will return the file id to be referenced in future calls.
  • For PATCH requests, use Bb_PATCH
  • For PUT requests, use Bb_PUT
  • For DELETE resources, use Bb_DELETE

then call the chosen method pasing the different arguments; Learn url, endpoint, token and parameters. Some methods such as POST or PATCH methods, will also require a payload in the form of a dictionary.

#GET example
learn_data = reqs.Bb_GET(base_url,courses_endpoint,learn_token,params)
#POST example to create courses in Learn
base_url = 'your server url'
courses_endpoint = '/learn/api/public/v3/courses'
params = {
     'fields':'courseId,name,description,ultraStatus'
}
payload = {
     "externalId": "Javier_API_003",
     "courseId": "Javier_API_003",
     "name": "Learn helper test",
     "description": "A learn helper test to check if the class works as expectted",
     "organization": False,
     "ultraStatus": "Ultra",
     "availability": {
          "available": "Yes",
          "duration": {
               "type": "Continuous",
          },
     },
}
#POST call
course = reqs.Bb_POST(base_url,courses_endpoint,learn_token,params,payload)
#prints the response
utils.pretty_printer(course)

Bb_Utils class

Bb_Utils is a class that contains utiliy methods that makes our life easier when performing certain common operations with the Blackboard REST APIs such as logging, pretty printing, date formatting or id conversion. This class is somewhat experimental and will be growing over time as the need arises in new projects.

The first step to use the methods is to create an instance of the Bb_utils class:

utils = Bb_Utils()
# From here you will have access to all the methods below

set_logging

Configure the logging, otherwise the application will run, but will not provide any info. To do so create an instance of the Bb_utils class and set the logging by using the set_logging method.

#Create an instance of the Bb_utils class
utils = Bb_utils()
#Set the logging, default does not require arguments
utils.set_logging()

Default logging level is DEBUG, but this can be changed by passing the desired level value as ab argument to the method. It is also possible to change the path for the logs folder, but currently only within the the main folder of the application. Finally, logs are configured to rotate every hour, but this can also be changed by passing the "when" and "interval" arguments.

utils.set_logging('logging.WARNING','./different_folder',when = 'm', interval= 5)
# This example configures the logs to record at the WARNING level, to a different folder and to rotate every 5 min

pretty_printer

Prints the response from any of the requests methods in a prettified format to the console.

#Example call.
base_url = 'your server url'
courses_endpoint = '/learn/api/public/v3/courses'
courses = reqs.Bb_GET(base_url,courses_endpoint,learn_token,params)
utils.pretty_printer(courses)

by default, the method will indent 4 spaces and sort the keys aphabetically, this can be modified by passing sort_keys = False as a second argument

utils.pretty_printer(courses, sort_keys = False)

check_course_id

Checks if a given Learn course exists in the server by taking the external course id as an argument and returs True or False. Please note that the accuracy of this method depends on the externalId being an specific value. It is discouraged to use short, common strings such as "001" or "aaa" as those would likely return many different values.

#Returns True or False.
check_course = utils.(external_course_id)

time_format

This method is provided to facilitate date formatting when importing dates from other applications, i.e, dates in excel format, it can take a date string with the following formats

DD/MM/YYYY
DD/MM/YYYY HH:MM
DD/MM/YYYY HH:MM:SS

optional arguments for date delimiter (default "/") and hour delimiter (default ":") can be provided. The outcome of the method is:

#YYYY-MM-DDTHH:MM:SS:000Z
formatted_date = utils.time_format(DD/MM/YYYY)

learn_convert_external_id

This method is used to get the external id of a Learn course as an argument and return another field in the get response (usually the course id). We found it is a common operation, particularly when getting a list of courses in a CSV.

#Returns the courseId (default)
converted_id = utils.learn_convert_external_id(
     learn_url,
     learn_token,
     '007687'
)

if interested in converting the externalId to another value that can be found in the GET response for courses, pass that field name as the last argument for the method

#Returns the dataSourceId instead of the id
conv_id = utils.learn_convert_external_id(
     learn_url,
     learn_token,
     '007687',
     'DataSourceId'
)

quick_auth

This method uses the Get_Config and Auth_Helper classes under the hood to provide a convenient one liner that returns the token and the base_url.

utils = Bb_Utils()
quick_auth_learn = utils.quick_auth('./learn_config.json','Learn')
#With this method you have access to the token and the url for each platform so it will not be neccesary to hardcode the url or call Get_Config separately
learn_token = quick_auth_learn['token']
learn_url = quick_auth_learn['url']

check_connection

This method checks connectivity by using the requests module to connect to a host of choice (default google.com). It is also possible to adjust the timeout value (defaut is 5 sec). It is useful for longer script runs, and can be used to pause script until connection resumes or to gracefully shutdown the script if it does not return in some time.

#checks conectivity and returns True if connected and False if not connected
utils = Bb_Utils()
utils.connection_check()

read_csv

This is a convenience method to read data from a csv file, uses the Python csv module and returns a list where each row is a dict with the column header as key and the content of the field is the value. It takes the path to the csv file to read and optionally a delimiter (default ','). This version returns all the contents for from the csv.

utils = Bb_Utils()
path = './test_read.csv'
reader = utils.read_csv(path)

for r in reader:
    print(r)

#{'header1': 'row1', 'header2': 'row1', 'header3': 'row1', 'header4': 'row1', 'header5': 'row1'}
# As a hint with multiple rows you need to access data as reader[0]['header1']

write_csv

This is a convenience method to write rows to a csv file. If the csv file does not exist it will create it in the desired path, and if it does it will append rows to the existing file. As arguments it takes the path for the file, headers (fieldnames), the data to write and optionally a delimiter (default ',')

path = './test_write.csv'
headers = ['header1','header2','header3']
row_1 = {'header1':'data1','header2':'data2','header3':'data3'}
row_2 = {'header1':'data1-2','header2':'data2-2','header3':'data3-2'}
utils = Bb_Utils()
utils.write_csv(self.path, self.headers, self.row_1)
utils.write_csv(self.path, self.headers, self.row_2)

#note headers are currently needed each time the method is called