Skip to content

Added docstrings and type annotations in processtext.py. Added docstr… #5

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 81 additions & 5 deletions canvas.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,9 +215,31 @@ def students(self):


class CourseSubObject(Canvas):
"""A Canvas element that is owned (directly or indirectly) by a Course.

Guaranteed to have instance fields:
- data (the dictionary of Canvas data associated with this object)
- id_field (the name of the field in data used as ID/key in Canvas)
- id (this object's specific ID; should be cached when recomputed)
- route_name (the Canvas API URL element specific to this type of object)
- url_prefix (the entire base for Canvas API URLs referring to this type of object;
should be cached when recomputed)
- request_param_name (the Canvas API URL element specific to this type of
object when referring to a single object (e.g., for updates))

Also supports direct dictionary-style indexing, which accesses/updates the data field.
"""

# If not provided, the request_param_name defaults to the lower-cased class name.
def __init__(self, parent, route_name, data, id_field='id', request_param_name=None):
"""Construct a CourseSubObject with the given parent, Canvas API route_name, and Canvas data.

The route_name is use to construct REST API URLs applying to this object. The data is
the object's content (as a dictionary) and used in updates to Canvas. The id_field is the
key used to identify this object in Canvas (also used for API calls). The request_param_name
is used for API calls as well (e.g., for PUT-based updates), defaulting to the lowercased
class name.
"""
# MUST be available before calling self.get_course.
self.parent = parent
super().__init__(self.get_course().token)
Expand All @@ -232,31 +254,46 @@ def __init__(self, parent, route_name, data, id_field='id', request_param_name=N
self.request_param_name = request_param_name

def get_course(self):
"""Get the Course that owns this object.

Traverses parents until it reaches a parent that is a course.
"""
if isinstance(self.parent, Course):
return self.parent
else:
return self.parent.get_course()

def compute_id(self):
"""Get the ID of this object."""
return self.data[self.id_field]

def compute_base_url(self):
"""Get the entire base for Canvas API URLs referring to this type of object"""
return f'{self.parent.url_prefix}/{self.route_name}'

def compute_url_prefix(self):
"""Get the entire base for Canvas API URLs referring to this particular object."""
return f'{self.compute_base_url()}/{self.id}'

def __getitem__(self, index):
"""Index into self.data"""
return self.data[index]

def __setitem__(self, index, value):
"""Update self.data"""
self.data[index] = value

def items(self):
""" docstring """
"""Get all items in self.data"""
return self.data.items()

def update(self, data=None):
"""Update Canvas with new data for this object.

Updates the stored data with the given data if it is non-None.
Then, updates Canvas (posting a new object if self.id is absent).
Returns self for chaining.
"""
if data:
self.data = data
if self.id:
Expand All @@ -271,13 +308,18 @@ def update(self, data=None):


class Quiz(CourseSubObject):
""" Quiz """
"""A Canvas Quiz object."""

def __init__(self, course, quiz_data):
"""Creates a new Quiz with a course as parent, and initial Canvas quiz data."""
super().__init__(course, "quizzes", quiz_data)

def update_quiz(self, data=None):
""" docstring """
"""Update this quiz on Canvas.

Updates the stored data with the given data if it is non-None.
Then updates Canvas with the stored data. Returns self for chaining.
"""
return self.update(data)

def question_group(self, group_id):
Expand Down Expand Up @@ -396,8 +438,13 @@ def send_quiz_grade(self, quiz_submission,


class QuizQuestion(CourseSubObject):
# If the quiz is not supplied, fetches it via quiz_question_data['quiz_id'].
"""A Canvas object representing a Quiz Question."""

def __init__(self, quiz_question_data, quiz=None):
"""Create a new QuizQuestion with the given data and with the given quiz as parent.

If no quiz is supplied, fetches it via quiz_question_data['quiz_id'].
"""
if quiz is None:
if 'quiz_id' not in quiz_question_data:
raise RuntimeError(
Expand All @@ -406,6 +453,14 @@ def __init__(self, quiz_question_data, quiz=None):
super().__init__(quiz, "questions", quiz_question_data, request_param_name='question')

def update(self, data=None):
"""Update this QuizQuestion on Canvas.

Updates the stored data with the given data if it is non-None.
Then updates Canvas with the stored data. Returns self for chaining.

Attempts to handle differences in format between input and output
of quiz questions in the Canvas API.
"""
if data:
self.data = data

Expand All @@ -429,16 +484,30 @@ def update(self, data=None):
return super().update(self.data)

def update_question(self, data=None):
"""Update this QuizQuestion on Canvas.

Updates the stored data with the given data if it is non-None.
Then updates Canvas with the stored data. Returns self for chaining.

Attempts to handle differences in format between input and output
of quiz questions in the Canvas API.
"""
return self.update(data)


class Assignment(CourseSubObject):
""" Assignment """
"""A Canvas assignment object."""

def __init__(self, course, assg_data):
"""Create a new Assignment with course as parent and the given assignment data."""
super().__init__(course, "assignments", assg_data)

def update_assignment(self, data=None):
"""Update this Assignment on Canvas.

Updates the stored data with the given data if it is non-None.
Then updates Canvas with the stored data. Returns self for chaining.
"""
return self.update(data)

def rubric(self):
Expand Down Expand Up @@ -468,10 +537,17 @@ def send_assig_grade(self, student, assessment):


class Page(CourseSubObject):
"""A Canvas page (wikipage) object."""

def __init__(self, course, page_data):
"""Create a Page with course as parent and the given page data."""
super().__init__(course, "pages", page_data,
id_field="url", request_param_name="wiki_page")

def update_page(self, data=None):
"""Update this page on Canvas.

Updates the stored data with the given data if it is non-None.
Then updates Canvas with the stored data. Returns self for chaining.
"""
return self.update(data)
Loading