Source code for muddle.api

import requests

MOODLE_WS_ENDPOINT = '/webservice/rest/server.php'


def valid_options(kwargs, allowed_options):
    """ Checks that kwargs are valid API options"""

    diff = set(kwargs) - set(allowed_options)
    if diff:
        print("Invalid option(s): ", ', '.join(diff))
        return False
    return True


[docs]class Muddle(): """ The main Muddle class Example Usage:: >>> import muddle >>> course = muddle.course(int) <Response [200]> """ def authenticate(self, api_key, api_url): Muddle.api_key = api_key Muddle.api_url = api_url + MOODLE_WS_ENDPOINT Muddle.request_params = {'wstoken': api_key, 'moodlewsrestformat': 'json'} def course(self, *course_id): return Course(*course_id) def category(self, *category_id): return Category(*category_id)
[docs]class Course(Muddle): """ Represents API endpoints for a Moodle Course """ def __init__(self, course_id=None): self.course_id = course_id
[docs] def create(self, fullname, shortname, category_id, **kwargs): """ Create a new course :param string fullname: The course's fullname :param string shortname: The course's shortname :param int category_id: The course's category :keyword string idnumber: (optional) Course ID number. \ Yes, it's a string, blame Moodle. :keyword int summaryformat: (optional) Defaults to 1 (HTML). \ Summary format options: (1 = HTML, 0 = Moodle, 2 = Plain, \ or 4 = Markdown) :keyword string format: (optional) Defaults to "topics" Topic options: (weeks, topics, social, site) :keyword bool showgrades: (optional) Defaults to True. \ Determines if grades are shown :keyword int newsitems: (optional) Defaults to 5. \ Number of recent items appearing on the course page :keyword bool startdate: (optional) Timestamp when the course start :keyword int maxbytes: (optional) Defaults to 83886080. \ Largest size of file that can be uploaded into the course :keyword bool showreports: Default to True. Are activity report shown? :keyword bool visible: (optional) Determines if course is \ visible to students :keyword int groupmode: (optional) Defaults to 2. options: (0 = no group, 1 = separate, 2 = visible) :keyword bool groupmodeforce: (optional) Defaults to False. \ Force group mode :keyword int defaultgroupingid: (optional) Defaults to 0. \ Default grouping id :keyword bool enablecompletion: (optional) Enable control via \ completion in activity settings. :keyword bool completionstartonenrol: (optional) \ Begin tracking a student's progress in course completion after :keyword bool completionnotify: (optional) Default? Dunno. \ Presumably notifies course completion :keyword string lang: (optional) Force course language. :keyword string forcetheme: (optional) Name of the force theme Example Usage:: >>> import muddle >>> muddle.course().create('a new course', 'new-course', 20) """ allowed_options = ['idnumber', 'summaryformat', 'format', 'showgrades', 'newsitems', 'startdate', 'maxbytes', 'showreports', 'visible', 'groupmode', 'groupmodeforce', 'jdefaultgroupingid', 'enablecompletion', 'completionstartonenrol', 'completionnotify', 'lang', 'forcetheme'] if valid_options(kwargs, allowed_options): option_params = {} for index, key in enumerate(kwargs): val = kwargs.get(key) if isinstance(val, bool): val = int(val) option_params.update({'courses[0][' + key + ']': val}) params = {'wsfunction': 'core_course_create_courses', 'courses[0][fullname]': fullname, 'courses[0][shortname]': shortname, 'courses[0][categoryid]': category_id} params.update(option_params) params.update(self.request_params) return requests.post(self.api_url, params=params, verify=False)
[docs] def delete(self): """ Deletes a specified courses Example Usage:: >>> import muddle >>> muddle.course(10).delete() """ params = {'wsfunction': 'core_course_delete_courses', 'courseids[0]': self.course_id} params.update(self.request_params) return requests.post(self.api_url, params=params, verify=False)
[docs] def contents(self): """ Returns entire contents of course page :returns: response object Example Usage:: >>> import muddle >>> muddle.course(10).content() """ params = self.request_params params.update({'wsfunction': 'core_course_get_contents', 'courseid': self.course_id}) return requests.get(self.api_url, params=params, verify=False).json()
[docs] def duplicate(self, fullname, shortname, categoryid, visible=True, **kwargs): """ Duplicates an existing course with options. Note: Can be very slow running. :param string fullname: The new course's full name :param string shortname: The new course's short name :param string categoryid: Category new course should be created under :keyword bool visible: Defaults to True. The new course's visiblity :keyword bool activities: (optional) Defaults to True. \ Include course activites :keyword bool blocks: (optional) Defaults to True. \ Include course blocks :keyword bool filters: (optional) Defaults to True. \ Include course filters :keyword bool users: (optional) Defaults to False. Include users :keyword bool role_assignments: (optional) Defaults to False. \ Include role assignments :keyword bool comments: (optional) Defaults to False. \ Include user comments :keyword bool usercompletion: (optional) Defaults to False. \ Include user course completion information :keyword bool logs: (optional) Defaults to False. Include course logs :keyword bool grade_histories: (optional) Defaults to False. \ Include histories :returns: response object Example Usage:: >>> import muddle >>> muddle.course(10).duplicate('new-fullname', 'new-shortname', 20) """ # TODO # Ideally categoryid should be optional here and # should default to catid of course being duplicated. allowed_options = ['activities', 'blocks', 'filters', 'users', 'role_assignments', 'comments', 'usercompletion', 'logs', 'grade_histories'] if valid_options(kwargs, allowed_options): option_params = {} for index, key in enumerate(kwargs): option_params.update( {'options[' + str(index) + '][name]': key, 'options[' + str(index) + '][value]': int(kwargs.get(key))}) params = {'wsfunction': 'core_course_duplicate_course', 'courseid': self.course_id, 'fullname': fullname, 'shortname': shortname, 'categoryid': categoryid, 'visible': int(visible)} params.update(option_params) params.update(self.request_params) return requests.post(self.api_url, params=params, verify=False)
[docs] def export_data(self, export_to, delete_content=False): """ Export course data to another course. Does not include any user data. :param bool delete_content: (optional) Delete content \ from source course. Example Usage:: >>> import muddle >>> muddle.course(10).export_data(12) """ params = {'wsfunction': 'core_course_import_course', 'importfrom': self.course_id, 'importto': export_to, 'deletecontent': int(delete_content)} params.update(self.request_params) return requests.post(self.api_url, params=params, verify=False)
[docs]class Category(Muddle): """ Represents API endpoints for Moodle Courses Categories """ def __init__(self, category_id=None): self.category_id = category_id
[docs] def details(self): """ Returns details for given category :returns: category response object Example Usage:: >>> import muddle >>> muddle.category(10).details() """ params = {'wsfunction': 'core_course_get_categories', 'criteria[0][key]': 'id', 'criteria[0][value]': self.category_id} params.update(self.request_params) return requests.post(self.api_url, params=params, verify=False)
[docs] def create(self, category_name, **kwargs): """ Create a new category :param string name: new category name :param int parent: (optional) Defaults to 0, root category. \ The parent category id inside which the new \ category will be created :param string description: (optional) The new category description :param int descriptionformat: (optional) Defaults to 1 \ description format (1 = HTML, 0 = MOODLE, 2 = PLAIN, 4 = MARKDOWN) :param string theme: (optional) The new category theme Example Usage:: >>> import muddle >>> muddle.category().create('category name') """ allowed_options = ['parent', 'description', 'descriptionformat', 'theme'] if valid_options(kwargs, allowed_options): option_params = {} for key in kwargs: option_params.update( {'categories[0][' + key + ']': str(kwargs.get(key))}) params = {'wsfunction': 'core_course_create_categories', 'categories[0][name]': category_name, } params.update(option_params) params.update(self.request_params) return requests.post(self.api_url, params=params, verify=False)
[docs] def delete(self, new_parent=None, recursive=False): """ Deletes a category. Optionally moves content to new category. Note: If category is in root, new_parent must be specified. :param int new_parent: (optional) Category ID of new parent :param bool recursive: recursively delete contents inside this category Example Usage:: >>> import muddle >>> muddle.category(10).delete() """ params = {'wsfunction': 'core_course_delete_categories', 'categories[0][id]': self.category_id, 'categories[0][recursive]': int(recursive)} if new_parent: params.update({'categories[0][newparent]': new_parent}) params.update(self.request_params) return requests.post(self.api_url, params=params, verify=False)
[docs] def update(self, **kwargs): """ Update categories :param string name: (optional) Name :param string idnumber: (optional) Id number :param int parent: (optional) Parent category id :param string description: (optional) Description :param int description-format: Defaults to 1 \ (1 = HTML, 0 = MOODLE, 2 = PLAIN or 4 = MARKDOWN) :param string theme: (optional) Theme Example Usage:: >>> import muddle >>> muddle.category(10).update(name='new name') """ allowed_options = ['name', 'idnumber', 'parent', 'description', 'descriptionformat', 'theme'] if valid_options(kwargs, allowed_options): option_params = {} for key in kwargs: option_params.update( {'categories[0][' + key + ']': str(kwargs.get(key))}) params = {'wsfunction': 'core_course_update_categories', 'categories[0][id]': self.category_id} params.update(option_params) params.update(self.request_params) return requests.post(self.api_url, params=params, verify=False)