Repository: ucfopen/canvasapi (language: python)

Issue:
Find Missing Kwargs script doesn't check all files
When reviewing #455, I discovered that `scripts/find_missing_kwargs.py` is now finding missing `**kwargs` in `enrollment.py`. There is no difference between that file on the issue branch and on `develop`, yet the script finds the error **only** in the issue branch.

This behavior occurs both in Travis and when I run the script manually on my local environment.

It looks like the problem starts early on in the script:

```python
for _, module in inspect.getmembers(canvasapi, inspect.ismodule):
```

If I replace `_` with `module_name` and print out the name immediately after, the list of modules is considerably shorter than expected. I suspect it's related to some shenanigans with imports and how we set up the `canvasapi` module.


Discussion / hints:

Fix patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 67dd9805..f82277a6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,7 @@
 ### Bugfixes
 
 - Fixed an issue where kwargs were not passed along to Canvas in `Course.get_module()`. (Thanks, [@bennettscience](https://github.com/bennettscience))
+- Fixed an issue where not all functions allowed arbitrary keyword arguments. Added a test to detect and prevent this for the future.
 
 ## [3.0.0] - 2022-09-21
 
diff --git a/canvasapi/account.py b/canvasapi/account.py
index 2aa37ee5..46d4f941 100644
--- a/canvasapi/account.py
+++ b/canvasapi/account.py
@@ -1,12 +1,24 @@
+from canvasapi.authentication_event import AuthenticationEvent
+from canvasapi.authentication_provider import AuthenticationProvider
 from canvasapi.canvas_object import CanvasObject
+from canvasapi.content_migration import ContentMigration, Migrator
+from canvasapi.course import Course
+from canvasapi.enrollment import Enrollment
+from canvasapi.enrollment_term import EnrollmentTerm
 from canvasapi.exceptions import CanvasException, RequiredFieldMissing
+from canvasapi.external_tool import ExternalTool
 from canvasapi.feature import Feature, FeatureFlag
 from canvasapi.grading_period import GradingPeriod
 from canvasapi.grading_standard import GradingStandard
+from canvasapi.group import Group, GroupCategory
+from canvasapi.login import Login
+from canvasapi.outcome import OutcomeGroup, OutcomeLink
 from canvasapi.outcome_import import OutcomeImport
 from canvasapi.paginated_list import PaginatedList
 from canvasapi.rubric import Rubric
+from canvasapi.scope import Scope
 from canvasapi.sis_import import SisImport
+from canvasapi.user import User
 from canvasapi.util import combine_kwargs, file_or_path, obj_or_id, obj_or_str
 
 
@@ -62,8 +74,6 @@ def add_authentication_providers(self, **kwargs):
 
         :rtype: :class:`canvasapi.authentication_provider.AuthenticationProvider`
         """
-        from canvasapi.authentication_provider import AuthenticationProvider
-
         response = self._requester.request(
             "POST",
             "accounts/{}/authentication_providers".format(self.id),
@@ -123,8 +133,6 @@ def close_notification_for_user(self, user, notification, **kwargs):
 
         :rtype: :class:`canvasapi.account.AccountNotification`
         """
-        from canvasapi.user import User
-
         user_id = obj_or_id(user, "user", (User,))
         notif_id = obj_or_id(notification, "notification", (AccountNotification,))
 
@@ -165,8 +173,6 @@ def create_admin(self, user, **kwargs):
 
         :rtype: :class:`canvasapi.account.Admin`
         """
-        from canvasapi.user import User
-
         user_id = obj_or_id(user, "user", (User,))
         kwargs["user_id"] = user_id
 
@@ -189,8 +195,6 @@ def create_content_migration(self, migration_type, **kwargs):
 
         :rtype: :class:`canvasapi.content_migration.ContentMigration`
         """
-        from canvasapi.content_migration import ContentMigration, Migrator
-
         if isinstance(migration_type, Migrator):
             kwargs["migration_type"] = migration_type.type
         elif isinstance(migration_type, str):
@@ -218,8 +222,6 @@ def create_course(self, **kwargs):
 
         :rtype: :class:`canvasapi.course.Course`
         """
-        from canvasapi.course import Course
-
         response = self._requester.request(
             "POST",
             "accounts/{}/courses".format(self.id),
@@ -237,8 +239,6 @@ def create_enrollment_term(self, **kwargs):
 
         :rtype: :class:`canvasapi.enrollment_term.EnrollmentTerm`
         """
-        from canvasapi.enrollment_term import EnrollmentTerm
-
         response = self._requester.request(
             "POST",
             "accounts/{}/terms".format(self.id),
@@ -269,8 +269,6 @@ def create_external_tool(
         :type shared_secret: str
         :rtype: :class:`canvasapi.external_tool.ExternalTool`
         """
-        from canvasapi.external_tool import ExternalTool
-
         response = self._requester.request(
             "POST",
             "accounts/{}/external_tools".format(self.id),
@@ -296,8 +294,6 @@ def create_group_category(self, name, **kwargs):
         :type name: str
         :rtype: :class:`canvasapi.group.GroupCategory`
         """
-        from canvasapi.group import GroupCategory
-
         response = self._requester.request(
             "POST",
             "accounts/{}/group_categories".format(self.id),
@@ -326,10 +322,8 @@ def create_notification(self, account_notification, **kwargs):
             kwargs["account_notification"] = account_notification
         else:
             raise RequiredFieldMissing(
-                (
-                    "account_notification must be a dictionary with keys "
-                    "'subject', 'message', 'start_at', and 'end_at'."
-                )
+                "account_notification must be a dictionary with keys "
+                "'subject', 'message', 'start_at', and 'end_at'."
             )
 
         response = self._requester.request(
@@ -355,7 +349,6 @@ def create_report(self, report_type, **kwargs):
 
         :rtype: :class:`canvasapi.account.AccountReport`
         """
-
         response = self._requester.request(
             "POST",
             "accounts/{}/reports/{}".format(self.id, report_type),
@@ -398,7 +391,6 @@ def create_sis_import(self, attachment, **kwargs):
 
         :rtype: :class:`canvasapi.sis_import.SisImport`
         """
-
         attachment, is_path = file_or_path(attachment)
 
         try:
@@ -452,8 +444,6 @@ def create_user(self, pseudonym, **kwargs):
         :type pseudonym: dict
         :rtype: :class:`canvasapi.user.User`
         """
-        from canvasapi.user import User
-
         if isinstance(pseudonym, dict) and "unique_id" in pseudonym:
             kwargs["pseudonym"] = pseudonym
         else:
@@ -479,18 +469,16 @@ def create_user_login(self, user, login, **kwargs):
         :type login: `dict`
         :rtype: :class:`canvasapi.login.Login`
         """
-        from canvasapi.login import Login
-
         if isinstance(user, dict) and "id" in user:
             kwargs["user"] = user
         else:
-            raise RequiredFieldMissing(("user must be a dictionary with keys " "'id'."))
+            raise RequiredFieldMissing("user must be a dictionary with keys 'id'.")
 
         if isinstance(login, dict) and "unique_id" in login:
             kwargs["login"] = login
         else:
             raise RequiredFieldMissing(
-                ("login must be a dictionary with keys " "'unique_id'.")
+                "login must be a dictionary with keys 'unique_id'."
             )
 
         response = self._requester.request(
@@ -557,8 +545,6 @@ def delete_admin(self, user, **kwargs):
 
         :rtype: :class:`canvasapi.account.Admin`
         """
-        from canvasapi.user import User
-
         user_id = obj_or_id(user, "user", (User,))
         kwargs["user_id"] = user_id
 
@@ -616,8 +602,6 @@ def delete_user(self, user, **kwargs):
 
         :rtype: :class:`canvasapi.user.User`
         """
-        from canvasapi.user import User
-
         user_id = obj_or_id(user, "user", (User,))
 
         response = self._requester.request(
@@ -656,8 +640,6 @@ def get_all_outcome_links_in_context(self, **kwargs):
         :rtype: :class:`canvasapi.paginated_list.PaginatedList` of
             :class:`canvasapi.outcome.OutcomeLink`
         """
-        from canvasapi.outcome import OutcomeLink
-
         return PaginatedList(
             OutcomeLink,
             self._requester,
@@ -676,8 +658,6 @@ def get_authentication_events(self, **kwargs):
         :rtype: :class:`canvasapi.paginated_list.PaginatedList` of
                 :class:`canvasapi.authentication_event.AuthenticationEvent`
         """
-        from canvasapi.authentication_event import AuthenticationEvent
-
         return PaginatedList(
             AuthenticationEvent,
             self._requester,
@@ -699,8 +679,6 @@ def get_authentication_provider(self, authentication_provider, **kwargs):
 
         :rtype: :class:`canvasapi.authentication_provider.AuthenticationProvider`
         """
-        from canvasapi.authentication_provider import AuthenticationProvider
-
         authentication_providers_id = obj_or_id(
             authentication_provider,
             "authentication provider",
@@ -727,8 +705,6 @@ def get_authentication_providers(self, **kwargs):
         :rtype: :class:`canvasapi.paginated_list.PaginatedList` of
             :class:`canvasapi.authentication_provider.AuthenticationProvider`
         """
-        from canvasapi.authentication_provider import AuthenticationProvider
-
         return PaginatedList(
             AuthenticationProvider,
             self._requester,
@@ -750,8 +726,6 @@ def get_content_migration(self, content_migration, **kwargs):
 
         :rtype: :class:`canvasapi.content_migration.ContentMigration`
         """
-        from canvasapi.content_migration import ContentMigration
-
         migration_id = obj_or_id(
             content_migration, "content_migration", (ContentMigration,)
         )
@@ -777,8 +751,6 @@ def get_content_migrations(self, **kwargs):
         :rtype: :class:`canvasapi.paginated_list.PaginatedList` of
             :class:`canvasapi.content_migration.ContentMigration`
         """
-        from canvasapi.content_migration import ContentMigration
-
         return PaginatedList(
             ContentMigration,
             self._requester,
@@ -798,8 +770,6 @@ def get_courses(self, **kwargs):
         :rtype: :class:`canvasapi.paginated_list.PaginatedList` of
             :class:`canvasapi.course.Course`
         """
-        from canvasapi.course import Course
-
         return PaginatedList(
             Course,
             self._requester,
@@ -817,7 +787,6 @@ def get_department_level_grade_data_completed(self, **kwargs):
 
         :rtype: dict
         """
-
         response = self._requester.request(
             "GET",
             "accounts/{}/analytics/completed/grades".format(self.id),
@@ -834,7 +803,6 @@ def get_department_level_grade_data_current(self, **kwargs):
 
         :rtype: dict
         """
-
         response = self._requester.request(
             "GET",
             "accounts/{}/analytics/current/grades".format(self.id),
@@ -854,7 +822,6 @@ def get_department_level_grade_data_with_given_term(self, term_id, **kwargs):
 
         :rtype: dict
         """
-
         response = self._requester.request(
             "GET",
             "accounts/{}/analytics/terms/{}/grades".format(self.id, term_id),
@@ -871,7 +838,6 @@ def get_department_level_participation_data_completed(self, **kwargs):
 
         :rtype: dict
         """
-
         response = self._requester.request(
             "GET",
             "accounts/{}/analytics/completed/activity".format(self.id),
@@ -888,7 +854,6 @@ def get_department_level_participation_data_current(self, **kwargs):
 
         :rtype: dict
         """
-
         response = self._requester.request(
             "GET",
             "accounts/{}/analytics/current/activity".format(self.id),
@@ -910,7 +875,6 @@ def get_department_level_participation_data_with_given_term(
 
         :rtype: dict
         """
-
         response = self._requester.request(
             "GET",
             "accounts/{}/analytics/terms/{}/activity".format(self.id, term_id),
@@ -927,7 +891,6 @@ def get_department_level_statistics_completed(self, **kwargs):
 
         :rtype: dict
         """
-
         response = self._requester.request(
             "GET",
             "accounts/{}/analytics/completed/statistics".format(self.id),
@@ -944,7 +907,6 @@ def get_department_level_statistics_current(self, **kwargs):
 
         :rtype: dict
         """
-
         response = self._requester.request(
             "GET",
             "accounts/{}/analytics/current/statistics".format(self.id),
@@ -964,7 +926,6 @@ def get_department_level_statistics_with_given_term(self, term_id, **kwargs):
 
         :rtype: dict
         """
-
         response = self._requester.request(
             "GET",
             "accounts/{}/analytics/terms/{}/statistics".format(self.id, term_id),
@@ -1003,8 +964,6 @@ def get_enrollment(self, enrollment, **kwargs):
 
         :rtype: :class:`canvasapi.enrollment.Enrollment`
         """
-        from canvasapi.enrollment import Enrollment
-
         enrollment_id = obj_or_id(enrollment, "enrollment", (Enrollment,))
 
         response = self._requester.request(
@@ -1026,8 +985,6 @@ def get_enrollment_term(self, term, **kwargs):
 
         :rtype: :class:`canvasapi.enrollment_term.EnrollmentTerm`
         """
-        from canvasapi.enrollment_term import EnrollmentTerm
-
         term_id = obj_or_id(term, "term", (EnrollmentTerm,))
 
         response = self._requester.request(
@@ -1045,8 +1002,6 @@ def get_enrollment_terms(self, **kwargs):
         :rtype: :class:`canvasapi.paginated_list.PaginatedList` of
             :class:`canvasapi.enrollment_term.EnrollmentTerm`
         """
-        from canvasapi.enrollment_term import EnrollmentTerm
-
         return PaginatedList(
             EnrollmentTerm,
             self._requester,
@@ -1067,8 +1022,6 @@ def get_external_tool(self, tool, **kwargs):
 
         :rtype: :class:`canvasapi.external_tool.ExternalTool`
         """
-        from canvasapi.external_tool import ExternalTool
-
         tool_id = obj_or_id(tool, "tool", (ExternalTool,))
 
         response = self._requester.request(
@@ -1089,8 +1042,6 @@ def get_external_tools(self, **kwargs):
         :rtype: :class:`canvasapi.paginated_list.PaginatedList` of
             :class:`canvasapi.external_tool.ExternalTool`
         """
-        from canvasapi.external_tool import ExternalTool
-
         return PaginatedList(
             ExternalTool,
             self._requester,
@@ -1152,7 +1103,6 @@ def get_global_notification(self, notification_id, **kwargs):
 
         :rtype: :class:`canvasapi.account.AccountNotification`
         """
-
         response = self._requester.request(
             "GET",
             "accounts/{}/account_notifications/{}".format(self.id, notification_id),
@@ -1174,7 +1124,6 @@ def get_grading_periods(self, **kwargs):
         :rtype: :class:`canvasapi.paginated_list.PaginatedList` of
             :class:`canvasapi.grading_period.GradingPeriod`
         """
-
         return PaginatedList(
             GradingPeriod,
             self._requester,
@@ -1195,7 +1144,6 @@ def get_grading_standards(self, **kwargs):
         :rtype: :class:`canvasapi.paginated_list.PaginatedList` of
             :class:`canvasapi.grading_standards.GradingStandard`
         """
-
         return PaginatedList(
             GradingStandard,
             self._requester,
@@ -1214,8 +1162,6 @@ def get_group_categories(self, **kwargs):
         :rtype: :class:`canvasapi.paginated_list.PaginatedList` of
             :class:`canvasapi.group.GroupCategory`
         """
-        from canvasapi.group import GroupCategory
-
         return PaginatedList(
             GroupCategory,
             self._requester,
@@ -1233,8 +1179,6 @@ def get_groups(self, **kwargs):
 
         :rtype: :class:`canvasapi.paginated_list.PaginatedList` of :class:`canvasapi.group.Group`
         """
-        from canvasapi.group import Group
-
         return PaginatedList(
             Group,
             self._requester,
@@ -1274,8 +1218,6 @@ def get_migration_systems(self, **kwargs):
         :rtype: :class:`canvasapi.paginated_list.PaginatedList` of
             :class:`canvasapi.content_migration.Migrator`
         """
-        from canvasapi.content_migration import Migrator
-
         return PaginatedList(
             Migrator,
             self._requester,
@@ -1298,8 +1240,6 @@ def get_outcome_group(self, group, **kwargs):
         :returns: An outcome group object.
         :rtype: :class:`canvasapi.outcome.OutcomeGroup`
         """
-        from canvasapi.outcome import OutcomeGroup
-
         outcome_group_id = obj_or_id(group, "outcome group", (OutcomeGroup,))
         response = self._requester.request(
             "GET",
@@ -1320,8 +1260,6 @@ def get_outcome_groups_in_context(self, **kwargs):
         :rtype: :class:`canvasapi.paginated_list.PaginatedList` of
             :class:`canvasapi.outcome.OutcomeGroups`
         """
-        from canvasapi.outcome import OutcomeGroup
-
         return PaginatedList(
             OutcomeGroup,
             self._requester,
@@ -1438,7 +1376,6 @@ def get_roles(self, **kwargs):
         :rtype: :class:`canvasapi.paginated_list.PaginatedList` of
             :class:`canvasapi.account.Role`
         """
-
         return PaginatedList(
             Role,
             self._requester,
@@ -1457,8 +1394,6 @@ def get_root_outcome_group(self, **kwargs):
         :returns: The OutcomeGroup of the context.
         :rtype: :class:`canvasapi.outcome.OutcomeGroup`
         """
-        from canvasapi.outcome import OutcomeGroup
-
         response = self._requester.request(
             "GET",
             "accounts/{}/root_outcome_group".format(self.id),
@@ -1512,8 +1447,6 @@ def get_scopes(self, **kwargs):
 
         :rtype: :class:`canvasapi.paginated_list.PaginatedList` of :class:`canvasapi.scope.Scope`
         """
-        from canvasapi.scope import Scope
-
         return PaginatedList(
             Scope,
             self._requester,
@@ -1533,7 +1466,6 @@ def get_single_grading_standard(self, grading_standard_id, **kwargs):
         :type grading_standard_id: int
         :rtype: :class:`canvasapi.grading_standards.GradingStandard`
         """
-
         response = self._requester.request(
             "GET",
             "accounts/%s/grading_standards/%d" % (self.id, grading_standard_id),
@@ -1576,7 +1508,6 @@ def get_sis_imports(self, **kwargs):
         :rtype: :class:`canvasapi.paginated_list.PaginatedList` of
             :class:`canvasapi.sis_import.SisImport`
         """
-
         return PaginatedList(
             SisImport,
             self._requester,
@@ -1597,7 +1528,6 @@ def get_sis_imports_running(self, **kwargs):
         :rtype: :class:`canvasapi.paginated_list.PaginatedList`
             of :class:`canvasapi.sis_import.SisImport`
         """
-
         return PaginatedList(
             SisImport,
             self._requester,
@@ -1640,8 +1570,6 @@ def get_user_logins(self, **kwargs):
         :rtype: :class:`canvasapi.paginated_list.PaginatedList` of
             :class:`canvasapi.login.Login`
         """
-        from canvasapi.login import Login
-
         return PaginatedList(
             Login,
             self._requester,
@@ -1665,8 +1593,6 @@ def get_user_notifications(self, user, **kwargs):
         :rtype: :class:`canvasapi.paginated_list.PaginatedList` of
             :class:`canvasapi.account.AccountNotification`
         """
-        from canvasapi.user import User
-
         user_id = obj_or_id(user, "user", (User,))
 
         return PaginatedList(
@@ -1686,8 +1612,6 @@ def get_users(self, **kwargs):
 
         :rtype: :class:`canvasapi.paginated_list.PaginatedList` of :class:`canvasapi.user.User`
         """
-        from canvasapi.user import User
-
         return PaginatedList(
             User,
             self._requester,
@@ -1708,7 +1632,6 @@ def import_outcome(self, attachment, **kwargs):
 
         :rtype: :class:`canvasapi.outcome_import.OutcomeImport`
         """
-
         attachment, is_path = file_or_path(attachment)
 
         try:
@@ -1736,7 +1659,6 @@ def show_account_auth_settings(self, **kwargs):
 
         :rtype: :class:`canvasapi.account.SSOSettings`
         """
-
         response = self._requester.request(
             "GET",
             "accounts/{}/sso_settings".format(self.id),
@@ -1774,7 +1696,6 @@ def update_account_auth_settings(self, **kwargs):
 
         :rtype: :class:`canvasapi.account.SSOSettings`
         """
-
         response = self._requester.request(
             "PUT",
             "accounts/{}/sso_settings".format(self.id),
@@ -1830,10 +1751,8 @@ def update_global_notification(self, account_notification, **kwargs):
             kwargs["account_notification"] = account_notification
         else:
             raise RequiredFieldMissing(
-                (
-                    "account_notification must be a dictionary with keys "
-                    "'subject', 'message', 'start_at', and 'end_at'."
-                )
+                "account_notification must be a dictionary with keys "
+                "'subject', 'message', 'start_at', and 'end_at'."
             )
 
         response = self._requester.request(
diff --git a/canvasapi/authentication_provider.py b/canvasapi/authentication_provider.py
index 5ffd5c36..f74a7994 100644
--- a/canvasapi/authentication_provider.py
+++ b/canvasapi/authentication_provider.py
@@ -6,6 +6,22 @@ class AuthenticationProvider(CanvasObject):
     def __str__(self):  # pragma: no cover
         return "{} ({})".format(self.auth_type, self.position)
 
+    def delete(self, **kwargs):
+        """
+        Delete the config
+
+        :calls: `DELETE /api/v1/accounts/:account_id/authentication_providers/:id \
+        <https://canvas.instructure.com/doc/api/authentication_providers.html#method.account_authorization_configs.destroy>`_
+
+        :rtype: :class:`canvasapi.authentication_provider.AuthenticationProvider`
+        """
+        response = self._requester.request(
+            "DELETE",
+            "accounts/{}/authentication_providers/{}".format(self.account_id, self.id),
+            _kwargs=combine_kwargs(**kwargs),
+        )
+        return AuthenticationProvider(self._requester, response.json())
+
     def update(self, **kwargs):
         """
         Update an authentication provider using the same options as the create endpoint
@@ -25,18 +41,3 @@ def update(self, **kwargs):
             super(AuthenticationProvider, self).set_attributes(response.json())
 
         return response.json().get("auth_type")
-
-    def delete(self):
-        """
-        Delete the config
-
-        :calls: `DELETE /api/v1/accounts/:account_id/authentication_providers/:id \
-        <https://canvas.instructure.com/doc/api/authentication_providers.html#method.account_authorization_configs.destroy>`_
-
-        :rtype: :class:`canvasapi.authentication_provider.AuthenticationProvider`
-        """
-        response = self._requester.request(
-            "DELETE",
-            "accounts/{}/authentication_providers/{}".format(self.account_id, self.id),
-        )
-        return AuthenticationProvider(self._requester, response.json())
diff --git a/canvasapi/canvas.py b/canvasapi/canvas.py
index 7912ee8e..c90ae7de 100644
--- a/canvasapi/canvas.py
+++ b/canvasapi/canvas.py
@@ -1,16 +1,24 @@
 import warnings
 
 from canvasapi.account import Account
+from canvasapi.appointment_group import AppointmentGroup
+from canvasapi.calendar_event import CalendarEvent
 from canvasapi.comm_message import CommMessage
-from canvasapi.course import Course
+from canvasapi.conversation import Conversation
+from canvasapi.course import Course, CourseNickname
 from canvasapi.course_epub_export import CourseEpubExport
 from canvasapi.current_user import CurrentUser
+from canvasapi.discussion_topic import DiscussionTopic
 from canvasapi.eportfolio import EPortfolio
 from canvasapi.exceptions import RequiredFieldMissing
 from canvasapi.file import File
 from canvasapi.folder import Folder
 from canvasapi.group import Group, GroupCategory
+from canvasapi.outcome import Outcome, OutcomeGroup
 from canvasapi.paginated_list import PaginatedList
+from canvasapi.planner import PlannerNote, PlannerOverride
+from canvasapi.poll import Poll
+from canvasapi.progress import Progress
 from canvasapi.requester import Requester
 from canvasapi.section import Section
 from canvasapi.todo import Todo
@@ -93,9 +101,6 @@ def conversations_batch_update(self, conversation_ids, event, **kwargs):
         :type event: `str`
         :rtype: :class:`canvasapi.progress.Progress`
         """
-
-        from canvasapi.progress import Progress
-
         ALLOWED_EVENTS = [
             "mark_as_read",
             "mark_as_unread",
@@ -206,8 +211,6 @@ def create_appointment_group(self, appointment_group, **kwargs):
         :type title: `str`
         :rtype: :class:`canvasapi.appointment_group.AppointmentGroup`
         """
-        from canvasapi.appointment_group import AppointmentGroup
-
         if (
             isinstance(appointment_group, dict)
             and "context_codes" in appointment_group
@@ -243,8 +246,6 @@ def create_calendar_event(self, calendar_event, **kwargs):
         :type calendar_event: `dict`
         :rtype: :class:`canvasapi.calendar_event.CalendarEvent`
         """
-        from canvasapi.calendar_event import CalendarEvent
-
         if isinstance(calendar_event, dict) and "context_code" in calendar_event:
             kwargs["calendar_event"] = calendar_event
         else:
@@ -274,8 +275,6 @@ def create_conversation(self, recipients, body, **kwargs):
         :type body: `str`
         :rtype: list of :class:`canvasapi.conversation.Conversation`
         """
-        from canvasapi.conversation import Conversation
-
         kwargs["recipients"] = recipients
         kwargs["body"] = body
 
@@ -307,8 +306,6 @@ def create_planner_note(self, **kwargs):
 
         :rtype: :class:`canvasapi.planner.PlannerNote`
         """
-        from canvasapi.planner import PlannerNote
-
         response = self.__requester.request(
             "POST", "planner_notes", _kwargs=combine_kwargs(**kwargs)
         )
@@ -329,8 +326,6 @@ def create_planner_override(self, plannable_type, plannable_id, **kwargs):
 
         :rtype: :class:`canvasapi.planner.PlannerOverride`
         """
-        from canvasapi.planner import PlannerOverride
-
         if isinstance(plannable_type, str):
             kwargs["plannable_type"] = plannable_type
         else:
@@ -356,8 +351,6 @@ def create_poll(self, polls, **kwargs):
         :type polls: list of dict
         :rtype: :class:`canvasapi.poll.Poll`
         """
-        from canvasapi.poll import Poll
-
         if (
             isinstance(polls, list)
             and isinstance(polls[0], dict)
@@ -452,8 +445,6 @@ def get_announcements(self, context_codes, **kwargs):
         :rtype: :class:`canvasapi.paginated_list.PaginatedList` of
                 :class:`canvasapi.discussion_topic.DiscussionTopic`
         """
-        from canvasapi.discussion_topic import DiscussionTopic
-
         if type(context_codes) is not list or len(context_codes) == 0:
             raise RequiredFieldMissing("context_codes need to be passed as a list")
 
@@ -493,8 +484,6 @@ def get_appointment_group(self, appointment_group, **kwargs):
 
         :rtype: :class:`canvasapi.appointment_group.AppointmentGroup`
         """
-        from canvasapi.appointment_group import AppointmentGroup
-
         appointment_group_id = obj_or_id(
             appointment_group, "appointment_group", (AppointmentGroup,)
         )
@@ -516,8 +505,6 @@ def get_appointment_groups(self, **kwargs):
         :rtype: :class:`canvasapi.paginated_list.PaginatedList` of
             :class:`canvasapi.appointment_group.AppointmentGroup`
         """
-        from canvasapi.appointment_group import AppointmentGroup
-
         return PaginatedList(
             AppointmentGroup,
             self.__requester,
@@ -553,8 +540,6 @@ def get_calendar_event(self, calendar_event, **kwargs):
 
         :rtype: :class:`canvasapi.calendar_event.CalendarEvent`
         """
-        from canvasapi.calendar_event import CalendarEvent
-
         calendar_event_id = obj_or_id(
             calendar_event, "calendar_event", (CalendarEvent,)
         )
@@ -576,8 +561,6 @@ def get_calendar_events(self, **kwargs):
         :rtype: :class:`canvasapi.paginated_list.PaginatedList` of
             :class:`canvasapi.calendar_event.CalendarEvent`
         """
-        from canvasapi.calendar_event import CalendarEvent
-
         return PaginatedList(
             CalendarEvent,
             self.__requester,
@@ -624,8 +607,6 @@ def get_conversation(self, conversation, **kwargs):
 
         :rtype: :class:`canvasapi.conversation.Conversation`
         """
-        from canvasapi.conversation import Conversation
-
         conversation_id = obj_or_id(conversation, "conversation", (Conversation,))
 
         response = self.__requester.request(
@@ -645,8 +626,6 @@ def get_conversations(self, **kwargs):
         :rtype: :class:`canvasapi.paginated_list.PaginatedList` of \
         :class:`canvasapi.conversation.Conversation`
         """
-        from canvasapi.conversation import Conversation
-
         return PaginatedList(
             Conversation,
             self.__requester,
@@ -716,8 +695,6 @@ def get_course_nickname(self, course, **kwargs):
 
         :rtype: :class:`canvasapi.course.CourseNickname`
         """
-        from canvasapi.course import CourseNickname
-
         course_id = obj_or_id(course, "course", (Course,))
 
         response = self.__requester.request(
@@ -737,8 +714,6 @@ def get_course_nicknames(self, **kwargs):
         :rtype: :class:`canvasapi.paginated_list.PaginatedList` of
             :class:`canvasapi.course.CourseNickname`
         """
-        from canvasapi.course import CourseNickname
-
         return PaginatedList(
             CourseNickname,
             self.__requester,
@@ -914,9 +889,6 @@ def get_group_participants(self, appointment_group, **kwargs):
 
         :rtype: :class:`canvasapi.paginated_list.PaginatedList` of :class:`canvasapi.group.Group`
         """
-        from canvasapi.appointment_group import AppointmentGroup
-        from canvasapi.group import Group
-
         appointment_group_id = obj_or_id(
             appointment_group, "appointment_group", (AppointmentGroup,)
         )
@@ -942,8 +914,6 @@ def get_outcome(self, outcome, **kwargs):
         :returns: An Outcome object.
         :rtype: :class:`canvasapi.outcome.Outcome`
         """
-        from canvasapi.outcome import Outcome
-
         outcome_id = obj_or_id(outcome, "outcome", (Outcome,))
         response = self.__requester.request(
             "GET", "outcomes/{}".format(outcome_id), _kwargs=combine_kwargs(**kwargs)
@@ -963,8 +933,6 @@ def get_outcome_group(self, group, **kwargs):
         :returns: An outcome group object.
         :rtype: :class:`canvasapi.outcome.OutcomeGroup`
         """
-        from canvasapi.outcome import OutcomeGroup
-
         outcome_group_id = obj_or_id(group, "group", (OutcomeGroup,))
 
         response = self.__requester.request(
@@ -987,8 +955,6 @@ def get_planner_note(self, planner_note, **kwargs):
 
         :rtype: :class:`canvasapi.planner.PlannerNote`
         """
-        from canvasapi.planner import PlannerNote
-
         if isinstance(planner_note, int) or isinstance(planner_note, PlannerNote):
             planner_note_id = obj_or_id(planner_note, "planner_note", (PlannerNote,))
         else:
@@ -1014,8 +980,6 @@ def get_planner_notes(self, **kwargs):
         :rtype: :class:`canvasapi.paginated_list.PaginatedList` of
             :class:`canvasapi.planner.PlannerNote`
         """
-        from canvasapi.planner import PlannerNote
-
         return PaginatedList(
             PlannerNote,
             self.__requester,
@@ -1036,8 +1000,6 @@ def get_planner_override(self, planner_override, **kwargs):
 
         :rtype: :class:`canvasapi.planner.PlannerOverride`
         """
-        from canvasapi.planner import PlannerOverride
-
         if isinstance(planner_override, int) or isinstance(
             planner_override, PlannerOverride
         ):
@@ -1067,8 +1029,6 @@ def get_planner_overrides(self, **kwargs):
         :rtype: :class:`canvasapi.paginated_list.PaginatedList` of
             :class:`canvasapi.planner.PlannerOverride`
         """
-        from canvasapi.planner import PlannerOverride
-
         return PaginatedList(
             PlannerOverride,
             self.__requester,
@@ -1088,8 +1048,6 @@ def get_poll(self, poll, **kwargs):
         :type poll: int
         :rtype: :class:`canvasapi.poll.Poll`
         """
-        from canvasapi.poll import Poll
-
         poll_id = obj_or_id(poll, "poll", (Poll,))
 
         response = self.__requester.request(
@@ -1107,8 +1065,6 @@ def get_polls(self, **kwargs):
         :rtype: :class:`canvasapi.paginated_list.PaginatedList` of
             :class:`canvasapi.poll.Poll`
         """
-        from canvasapi.poll import Poll
-
         return PaginatedList(
             Poll,
             self.__requester,
@@ -1130,9 +1086,6 @@ def get_progress(self, progress, **kwargs):
 
         :rtype: :class:`canvasapi.progress.Progress`
         """
-
-        from canvasapi.progress import Progress
-
         progress_id = obj_or_id(progress, "progress", (Progress,))
 
         response = self.__requester.request(
@@ -1150,8 +1103,6 @@ def get_root_outcome_group(self, **kwargs):
         :returns: The OutcomeGroup of the context.
         :rtype: :class:`canvasapi.outcome.OutcomeGroup`
         """
-        from canvasapi.outcome import OutcomeGroup
-
         response = self.__requester.request(
             "GET", "global/root_outcome_group", _kwargs=combine_kwargs(**kwargs)
         )
@@ -1260,9 +1211,6 @@ def get_user_participants(self, appointment_group, **kwargs):
 
         :rtype: :class:`canvasapi.paginated_list.PaginatedList` of :class:`canvasapi.user.User`
         """
-        from canvasapi.appointment_group import AppointmentGroup
-        from canvasapi.user import User
-
         appointment_group_id = obj_or_id(
             appointment_group, "appointment_group", (AppointmentGroup,)
         )
@@ -1317,8 +1265,6 @@ def reserve_time_slot(self, calendar_event, participant_id=None, **kwargs):
 
         :rtype: :class:`canvasapi.calendar_event.CalendarEvent`
         """
-        from canvasapi.calendar_event import CalendarEvent
-
         calendar_event_id = obj_or_id(
             calendar_event, "calendar_event", (CalendarEvent,)
         )
@@ -1400,8 +1346,6 @@ def set_course_nickname(self, course, nickname, **kwargs):
 
         :rtype: :class:`canvasapi.course.CourseNickname`
         """
-        from canvasapi.course import CourseNickname
-
         course_id = obj_or_id(course, "course", (Course,))
 
         kwargs["nickname"] = nickname
diff --git a/canvasapi/conversation.py b/canvasapi/conversation.py
index d1714b49..bb59f7db 100644
--- a/canvasapi/conversation.py
+++ b/canvasapi/conversation.py
@@ -6,43 +6,27 @@ class Conversation(CanvasObject):
     def __str__(self):
         return "{} ({})".format(self.subject, self.id)
 
-    def edit(self, **kwargs):
+    def add_message(self, body, **kwargs):
         """
-        Update a conversation.
+        Add a message to a conversation.
 
-        :calls: `PUT /api/v1/conversations/:id \
-        <https://canvas.instructure.com/doc/api/conversations.html#method.conversations.update>`_
+        :calls: `POST /api/v1/conversations/:id/add_message \
+        <https://canvas.instructure.com/doc/api/conversations.html#method.conversations.add_message>`_
 
-        :rtype: `bool`
+        :param body: The body of the conversation.
+        :type body: str
+        :returns: A conversation with only the most recent message.
+        :rtype: :class:`canvasapi.account.Conversation`
         """
         response = self._requester.request(
-            "PUT", "conversations/{}".format(self.id), _kwargs=combine_kwargs(**kwargs)
+            "POST",
+            "conversations/{}/add_message".format(self.id),
+            body=body,
+            _kwargs=combine_kwargs(**kwargs),
         )
+        return Conversation(self._requester, response.json())
 
-        if response.json().get("id"):
-            super(Conversation, self).set_attributes(response.json())
-            return True
-        else:
-            return False
-
-    def delete(self):
-        """
-        Delete a conversation.
-
-        :calls: `DELETE /api/v1/conversations/:id \
-        <https://canvas.instructure.com/doc/api/conversations.html#method.conversations.destroy>`_
-
-        :rtype: `bool`
-        """
-        response = self._requester.request("DELETE", "conversations/{}".format(self.id))
-
-        if response.json().get("id"):
-            super(Conversation, self).set_attributes(response.json())
-            return True
-        else:
-            return False
-
-    def add_recipients(self, recipients):
+    def add_recipients(self, recipients, **kwargs):
         """
         Add a recipient to a conversation.
 
@@ -60,30 +44,32 @@ def add_recipients(self, recipients):
             "POST",
             "conversations/{}/add_recipients".format(self.id),
             recipients=recipients,
+            _kwargs=combine_kwargs(**kwargs),
         )
         return Conversation(self._requester, response.json())
 
-    def add_message(self, body, **kwargs):
+    def delete(self, **kwargs):
         """
-        Add a message to a conversation.
+        Delete a conversation.
 
-        :calls: `POST /api/v1/conversations/:id/add_message \
-        <https://canvas.instructure.com/doc/api/conversations.html#method.conversations.add_message>`_
+        :calls: `DELETE /api/v1/conversations/:id \
+        <https://canvas.instructure.com/doc/api/conversations.html#method.conversations.destroy>`_
 
-        :param body: The body of the conversation.
-        :type body: str
-        :returns: A conversation with only the most recent message.
-        :rtype: :class:`canvasapi.account.Conversation`
+        :rtype: `bool`
         """
         response = self._requester.request(
-            "POST",
-            "conversations/{}/add_message".format(self.id),
-            body=body,
+            "DELETE",
+            "conversations/{}".format(self.id),
             _kwargs=combine_kwargs(**kwargs),
         )
-        return Conversation(self._requester, response.json())
 
-    def delete_messages(self, remove):
+        if response.json().get("id"):
+            super(Conversation, self).set_attributes(response.json())
+            return True
+        else:
+            return False
+
+    def delete_messages(self, remove, **kwargs):
         """
         Delete messages from this conversation.
 
@@ -98,6 +84,28 @@ def delete_messages(self, remove):
         :rtype: `dict`
         """
         response = self._requester.request(
-            "POST", "conversations/{}/remove_messages".format(self.id), remove=remove
+            "POST",
+            "conversations/{}/remove_messages".format(self.id),
+            remove=remove,
+            _kwargs=combine_kwargs(**kwargs),
         )
         return response.json()
+
+    def edit(self, **kwargs):
+        """
+        Update a conversation.
+
+        :calls: `PUT /api/v1/conversations/:id \
+        <https://canvas.instructure.com/doc/api/conversations.html#method.conversations.update>`_
+
+        :rtype: `bool`
+        """
+        response = self._requester.request(
+            "PUT", "conversations/{}".format(self.id), _kwargs=combine_kwargs(**kwargs)
+        )
+
+        if response.json().get("id"):
+            super(Conversation, self).set_attributes(response.json())
+            return True
+        else:
+            return False
diff --git a/canvasapi/course.py b/canvasapi/course.py
index 46f6a361..733e7b6d 100644
--- a/canvasapi/course.py
+++ b/canvasapi/course.py
@@ -4,10 +4,12 @@
 from canvasapi.blueprint import BlueprintSubscription
 from canvasapi.canvas_object import CanvasObject
 from canvasapi.collaboration import Collaboration
+from canvasapi.content_export import ContentExport
 from canvasapi.course_epub_export import CourseEpubExport
 from canvasapi.custom_gradebook_columns import CustomGradebookColumn
 from canvasapi.discussion_topic import DiscussionTopic
 from canvasapi.exceptions import RequiredFieldMissing
+from canvasapi.external_feed import ExternalFeed
 from canvasapi.feature import Feature, FeatureFlag
 from canvasapi.folder import Folder
 from canvasapi.grade_change_log import GradeChangeEvent
@@ -20,6 +22,7 @@
 from canvasapi.grading_period import GradingPeriod
 from canvasapi.grading_standard import GradingStandard
 from canvasapi.license import License
+from canvasapi.module import Module
 from canvasapi.outcome_import import OutcomeImport
 from canvasapi.page import Page
 from canvasapi.paginated_list import PaginatedList
@@ -322,8 +325,6 @@ def create_external_feed(self, url, **kwargs):
         :type url: str
         :rtype: :class:`canvasapi.external_feed.ExternalFeed`
         """
-        from canvasapi.external_feed import ExternalFeed
-
         response = self._requester.request(
             "POST",
             "courses/{}/external_feeds".format(self.id),
@@ -435,8 +436,6 @@ def create_module(self, module, **kwargs):
         :returns: The created module.
         :rtype: :class:`canvasapi.module.Module`
         """
-        from canvasapi.module import Module
-
         if isinstance(module, dict) and "name" in module:
             kwargs["module"] = module
         else:
@@ -596,8 +595,6 @@ def delete_external_feed(self, feed, **kwargs):
 
         :rtype: :class:`canvasapi.external_feed.ExternalFeed`
         """
-        from canvasapi.external_feed import ExternalFeed
-
         feed_id = obj_or_id(feed, "feed", (ExternalFeed,))
 
         response = self._requester.request(
@@ -695,8 +692,6 @@ def export_content(self, export_type, **kwargs):
 
         :rtype: :class:`canvasapi.content_export.ContentExport`
         """
-        from canvasapi.content_export import ContentExport
-
         kwargs["export_type"] = export_type
 
         response = self._requester.request(
@@ -927,8 +922,6 @@ def get_content_export(self, content_export, **kwargs):
 
         :rtype: :class:`canvasapi.content_export.ContentExport`
         """
-        from canvasapi.content_export import ContentExport
-
         export_id = obj_or_id(content_export, "content_export", (ContentExport,))
 
         response = self._requester.request(
@@ -949,8 +942,6 @@ def get_content_exports(self, **kwargs):
         :rtype: :class:`canvasapi.paginated_list.PaginatedList` of
             :class:`canvasapi.content_export.ContentExport`
         """
-        from canvasapi.content_export import ContentExport
-
         return PaginatedList(
             ContentExport,
             self._requester,
@@ -1200,8 +1191,6 @@ def get_external_feeds(self, **kwargs):
         :rtype: :class:`canvasapi.paginated_list.PaginatedList` of
             :class:`canvasapi.external_feed.ExternalFeed`
         """
-        from canvasapi.external_feed import ExternalFeed
-
         return PaginatedList(
             ExternalFeed,
             self._requester,
@@ -1653,8 +1642,6 @@ def get_module(self, module, **kwargs):
 
         :rtype: :class:`canvasapi.module.Module`
         """
-        from canvasapi.module import Module
-
         module_id = obj_or_id(module, "module", (Module,))
 
         response = self._requester.request(
@@ -1678,8 +1665,6 @@ def get_modules(self, **kwargs):
         :rtype: :class:`canvasapi.paginated_list.PaginatedList` of
             :class:`canvasapi.module.Module`
         """
-        from canvasapi.module import Module
-
         return PaginatedList(
             Module,
             self._requester,
diff --git a/canvasapi/enrollment_term.py b/canvasapi/enrollment_term.py
index a2a4d148..8de88e80 100644
--- a/canvasapi/enrollment_term.py
+++ b/canvasapi/enrollment_term.py
@@ -6,7 +6,7 @@ class EnrollmentTerm(CanvasObject):
     def __str__(self):
         return "{} ({})".format(self.name, self.id)
 
-    def delete(self):
+    def delete(self, **kwargs):
         """
         Delete this Enrollment Term.
 
@@ -16,7 +16,9 @@ def delete(self):
         :rtype: :class:`canvasapi.enrollment_term.EnrollmentTerm`
         """
         response = self._requester.request(
-            "DELETE", "accounts/{}/terms/{}".format(self.account_id, self.id)
+            "DELETE",
+            "accounts/{}/terms/{}".format(self.account_id, self.id),
+            _kwargs=combine_kwargs(**kwargs),
         )
         return EnrollmentTerm(self._requester, response.json())
 
diff --git a/canvasapi/external_tool.py b/canvasapi/external_tool.py
index 41d5616c..9d8afa24 100644
--- a/canvasapi/external_tool.py
+++ b/canvasapi/external_tool.py
@@ -35,25 +35,7 @@ def parent_type(self):
         else:
             raise ValueError("ExternalTool does not have a course_id or account_id")
 
-    def get_parent(self):
-        """
-        Return the object that spawned this tool.
-
-        :rtype: :class:`canvasapi.account.Account` or :class:`canvasapi.account.Course`
-        """
-        from canvasapi.account import Account
-        from canvasapi.course import Course
-
-        response = self._requester.request(
-            "GET", "{}s/{}".format(self.parent_type, self.parent_id)
-        )
-
-        if self.parent_type == "account":
-            return Account(self._requester, response.json())
-        elif self.parent_type == "course":
-            return Course(self._requester, response.json())
-
-    def delete(self):
+    def delete(self, **kwargs):
         """
         Remove the specified external tool.
 
@@ -69,6 +51,7 @@ def delete(self):
             "{}s/{}/external_tools/{}".format(
                 self.parent_type, self.parent_id, self.id
             ),
+            _kwargs=combine_kwargs(**kwargs),
         )
 
         return ExternalTool(self._requester, response.json())
@@ -98,6 +81,26 @@ def edit(self, **kwargs):
 
         return ExternalTool(self._requester, response_json)
 
+    def get_parent(self, **kwargs):
+        """
+        Return the object that spawned this tool.
+
+        :rtype: :class:`canvasapi.account.Account` or :class:`canvasapi.account.Course`
+        """
+        from canvasapi.account import Account
+        from canvasapi.course import Course
+
+        response = self._requester.request(
+            "GET",
+            "{}s/{}".format(self.parent_type, self.parent_id),
+            _kwargs=combine_kwargs(**kwargs),
+        )
+
+        if self.parent_type == "account":
+            return Account(self._requester, response.json())
+        elif self.parent_type == "course":
+            return Course(self._requester, response.json())
+
     def get_sessionless_launch_url(self, **kwargs):
         """
         Return a sessionless launch url for an external tool.
diff --git a/canvasapi/group.py b/canvasapi/group.py
index 1acb6666..b9aaad41 100644
--- a/canvasapi/group.py
+++ b/canvasapi/group.py
@@ -2,6 +2,7 @@
 from canvasapi.collaboration import Collaboration
 from canvasapi.discussion_topic import DiscussionTopic
 from canvasapi.exceptions import RequiredFieldMissing
+from canvasapi.external_feed import ExternalFeed
 from canvasapi.folder import Folder
 from canvasapi.license import License
 from canvasapi.paginated_list import PaginatedList
@@ -78,8 +79,6 @@ def create_external_feed(self, url, **kwargs):
         :type url: str
         :rtype: :class:`canvasapi.external_feed.ExternalFeed`
         """
-        from canvasapi.external_feed import ExternalFeed
-
         response = self._requester.request(
             "POST",
             "groups/{}/external_feeds".format(self.id),
diff --git a/canvasapi/login.py b/canvasapi/login.py
index e24f8442..5089e9bd 100644
--- a/canvasapi/login.py
+++ b/canvasapi/login.py
@@ -7,7 +7,7 @@ class Login(CanvasObject):
     def __str__(self):
         return "{} ({})".format(self.id, self.unique_id)
 
-    def delete(self):
+    def delete(self, **kwargs):
         """
         Delete an existing login.
 
@@ -17,7 +17,9 @@ def delete(self):
         :rtype: :class:`canvasapi.login.Login`
         """
         response = self._requester.request(
-            "DELETE", "users/{}/logins/{}".format(self.user_id, self.id)
+            "DELETE",
+            "users/{}/logins/{}".format(self.user_id, self.id),
+            _kwargs=combine_kwargs(**kwargs),
         )
         return Login(self._requester, response.json())
 
diff --git a/canvasapi/module.py b/canvasapi/module.py
index fe6b3b28..4403af4a 100644
--- a/canvasapi/module.py
+++ b/canvasapi/module.py
@@ -8,26 +8,43 @@ class Module(CanvasObject):
     def __str__(self):
         return "{} ({})".format(self.name, self.id)
 
-    def edit(self, **kwargs):
+    def create_module_item(self, module_item, **kwargs):
         """
-        Update this module.
+        Create a module item.
 
-        :calls: `PUT /api/v1/courses/:course_id/modules/:id \
-        <https://canvas.instructure.com/doc/api/modules.html#method.context_modules_api.update>`_
+        :calls: `POST /api/v1/courses/:course_id/modules/:module_id/items \
+        <https://canvas.instructure.com/doc/api/modules.html#method.context_module_items_api.create>`_
 
-        :rtype: :class:`canvasapi.module.Module`
+        :param module_item: The attributes to create the module item with.
+        :type module_item: dict
+        :returns: The created module item.
+        :rtype: :class:`canvasapi.module.ModuleItem`
         """
+
+        unrequired_types = ["ExternalUrl", "Page", "SubHeader"]
+
+        if isinstance(module_item, dict) and "type" in module_item:
+            # content_id is not required for unrequired_types
+            if module_item["type"] in unrequired_types or "content_id" in module_item:
+                kwargs["module_item"] = module_item
+            else:
+                raise RequiredFieldMissing(
+                    "Dictionary with key 'content_id' is required."
+                )
+        else:
+            raise RequiredFieldMissing("Dictionary with key 'type' is required.")
+
         response = self._requester.request(
-            "PUT",
-            "courses/{}/modules/{}".format(self.course_id, self.id),
+            "POST",
+            "courses/{}/modules/{}/items".format(self.course_id, self.id),
             _kwargs=combine_kwargs(**kwargs),
         )
-        module_json = response.json()
-        module_json.update({"course_id": self.course_id})
+        module_item_json = response.json()
+        module_item_json.update({"course_id": self.course_id})
 
-        return Module(self._requester, module_json)
+        return ModuleItem(self._requester, module_item_json)
 
-    def delete(self):
+    def delete(self, **kwargs):
         """
         Delete this module.
 
@@ -37,53 +54,34 @@ def delete(self):
         :rtype: :class:`canvasapi.module.Module`
         """
         response = self._requester.request(
-            "DELETE", "courses/{}/modules/{}".format(self.course_id, self.id)
+            "DELETE",
+            "courses/{}/modules/{}".format(self.course_id, self.id),
+            _kwargs=combine_kwargs(**kwargs),
         )
         module_json = response.json()
         module_json.update({"course_id": self.course_id})
 
         return Module(self._requester, module_json)
 
-    def relock(self):
+    def edit(self, **kwargs):
         """
-        Reset module progressions to their default locked state and recalculates
-        them based on the current requirements.
-
-        Adding progression requirements to an active course will not lock students
-        out of modules they have already unlocked unless this action is called.
+        Update this module.
 
-        :calls: `PUT /api/v1/courses/:course_id/modules/:id/relock \
-        <https://canvas.instructure.com/doc/api/modules.html#method.context_modules_api.relock>`_
+        :calls: `PUT /api/v1/courses/:course_id/modules/:id \
+        <https://canvas.instructure.com/doc/api/modules.html#method.context_modules_api.update>`_
 
         :rtype: :class:`canvasapi.module.Module`
         """
         response = self._requester.request(
-            "PUT", "courses/{}/modules/{}/relock".format(self.course_id, self.id)
+            "PUT",
+            "courses/{}/modules/{}".format(self.course_id, self.id),
+            _kwargs=combine_kwargs(**kwargs),
         )
         module_json = response.json()
         module_json.update({"course_id": self.course_id})
 
         return Module(self._requester, module_json)
 
-    def get_module_items(self, **kwargs):
-        """
-        List all of the items in this module.
-
-        :calls: `GET /api/v1/courses/:course_id/modules/:module_id/items \
-        <https://canvas.instructure.com/doc/api/modules.html#method.context_module_items_api.index>`_
-
-        :rtype: :class:`canvasapi.paginated_list.PaginatedList` of
-            :class:`canvasapi.module.ModuleItem`
-        """
-        return PaginatedList(
-            ModuleItem,
-            self._requester,
-            "GET",
-            "courses/{}/modules/{}/items".format(self.course_id, self.id),
-            {"course_id": self.course_id},
-            _kwargs=combine_kwargs(**kwargs),
-        )
-
     def get_module_item(self, module_item, **kwargs):
         """
         Retrieve a module item by ID.
@@ -110,60 +108,65 @@ def get_module_item(self, module_item, **kwargs):
 
         return ModuleItem(self._requester, module_item_json)
 
-    def create_module_item(self, module_item, **kwargs):
+    def get_module_items(self, **kwargs):
         """
-        Create a module item.
+        List all of the items in this module.
 
-        :calls: `POST /api/v1/courses/:course_id/modules/:module_id/items \
-        <https://canvas.instructure.com/doc/api/modules.html#method.context_module_items_api.create>`_
+        :calls: `GET /api/v1/courses/:course_id/modules/:module_id/items \
+        <https://canvas.instructure.com/doc/api/modules.html#method.context_module_items_api.index>`_
 
-        :param module_item: The attributes to create the module item with.
-        :type module_item: dict
-        :returns: The created module item.
-        :rtype: :class:`canvasapi.module.ModuleItem`
+        :rtype: :class:`canvasapi.paginated_list.PaginatedList` of
+            :class:`canvasapi.module.ModuleItem`
         """
+        return PaginatedList(
+            ModuleItem,
+            self._requester,
+            "GET",
+            "courses/{}/modules/{}/items".format(self.course_id, self.id),
+            {"course_id": self.course_id},
+            _kwargs=combine_kwargs(**kwargs),
+        )
 
-        unrequired_types = ["ExternalUrl", "Page", "SubHeader"]
+    def relock(self, **kwargs):
+        """
+        Reset module progressions to their default locked state and recalculates
+        them based on the current requirements.
 
-        if isinstance(module_item, dict) and "type" in module_item:
-            # content_id is not required for unrequired_types
-            if module_item["type"] in unrequired_types or "content_id" in module_item:
-                kwargs["module_item"] = module_item
-            else:
-                raise RequiredFieldMissing(
-                    "Dictionary with key 'content_id' is required."
-                )
-        else:
-            raise RequiredFieldMissing("Dictionary with key 'type' is required.")
+        Adding progression requirements to an active course will not lock students
+        out of modules they have already unlocked unless this action is called.
 
+        :calls: `PUT /api/v1/courses/:course_id/modules/:id/relock \
+        <https://canvas.instructure.com/doc/api/modules.html#method.context_modules_api.relock>`_
+
+        :rtype: :class:`canvasapi.module.Module`
+        """
         response = self._requester.request(
-            "POST",
-            "courses/{}/modules/{}/items".format(self.course_id, self.id),
+            "PUT",
+            "courses/{}/modules/{}/relock".format(self.course_id, self.id),
             _kwargs=combine_kwargs(**kwargs),
         )
-        module_item_json = response.json()
-        module_item_json.update({"course_id": self.course_id})
+        module_json = response.json()
+        module_json.update({"course_id": self.course_id})
 
-        return ModuleItem(self._requester, module_item_json)
+        return Module(self._requester, module_json)
 
 
 class ModuleItem(CanvasObject):
     def __str__(self):
         return "{} ({})".format(self.title, self.id)
 
-    def edit(self, **kwargs):
+    def complete(self, **kwargs):
         """
-        Update this module item.
+        Mark this module item as done.
 
-        :calls: `PUT /api/v1/courses/:course_id/modules/:module_id/items/:id \
-        <https://canvas.instructure.com/doc/api/modules.html#method.context_module_items_api.update>`_
+        :calls: `PUT /api/v1/courses/:course_id/modules/:module_id/items/:id/done \
+        <https://canvas.instructure.com/doc/api/modules.html#method.context_module_items_api.mark_as_done>`_
 
-        :returns: The updated module item.
         :rtype: :class:`canvasapi.module.ModuleItem`
         """
         response = self._requester.request(
             "PUT",
-            "courses/{}/modules/{}/items/{}".format(
+            "courses/{}/modules/{}/items/{}/done".format(
                 self.course_id, self.module_id, self.id
             ),
             _kwargs=combine_kwargs(**kwargs),
@@ -173,7 +176,7 @@ def edit(self, **kwargs):
 
         return ModuleItem(self._requester, module_item_json)
 
-    def delete(self):
+    def delete(self, **kwargs):
         """
         Delete this module item.
 
@@ -187,33 +190,36 @@ def delete(self):
             "courses/{}/modules/{}/items/{}".format(
                 self.course_id, self.module_id, self.id
             ),
+            _kwargs=combine_kwargs(**kwargs),
         )
         module_item_json = response.json()
         module_item_json.update({"course_id": self.course_id})
 
         return ModuleItem(self._requester, module_item_json)
 
-    def complete(self):
+    def edit(self, **kwargs):
         """
-        Mark this module item as done.
+        Update this module item.
 
-        :calls: `PUT /api/v1/courses/:course_id/modules/:module_id/items/:id/done \
-        <https://canvas.instructure.com/doc/api/modules.html#method.context_module_items_api.mark_as_done>`_
+        :calls: `PUT /api/v1/courses/:course_id/modules/:module_id/items/:id \
+        <https://canvas.instructure.com/doc/api/modules.html#method.context_module_items_api.update>`_
 
+        :returns: The updated module item.
         :rtype: :class:`canvasapi.module.ModuleItem`
         """
         response = self._requester.request(
             "PUT",
-            "courses/{}/modules/{}/items/{}/done".format(
+            "courses/{}/modules/{}/items/{}".format(
                 self.course_id, self.module_id, self.id
             ),
+            _kwargs=combine_kwargs(**kwargs),
         )
         module_item_json = response.json()
         module_item_json.update({"course_id": self.course_id})
 
         return ModuleItem(self._requester, module_item_json)
 
-    def uncomplete(self):
+    def uncomplete(self, **kwargs):
         """
         Mark this module item as not done.
 
@@ -227,6 +233,7 @@ def uncomplete(self):
             "courses/{}/modules/{}/items/{}/done".format(
                 self.course_id, self.module_id, self.id
             ),
+            _kwargs=combine_kwargs(**kwargs),
         )
         module_item_json = response.json()
         module_item_json.update({"course_id": self.course_id})
diff --git a/canvasapi/outcome.py b/canvasapi/outcome.py
index 9adf2910..4baa9553 100644
--- a/canvasapi/outcome.py
+++ b/canvasapi/outcome.py
@@ -39,7 +39,7 @@ def context_ref(self):
         elif self.context_type == "Account":
             return "accounts/{}".format(self.context_id)
 
-    def get_outcome(self):
+    def get_outcome(self, **kwargs):
         """
         Return the linked outcome
 
@@ -50,11 +50,13 @@ def get_outcome(self):
         :rtype: :class:`canvasapi.outcome.Outcome`
         """
         oid = self.outcome["id"]
-        response = self._requester.request("GET", "outcomes/{}".format(oid))
+        response = self._requester.request(
+            "GET", "outcomes/{}".format(oid), _kwargs=combine_kwargs(**kwargs)
+        )
 
         return Outcome(self._requester, response.json())
 
-    def get_outcome_group(self):
+    def get_outcome_group(self, **kwargs):
         """
         Return the linked outcome group
 
@@ -70,7 +72,9 @@ def get_outcome_group(self):
         """
         ogid = self.outcome_group["id"]
         response = self._requester.request(
-            "GET", "{}/outcome_groups/{}".format(self.context_ref(), ogid)
+            "GET",
+            "{}/outcome_groups/{}".format(self.context_ref(), ogid),
+            _kwargs=combine_kwargs(**kwargs),
         )
 
         return OutcomeGroup(self._requester, response.json())
@@ -88,32 +92,33 @@ def context_ref(self):
         elif self.context_type is None:
             return "global"
 
-    def update(self, **kwargs):
+    def create_subgroup(self, title, **kwargs):
         """
-        Update an outcome group.
+        Create a subgroup of the current group
 
-        :calls: `PUT /api/v1/global/outcome_groups/:id \
-            <https://canvas.instructure.com/doc/api/outcome_groups.html#method.outcome_groups_api.update>`_
-            or `PUT /api/v1/accounts/:account_id/outcome_groups/:id \
-            <https://canvas.instructure.com/doc/api/outcome_groups.html#method.outcome_groups_api.update>`_
-            or `PUT /api/v1/courses/:course_id/outcome_groups/:id \
-            <https://canvas.instructure.com/doc/api/outcome_groups.html#method.outcome_groups_api.update>`_
+        :calls: `POST /api/v1/global/outcome_groups/:id/subgroups \
+            <https://canvas.instructure.com/doc/api/outcome_groups.html#method.outcome_groups_api.create>`_
+            or `POST /api/v1/accounts/:account_id/outcome_groups/:id/subgroups \
+            <https://canvas.instructure.com/doc/api/outcome_groups.html#method.outcome_groups_api.create>`_
+            or `POST /api/v1/courses/:course_id/outcome_groups/:id/subgroups \
+            <https://canvas.instructure.com/doc/api/outcome_groups.html#method.outcome_groups_api.create>`_
 
-        :returns: True if updated, False otherwise.
-        :rtype: bool
+        :param title: The title of the subgroup.
+        :type title: str
+
+        :returns: Itself as an OutcomeGroup object.
+        :rtype: :class:`canvasapi.outcome.OutcomeGroup`
         """
         response = self._requester.request(
-            "PUT",
-            "{}/outcome_groups/{}".format(self.context_ref(), self.id),
+            "POST",
+            "{}/outcome_groups/{}/subgroups".format(self.context_ref(), self.id),
+            title=title,
             _kwargs=combine_kwargs(**kwargs),
         )
 
-        if "id" in response.json():
-            super(OutcomeGroup, self).set_attributes(response.json())
-
-        return "id" in response.json()
+        return OutcomeGroup(self._requester, response.json())
 
-    def delete(self):
+    def delete(self, **kwargs):
         """
         Delete an outcome group.
 
@@ -128,7 +133,9 @@ def delete(self):
         :rtype: bool
         """
         response = self._requester.request(
-            "DELETE", "{}/outcome_groups/{}".format(self.context_ref(), self.id)
+            "DELETE",
+            "{}/outcome_groups/{}".format(self.context_ref(), self.id),
+            _kwargs=combine_kwargs(**kwargs),
         )
 
         if "id" in response.json():
@@ -159,7 +166,61 @@ def get_linked_outcomes(self, **kwargs):
             _kwargs=combine_kwargs(**kwargs),
         )
 
-    def link_existing(self, outcome):
+    def get_subgroups(self, **kwargs):
+        """
+        List subgroups.
+
+        :calls: `GET /api/v1/global/outcome_groups/:id/subgroups \
+            <https://canvas.instructure.com/doc/api/outcome_groups.html#method.outcome_groups_api.subgroups>`_
+            or `GET /api/v1/accounts/:account_id/outcome_groups/:id/subgroups \
+            <https://canvas.instructure.com/doc/api/outcome_groups.html#method.outcome_groups_api.subgroups>`_
+            or `GET /api/v1/courses/:course_id/outcome_groups/:id/subgroups \
+            <https://canvas.instructure.com/doc/api/outcome_groups.html#method.outcome_groups_api.subgroups>`_
+
+        :returns: Paginated List of OutcomeGroups linked to the current group.
+        :rtype: :class:`canvasapi.paginated_list.PaginatedList` of
+            :class:`canvasapi.outcome.OutcomeGroup`
+        """
+        return PaginatedList(
+            OutcomeGroup,
+            self._requester,
+            "GET",
+            "{}/outcome_groups/{}/subgroups".format(self.context_ref(), self.id),
+            {"context_type": self.context_type, "context_id": self.context_id},
+            _kwargs=combine_kwargs(**kwargs),
+        )
+
+    def import_outcome_group(self, outcome_group, **kwargs):
+        """
+        Import an outcome group as a subgroup into the current outcome group
+
+        :calls: `POST /api/v1/global/outcome_groups/:id/import \
+            <https://canvas.instructure.com/doc/api/outcome_groups.html#method.outcome_groups_api.import>`_
+            or `POST /api/v1/accounts/:account_id/outcome_groups/:id/import \
+            <https://canvas.instructure.com/doc/api/outcome_groups.html#method.outcome_groups_api.import>`_
+            or `POST /api/v1/courses/:course_id/outcome_groups/:id/import \
+            <https://canvas.instructure.com/doc/api/outcome_groups.html#method.outcome_groups_api.import>`_
+
+        :param outcome: The object or ID of the outcome group to import.
+        :type outcome: :class:`canvasapi.outcome.OutcomeGroup` or int
+
+        :returns: Itself as an OutcomeGroup object.
+        :rtype: :class:`canvasapi.outcome.OutcomeGroup`
+        """
+        source_outcome_group_id = obj_or_id(
+            outcome_group, "outcome_group", (OutcomeGroup,)
+        )
+
+        response = self._requester.request(
+            "POST",
+            "{}/outcome_groups/{}/import".format(self.context_ref(), self.id),
+            source_outcome_group_id=source_outcome_group_id,
+            _kwargs=combine_kwargs(**kwargs),
+        )
+
+        return OutcomeGroup(self._requester, response.json())
+
+    def link_existing(self, outcome, **kwargs):
         """
         Link to an existing Outcome.
 
@@ -181,8 +242,11 @@ def link_existing(self, outcome):
         response = self._requester.request(
             "PUT",
             "{}/outcome_groups/{}/outcomes/{}".format(
-                self.context_ref(), self.id, outcome_id
+                self.context_ref(),
+                self.id,
+                outcome_id,
             ),
+            _kwargs=combine_kwargs(**kwargs),
         )
 
         return OutcomeLink(self._requester, response.json())
@@ -213,7 +277,7 @@ def link_new(self, title, **kwargs):
 
         return OutcomeLink(self._requester, response.json())
 
-    def unlink_outcome(self, outcome):
+    def unlink_outcome(self, outcome, **kwargs):
         """
         Remove an Outcome from and OutcomeLink
 
@@ -235,8 +299,11 @@ def unlink_outcome(self, outcome):
         response = self._requester.request(
             "DELETE",
             "{}/outcome_groups/{}/outcomes/{}".format(
-                self.context_ref(), self.id, outcome_id
+                self.context_ref(),
+                self.id,
+                outcome_id,
             ),
+            _kwargs=combine_kwargs(**kwargs),
         )
 
         if "context_id" in response.json():
@@ -244,84 +311,30 @@ def unlink_outcome(self, outcome):
 
         return "context_id" in response.json()
 
-    def get_subgroups(self, **kwargs):
-        """
-        List subgroups.
-
-        :calls: `GET /api/v1/global/outcome_groups/:id/subgroups \
-            <https://canvas.instructure.com/doc/api/outcome_groups.html#method.outcome_groups_api.subgroups>`_
-            or `GET /api/v1/accounts/:account_id/outcome_groups/:id/subgroups \
-            <https://canvas.instructure.com/doc/api/outcome_groups.html#method.outcome_groups_api.subgroups>`_
-            or `GET /api/v1/courses/:course_id/outcome_groups/:id/subgroups \
-            <https://canvas.instructure.com/doc/api/outcome_groups.html#method.outcome_groups_api.subgroups>`_
-
-        :returns: Paginated List of OutcomeGroups linked to the current group.
-        :rtype: :class:`canvasapi.paginated_list.PaginatedList` of
-            :class:`canvasapi.outcome.OutcomeGroup`
-        """
-        return PaginatedList(
-            OutcomeGroup,
-            self._requester,
-            "GET",
-            "{}/outcome_groups/{}/subgroups".format(self.context_ref(), self.id),
-            {"context_type": self.context_type, "context_id": self.context_id},
-            _kwargs=combine_kwargs(**kwargs),
-        )
-
-    def create_subgroup(self, title, **kwargs):
+    def update(self, **kwargs):
         """
-        Create a subgroup of the current group
-
-        :calls: `POST /api/v1/global/outcome_groups/:id/subgroups \
-            <https://canvas.instructure.com/doc/api/outcome_groups.html#method.outcome_groups_api.create>`_
-            or `POST /api/v1/accounts/:account_id/outcome_groups/:id/subgroups \
-            <https://canvas.instructure.com/doc/api/outcome_groups.html#method.outcome_groups_api.create>`_
-            or `POST /api/v1/courses/:course_id/outcome_groups/:id/subgroups \
-            <https://canvas.instructure.com/doc/api/outcome_groups.html#method.outcome_groups_api.create>`_
+        Update an outcome group.
 
-        :param title: The title of the subgroup.
-        :type title: str
+        :calls: `PUT /api/v1/global/outcome_groups/:id \
+            <https://canvas.instructure.com/doc/api/outcome_groups.html#method.outcome_groups_api.update>`_
+            or `PUT /api/v1/accounts/:account_id/outcome_groups/:id \
+            <https://canvas.instructure.com/doc/api/outcome_groups.html#method.outcome_groups_api.update>`_
+            or `PUT /api/v1/courses/:course_id/outcome_groups/:id \
+            <https://canvas.instructure.com/doc/api/outcome_groups.html#method.outcome_groups_api.update>`_
 
-        :returns: Itself as an OutcomeGroup object.
-        :rtype: :class:`canvasapi.outcome.OutcomeGroup`
+        :returns: True if updated, False otherwise.
+        :rtype: bool
         """
         response = self._requester.request(
-            "POST",
-            "{}/outcome_groups/{}/subgroups".format(self.context_ref(), self.id),
-            title=title,
+            "PUT",
+            "{}/outcome_groups/{}".format(self.context_ref(), self.id),
             _kwargs=combine_kwargs(**kwargs),
         )
 
-        return OutcomeGroup(self._requester, response.json())
-
-    def import_outcome_group(self, outcome_group):
-        """
-        Import an outcome group as a subgroup into the current outcome group
-
-        :calls: `POST /api/v1/global/outcome_groups/:id/import \
-            <https://canvas.instructure.com/doc/api/outcome_groups.html#method.outcome_groups_api.import>`_
-            or `POST /api/v1/accounts/:account_id/outcome_groups/:id/import \
-            <https://canvas.instructure.com/doc/api/outcome_groups.html#method.outcome_groups_api.import>`_
-            or `POST /api/v1/courses/:course_id/outcome_groups/:id/import \
-            <https://canvas.instructure.com/doc/api/outcome_groups.html#method.outcome_groups_api.import>`_
-
-        :param outcome: The object or ID of the outcome group to import.
-        :type outcome: :class:`canvasapi.outcome.OutcomeGroup` or int
-
-        :returns: Itself as an OutcomeGroup object.
-        :rtype: :class:`canvasapi.outcome.OutcomeGroup`
-        """
-        source_outcome_group_id = obj_or_id(
-            outcome_group, "outcome_group", (OutcomeGroup,)
-        )
-
-        response = self._requester.request(
-            "POST",
-            "{}/outcome_groups/{}/import".format(self.context_ref(), self.id),
-            source_outcome_group_id=source_outcome_group_id,
-        )
+        if "id" in response.json():
+            super(OutcomeGroup, self).set_attributes(response.json())
 
-        return OutcomeGroup(self._requester, response.json())
+        return "id" in response.json()
 
 
 class OutcomeResult(CanvasObject):
diff --git a/canvasapi/planner.py b/canvasapi/planner.py
index 32946afe..a4b688e7 100644
--- a/canvasapi/planner.py
+++ b/canvasapi/planner.py
@@ -6,36 +6,36 @@ class PlannerNote(CanvasObject):
     def __str__(self):
         return "{} {} ({})".format(self.title, self.todo_date, self.id)
 
-    def update(self, **kwargs):
+    def delete(self, **kwargs):
         """
-        Update a planner note for the current user
+        Delete a planner note for the current user
 
-        :calls: `PUT /api/v1/planner_notes/:id \
-        <https://canvas.instructure.com/doc/api/planner.html#method.planner_notes.update>`_
+        :calls: `DELETE /api/v1/planner_notes/:id \
+        <https://canvas.instructure.com/doc/api/planner.html#method.planner_notes.destroy>`_
 
         :rtype: :class:`canvasapi.planner.PlannerNote`
         """
-
         response = self._requester.request(
-            "PUT", "planner_notes/{}".format(self.id), _kwargs=combine_kwargs(**kwargs)
+            "DELETE",
+            "planner_notes/{}".format(self.id),
+            _kwargs=combine_kwargs(**kwargs),
         )
+
         return PlannerNote(self._requester, response.json())
 
-    def delete(self, **kwargs):
+    def update(self, **kwargs):
         """
-        Delete a planner note for the current user
+        Update a planner note for the current user
 
-        :calls: `DELETE /api/v1/planner_notes/:id \
-        <https://canvas.instructure.com/doc/api/planner.html#method.planner_notes.destroy>`_
+        :calls: `PUT /api/v1/planner_notes/:id \
+        <https://canvas.instructure.com/doc/api/planner.html#method.planner_notes.update>`_
 
         :rtype: :class:`canvasapi.planner.PlannerNote`
         """
+
         response = self._requester.request(
-            "DELETE",
-            "planner_notes/{}".format(self.id),
-            _kwargs=combine_kwargs(**kwargs),
+            "PUT", "planner_notes/{}".format(self.id), _kwargs=combine_kwargs(**kwargs)
         )
-
         return PlannerNote(self._requester, response.json())
 
 
@@ -43,36 +43,36 @@ class PlannerOverride(CanvasObject):
     def __str__(self):
         return "{} {} ({})".format(self.plannable_id, self.marked_complete, self.id)
 
-    def update(self, **kwargs):
+    def delete(self, **kwargs):
         """
-        Update a planner override's visibilty for the current user
+        Delete a planner override for the current user
 
-        :calls: `PUT /api/v1/planner/overrides/:id \
-        <https://canvas.instructure.com/doc/api/planner.html#method.planner_overrides.update>`_
+        :calls: `DELETE /api/v1/planner/overrides/:id \
+        <https://canvas.instructure.com/doc/api/planner.html#method.planner_overrides.destroy>`_
 
         :rtype: :class:`canvasapi.planner.PlannerOverride`
         """
-
         response = self._requester.request(
-            "PUT",
+            "DELETE",
             "planner/overrides/{}".format(self.id),
             _kwargs=combine_kwargs(**kwargs),
         )
+
         return PlannerOverride(self._requester, response.json())
 
-    def delete(self, **kwargs):
+    def update(self, **kwargs):
         """
-        Delete a planner override for the current user
+        Update a planner override's visibilty for the current user
 
-        :calls: `DELETE /api/v1/planner/overrides/:id \
-        <https://canvas.instructure.com/doc/api/planner.html#method.planner_overrides.destroy>`_
+        :calls: `PUT /api/v1/planner/overrides/:id \
+        <https://canvas.instructure.com/doc/api/planner.html#method.planner_overrides.update>`_
 
         :rtype: :class:`canvasapi.planner.PlannerOverride`
         """
+
         response = self._requester.request(
-            "DELETE",
+            "PUT",
             "planner/overrides/{}".format(self.id),
             _kwargs=combine_kwargs(**kwargs),
         )
-
         return PlannerOverride(self._requester, response.json())
diff --git a/canvasapi/poll.py b/canvasapi/poll.py
index da365741..622ef3fe 100644
--- a/canvasapi/poll.py
+++ b/canvasapi/poll.py
@@ -10,30 +10,62 @@ class Poll(CanvasObject):
     def __str__(self):
         return "{} ({})".format(self.question, self.id)
 
-    def update(self, poll, **kwargs):
+    def create_choice(self, poll_choice, **kwargs):
         """
-        Update an existing poll belonging to the current user.
+        Create a new choice for the current poll.
 
-        :calls: `PUT /api/v1/polls/:id \
-        <https://canvas.instructure.com/doc/api/polls.html#method.polling/polls.update>`_
+        :calls: `POST /api/v1/polls/:poll_id/poll_choices \
+        <https://canvas.instructure.com/doc/api/poll_choices.html#method.polling/poll_choices.create>`_
 
-        :param poll: List of arguments. 'Question' is required and 'Description' is optional
-        :type poll: list
-        :rtype: :class:`canvasapi.poll.Poll`
+        :param poll_choice: 'text' is required, 'is_correct' and 'position' are optional.
+        :type poll_choice: list
+        :rtype: :class:`canvasapi.poll_choice.PollChoice`
         """
         if (
-            isinstance(poll, list)
-            and isinstance(poll[0], dict)
-            and "question" in poll[0]
+            isinstance(poll_choice, list)
+            and isinstance(poll_choice[0], dict)
+            and "text" in poll_choice[0]
         ):
-            kwargs["poll"] = poll
+            kwargs["poll_choice"] = poll_choice
         else:
-            raise RequiredFieldMissing("Dictionary with key 'question' is required.")
+            raise RequiredFieldMissing("Dictionary with key 'text' is required.")
 
         response = self._requester.request(
-            "PUT", "polls/{}".format(self.id), _kwargs=combine_kwargs(**kwargs)
+            "POST",
+            "polls/{}/poll_choices".format(self.id),
+            _kwargs=combine_kwargs(**kwargs),
         )
-        return Poll(self._requester, response.json()["polls"][0])
+        return PollChoice(self._requester, response.json()["poll_choices"][0])
+
+    def create_session(self, poll_session, **kwargs):
+        """
+        Create a new poll session for this poll
+
+        :calls: `POST /api/v1/polls/:poll_id/poll_sessions \
+        <https://canvas.instructure.com/doc/api/poll_sessions.html#method.polling/poll_sessions.create>`_
+
+        :param poll_session: List of arguments. course_id (required): id of the course for the
+            session, course_section_id (optional): id of the course section for this session,
+            has_public_results (optional): whether the results are viewable by students.
+        :type poll_session: list
+
+        :rtype: :class:`canvasapi.poll_session.PollSession`
+        """
+        if (
+            isinstance(poll_session, list)
+            and isinstance(poll_session[0], dict)
+            and "course_id" in poll_session[0]
+        ):
+            kwargs["poll_session"] = poll_session
+        else:
+            raise RequiredFieldMissing("Dictionary with key 'course_id' is required.")
+
+        response = self._requester.request(
+            "POST",
+            "polls/{}/poll_sessions".format(self.id),
+            _kwargs=combine_kwargs(**kwargs),
+        )
+        return PollSession(self._requester, response.json()["poll_sessions"][0])
 
     def delete(self, **kwargs):
         """
@@ -51,25 +83,6 @@ def delete(self, **kwargs):
         )
         return response.status_code == 204
 
-    def get_choices(self, **kwargs):
-        """
-        Returns a paginated list of PollChoices of a poll, based on poll id.
-
-        :calls: `GET /api/v1/polls/:poll_id/poll_choices \
-        <https://canvas.instructure.com/doc/api/poll_choices.html#method.polling/poll_choices.index>`_
-
-        :rtype: :class:`canvasapi.paginated_list.PaginatedList` of
-            :class:`canvasapi.poll_choice.PollChoice`
-        """
-        return PaginatedList(
-            PollChoice,
-            self._requester,
-            "GET",
-            "polls/{}/poll_choices".format(self.id),
-            _root="poll_choices",
-            _kwargs=combine_kwargs(**kwargs),
-        )
-
     def get_choice(self, poll_choice, **kwargs):
         """
         Returns the poll choice with the given id.
@@ -88,49 +101,22 @@ def get_choice(self, poll_choice, **kwargs):
         )
         return PollChoice(self._requester, response.json()["poll_choices"][0])
 
-    def create_choice(self, poll_choice, **kwargs):
-        """
-        Create a new choice for the current poll.
-
-        :calls: `POST /api/v1/polls/:poll_id/poll_choices \
-        <https://canvas.instructure.com/doc/api/poll_choices.html#method.polling/poll_choices.create>`_
-
-        :param poll_choice: 'text' is required, 'is_correct' and 'position' are optional.
-        :type poll_choice: list
-        :rtype: :class:`canvasapi.poll_choice.PollChoice`
-        """
-        if (
-            isinstance(poll_choice, list)
-            and isinstance(poll_choice[0], dict)
-            and "text" in poll_choice[0]
-        ):
-            kwargs["poll_choice"] = poll_choice
-        else:
-            raise RequiredFieldMissing("Dictionary with key 'text' is required.")
-
-        response = self._requester.request(
-            "POST",
-            "polls/{}/poll_choices".format(self.id),
-            _kwargs=combine_kwargs(**kwargs),
-        )
-        return PollChoice(self._requester, response.json()["poll_choices"][0])
-
-    def get_sessions(self, **kwargs):
+    def get_choices(self, **kwargs):
         """
-        Returns the paginated list of PollSessions in a poll.
+        Returns a paginated list of PollChoices of a poll, based on poll id.
 
-        :calls: `GET /api/v1/polls/:poll_id/poll_sessions \
-        <https://canvas.instructure.com/doc/api/poll_sessions.html#method.polling/poll_sessions.index>`_
+        :calls: `GET /api/v1/polls/:poll_id/poll_choices \
+        <https://canvas.instructure.com/doc/api/poll_choices.html#method.polling/poll_choices.index>`_
 
-        :rtype: :class:`canvasapi.paginated_lsit.Paginated List` of
-            :class:`canvasapi.poll_session.PollSession`
+        :rtype: :class:`canvasapi.paginated_list.PaginatedList` of
+            :class:`canvasapi.poll_choice.PollChoice`
         """
         return PaginatedList(
-            PollSession,
+            PollChoice,
             self._requester,
             "GET",
-            "polls/{}/poll_sessions".format(self.id),
-            _root="poll_sessions",
+            "polls/{}/poll_choices".format(self.id),
+            _root="poll_choices",
             _kwargs=combine_kwargs(**kwargs),
         )
 
@@ -155,32 +141,46 @@ def get_session(self, poll_session, **kwargs):
         )
         return PollSession(self._requester, response.json()["poll_sessions"][0])
 
-    def create_session(self, poll_session, **kwargs):
+    def get_sessions(self, **kwargs):
         """
-        Create a new poll session for this poll
+        Returns the paginated list of PollSessions in a poll.
 
-        :calls: `POST /api/v1/polls/:poll_id/poll_sessions \
-        <https://canvas.instructure.com/doc/api/poll_sessions.html#method.polling/poll_sessions.create>`_
+        :calls: `GET /api/v1/polls/:poll_id/poll_sessions \
+        <https://canvas.instructure.com/doc/api/poll_sessions.html#method.polling/poll_sessions.index>`_
 
-        :param poll_session: List of arguments. course_id (required): id of the course for the
-            session, course_section_id (optional): id of the course section for this session,
-            has_public_results (optional): whether the results are viewable by students.
-        :type poll_session: list
+        :rtype: :class:`canvasapi.paginated_lsit.Paginated List` of
+            :class:`canvasapi.poll_session.PollSession`
+        """
+        return PaginatedList(
+            PollSession,
+            self._requester,
+            "GET",
+            "polls/{}/poll_sessions".format(self.id),
+            _root="poll_sessions",
+            _kwargs=combine_kwargs(**kwargs),
+        )
 
-        :rtype: :class:`canvasapi.poll_session.PollSession`
+    def update(self, poll, **kwargs):
+        """
+        Update an existing poll belonging to the current user.
+
+        :calls: `PUT /api/v1/polls/:id \
+        <https://canvas.instructure.com/doc/api/polls.html#method.polling/polls.update>`_
+
+        :param poll: List of arguments. 'Question' is required and 'Description' is optional
+        :type poll: list
+        :rtype: :class:`canvasapi.poll.Poll`
         """
         if (
-            isinstance(poll_session, list)
-            and isinstance(poll_session[0], dict)
-            and "course_id" in poll_session[0]
+            isinstance(poll, list)
+            and isinstance(poll[0], dict)
+            and "question" in poll[0]
         ):
-            kwargs["poll_session"] = poll_session
+            kwargs["poll"] = poll
         else:
-            raise RequiredFieldMissing("Dictionary with key 'course_id' is required.")
+            raise RequiredFieldMissing("Dictionary with key 'question' is required.")
 
         response = self._requester.request(
-            "POST",
-            "polls/{}/poll_sessions".format(self.id),
-            _kwargs=combine_kwargs(**kwargs),
+            "PUT", "polls/{}".format(self.id), _kwargs=combine_kwargs(**kwargs)
         )
-        return PollSession(self._requester, response.json()["poll_sessions"][0])
+        return Poll(self._requester, response.json()["polls"][0])
diff --git a/canvasapi/poll_choice.py b/canvasapi/poll_choice.py
index ccf64df0..90985d13 100644
--- a/canvasapi/poll_choice.py
+++ b/canvasapi/poll_choice.py
@@ -7,6 +7,24 @@ class PollChoice(CanvasObject):
     def __str__(self):
         return "{} ({})".format(self.text, self.id)
 
+    def delete(self, **kwargs):
+        """
+        Delete a single poll, based on the poll id.
+
+        :calls: `DELETE /api/v1/polls/:poll_id/poll_choices/:id \
+        <https://canvas.instructure.com/doc/api/poll_choices.html#method.polling/poll_choices.destroy>`_
+
+        :returns: True if the deletion was successful, false otherwise.
+
+        :rtype: bool
+        """
+        response = self._requester.request(
+            "DELETE",
+            "polls/{}/poll_choices/{}".format(self.poll_id, self.id),
+            _kwargs=combine_kwargs(**kwargs),
+        )
+        return response.status_code == 204
+
     def update(self, poll_choice, **kwargs):
         """
         Update an existing choice for this poll.
@@ -34,21 +52,3 @@ def update(self, poll_choice, **kwargs):
             _kwargs=combine_kwargs(**kwargs),
         )
         return PollChoice(self._requester, response.json()["poll_choices"][0])
-
-    def delete(self, **kwargs):
-        """
-        Delete a single poll, based on the poll id.
-
-        :calls: `DELETE /api/v1/polls/:poll_id/poll_choices/:id \
-        <https://canvas.instructure.com/doc/api/poll_choices.html#method.polling/poll_choices.destroy>`_
-
-        :returns: True if the deletion was successful, false otherwise.
-
-        :rtype: bool
-        """
-        response = self._requester.request(
-            "DELETE",
-            "polls/{}/poll_choices/{}".format(self.poll_id, self.id),
-            _kwargs=combine_kwargs(**kwargs),
-        )
-        return response.status_code == 204
diff --git a/canvasapi/poll_session.py b/canvasapi/poll_session.py
index e03b435b..718497fd 100644
--- a/canvasapi/poll_session.py
+++ b/canvasapi/poll_session.py
@@ -8,35 +8,52 @@ class PollSession(CanvasObject):
     def __str__(self):
         return "{} ({})".format(self.poll_id, self.id)
 
-    def update(self, poll_session, **kwargs):
+    def close(self, **kwargs):
         """
-        Update an existing poll session for a poll based on poll id.
+        Close a poll session to answers based on the poll id.
 
-        :calls: `PUT /api/v1/polls/:poll_id/poll_sessions/:id \
-        <https://canvas.instructure.com/doc/api/poll_sessions.html#method.polling/poll_sessions.update>`_
+        :calls: `GET /api/v1/polls/:poll_id/poll_sessions/:id/close \
+        <https://canvas.instructure.com/doc/api/poll_sessions.html#method.polling/poll_sessions.close>`_
 
-        :param poll_session: List of arguments. course_id (required): id of the course for the
-            session, course_section_id (optional): id of the course section for this session,
-            has_public_results (optional): whether the results are viewable by students.
-        :type poll_session: list
+        :returns: :class:`canvasapi.poll_session.PollSession`
+        """
+        response = self._requester.request(
+            "GET",
+            "polls/{}/poll_sessions/{}/close".format(self.poll_id, self.id),
+            _kwargs=combine_kwargs(**kwargs),
+        )
+        return PollSession(self._requester, response.json()["poll_sessions"][0])
 
-        :rtype: :class:`canvasapi.poll_session.PollSession`
+    def create_submission(self, poll_submissions, **kwargs):
+        """
+        Create a new poll submission for this poll session.
+
+        :calls: `POST /api/v1/polls/:poll_id/poll_sessions/:poll_session_id/poll_submissions \
+        <https://canvas.instructure.com/doc/api/poll_submissions.html#method.polling/poll_submissions.create>`_
+
+        :param poll_submissions: List of arguments. poll_choice_id (required int): Chosen poll \
+        choice for this submission.
+        :type poll_submissions: list
+
+        :rtype: :class:`canvasapi.poll_submission.PollSubmission`
         """
         if (
-            isinstance(poll_session, list)
-            and isinstance(poll_session[0], dict)
-            and "course_id" in poll_session[0]
+            isinstance(poll_submissions, list)
+            and isinstance(poll_submissions[0], dict)
+            and "poll_choice_id" in poll_submissions[0]
         ):
-            kwargs["poll_session"] = poll_session
+            kwargs["poll_submissions"] = poll_submissions
         else:
-            raise RequiredFieldMissing("Dictionary with key 'course_id' is required.")
+            raise RequiredFieldMissing(
+                "Dictionary with key 'poll_choice_id is required."
+            )
 
         response = self._requester.request(
-            "PUT",
-            "polls/{}/poll_sessions/{}".format(self.poll_id, self.id),
+            "POST",
+            "polls/{}/poll_sessions/{}/poll_submissions".format(self.poll_id, self.id),
             _kwargs=combine_kwargs(**kwargs),
         )
-        return PollSession(self._requester, response.json()["poll_sessions"][0])
+        return PollSubmission(self._requester, response.json()["poll_submissions"][0])
 
     def delete(self, **kwargs):
         """
@@ -56,38 +73,6 @@ def delete(self, **kwargs):
         )
         return response.status_code == 204
 
-    def open(self, **kwargs):
-        """
-        Open a poll session to answers based on the poll id.
-
-        :calls: `GET /api/v1/polls/:poll_id/poll_sessions/:id/open \
-        <https://canvas.instructure.com/doc/api/poll_sessions.html#method.polling/poll_sessions.open>`_
-
-        :returns: :class:`canvasapi.poll_session.PollSession`
-        """
-        response = self._requester.request(
-            "GET",
-            "polls/{}/poll_sessions/{}/open".format(self.poll_id, self.id),
-            _kwargs=combine_kwargs(**kwargs),
-        )
-        return PollSession(self._requester, response.json()["poll_sessions"][0])
-
-    def close(self, **kwargs):
-        """
-        Close a poll session to answers based on the poll id.
-
-        :calls: `GET /api/v1/polls/:poll_id/poll_sessions/:id/close \
-        <https://canvas.instructure.com/doc/api/poll_sessions.html#method.polling/poll_sessions.close>`_
-
-        :returns: :class:`canvasapi.poll_session.PollSession`
-        """
-        response = self._requester.request(
-            "GET",
-            "polls/{}/poll_sessions/{}/close".format(self.poll_id, self.id),
-            _kwargs=combine_kwargs(**kwargs),
-        )
-        return PollSession(self._requester, response.json()["poll_sessions"][0])
-
     def get_submission(self, poll_submission, **kwargs):
         """
         Returns the poll submission with the given id.
@@ -113,33 +98,48 @@ def get_submission(self, poll_submission, **kwargs):
         )
         return PollSubmission(self._requester, response.json()["poll_submissions"][0])
 
-    def create_submission(self, poll_submissions, **kwargs):
+    def open(self, **kwargs):
         """
-        Create a new poll submission for this poll session.
+        Open a poll session to answers based on the poll id.
 
-        :calls: `POST /api/v1/polls/:poll_id/poll_sessions/:poll_session_id/poll_submissions \
-        <https://canvas.instructure.com/doc/api/poll_submissions.html#method.polling/poll_submissions.create>`_
+        :calls: `GET /api/v1/polls/:poll_id/poll_sessions/:id/open \
+        <https://canvas.instructure.com/doc/api/poll_sessions.html#method.polling/poll_sessions.open>`_
 
-        :param poll_submissions: List of arguments. poll_choice_id (required int): Chosen poll \
-        choice for this submission.
-        :type poll_submissions: list
+        :returns: :class:`canvasapi.poll_session.PollSession`
+        """
+        response = self._requester.request(
+            "GET",
+            "polls/{}/poll_sessions/{}/open".format(self.poll_id, self.id),
+            _kwargs=combine_kwargs(**kwargs),
+        )
+        return PollSession(self._requester, response.json()["poll_sessions"][0])
 
-        :rtype: :class:`canvasapi.poll_submission.PollSubmission`
+    def update(self, poll_session, **kwargs):
+        """
+        Update an existing poll session for a poll based on poll id.
+
+        :calls: `PUT /api/v1/polls/:poll_id/poll_sessions/:id \
+        <https://canvas.instructure.com/doc/api/poll_sessions.html#method.polling/poll_sessions.update>`_
+
+        :param poll_session: List of arguments. course_id (required): id of the course for the
+            session, course_section_id (optional): id of the course section for this session,
+            has_public_results (optional): whether the results are viewable by students.
+        :type poll_session: list
+
+        :rtype: :class:`canvasapi.poll_session.PollSession`
         """
         if (
-            isinstance(poll_submissions, list)
-            and isinstance(poll_submissions[0], dict)
-            and "poll_choice_id" in poll_submissions[0]
+            isinstance(poll_session, list)
+            and isinstance(poll_session[0], dict)
+            and "course_id" in poll_session[0]
         ):
-            kwargs["poll_submissions"] = poll_submissions
+            kwargs["poll_session"] = poll_session
         else:
-            raise RequiredFieldMissing(
-                "Dictionary with key 'poll_choice_id is required."
-            )
+            raise RequiredFieldMissing("Dictionary with key 'course_id' is required.")
 
         response = self._requester.request(
-            "POST",
-            "polls/{}/poll_sessions/{}/poll_submissions".format(self.poll_id, self.id),
+            "PUT",
+            "polls/{}/poll_sessions/{}".format(self.poll_id, self.id),
             _kwargs=combine_kwargs(**kwargs),
         )
-        return PollSubmission(self._requester, response.json()["poll_submissions"][0])
+        return PollSession(self._requester, response.json()["poll_sessions"][0])
diff --git a/canvasapi/user.py b/canvasapi/user.py
index 3faafac4..e3b62f99 100644
--- a/canvasapi/user.py
+++ b/canvasapi/user.py
@@ -1,10 +1,15 @@
+from canvasapi.authentication_event import AuthenticationEvent
+from canvasapi.avatar import Avatar
 from canvasapi.calendar_event import CalendarEvent
 from canvasapi.canvas_object import CanvasObject
 from canvasapi.communication_channel import CommunicationChannel
+from canvasapi.content_export import ContentExport
+from canvasapi.content_migration import ContentMigration, Migrator
 from canvasapi.feature import Feature, FeatureFlag
 from canvasapi.folder import Folder
 from canvasapi.grade_change_log import GradeChangeEvent
 from canvasapi.license import License
+from canvasapi.page_view import PageView
 from canvasapi.paginated_list import PaginatedList
 from canvasapi.pairing_code import PairingCode
 from canvasapi.upload import FileOrPathLike, Uploader
@@ -81,8 +86,6 @@ def create_content_migration(self, migration_type, **kwargs):
 
         :rtype: :class:`canvasapi.content_migration.ContentMigration`
         """
-        from canvasapi.content_migration import ContentMigration, Migrator
-
         if isinstance(migration_type, Migrator):
             kwargs["migration_type"] = migration_type.type
         elif isinstance(migration_type, str):
@@ -165,8 +168,6 @@ def export_content(self, export_type, **kwargs):
 
         :rtype: :class:`canvasapi.content_export.ContentExport`
         """
-        from canvasapi.content_export import ContentExport
-
         kwargs["export_type"] = export_type
 
         response = self._requester.request(
@@ -213,8 +214,6 @@ def get_authentication_events(self, **kwargs):
         :rtype: :class:`canvasapi.paginated_list.PaginatedList` of
                 :class:`canvasapi.authentication_event.AuthenticationEvent`
         """
-        from canvasapi.authentication_event import AuthenticationEvent
-
         return PaginatedList(
             AuthenticationEvent,
             self._requester,
@@ -233,8 +232,6 @@ def get_avatars(self, **kwargs):
         :rtype: :class:`canvasapi.paginated_list.PaginatedList` of
             :class:`canvasapi.avatar.Avatar`
         """
-        from canvasapi.avatar import Avatar
-
         return PaginatedList(
             Avatar,
             self._requester,
@@ -349,8 +346,6 @@ def get_content_export(self, content_export, **kwargs):
 
         :rtype: :class:`canvasapi.content_export.ContentExport`
         """
-        from canvasapi.content_export import ContentExport
-
         export_id = obj_or_id(content_export, "content_export", (ContentExport,))
 
         response = self._requester.request(
@@ -371,8 +366,6 @@ def get_content_exports(self, **kwargs):
         :rtype: :class:`canvasapi.paginated_list.PaginatedList` of
             :class:`canvasapi.content_export.ContentExport`
         """
-        from canvasapi.content_export import ContentExport
-
         return PaginatedList(
             ContentExport,
             self._requester,
@@ -821,8 +814,6 @@ def get_page_views(self, **kwargs):
         :rtype: :class:`canvasapi.paginated_list.PaginatedList` of
             :class:`canvasapi.course.PageView`
         """
-        from canvasapi.page_view import PageView
-
         return PaginatedList(
             PageView,
             self._requester,
diff --git a/scripts/find_missing_kwargs.py b/scripts/find_missing_kwargs.py
index 92969a8b..a40b3b76 100644
--- a/scripts/find_missing_kwargs.py
+++ b/scripts/find_missing_kwargs.py
@@ -15,6 +15,8 @@
     "Uploader.request_upload_token",
     "Uploader.start",
     "Uploader.upload",
+    "OutcomeGroup.context_ref",
+    "OutcomeLink.context_ref",
 )
 
 
diff --git a/scripts/find_missing_modules.py b/scripts/find_missing_modules.py
new file mode 100644
index 00000000..318871ea
--- /dev/null
+++ b/scripts/find_missing_modules.py
@@ -0,0 +1,50 @@
+import inspect
+import os
+import sys
+
+sys.path.append(os.path.join(sys.path[0], ".."))
+
+import canvasapi  # noqa
+
+
+exempt_files = ("__init__",)
+
+
+def find_missing_modules():
+    # get all modules visile to inspect from `canvasapi.__init__`
+    module_names = [
+        module_name
+        for module_name, module in inspect.getmembers(canvasapi, inspect.ismodule)
+    ]
+
+    # get all .py files in canvasapi dir (without .py extension)
+    path = "canvasapi"
+    filenames = [fname[:-3] for fname in os.listdir(path) if fname.endswith(".py")]
+
+    missing_modules = list()
+
+    for filename in filenames:
+        # ignore exempt files
+        if filename in exempt_files:
+            continue
+
+        # check for missing files against module names
+        if filename not in module_names:
+            missing_modules.append(filename)
+
+    return missing_modules
+
+
+if __name__ == "__main__":
+    missing_modules = find_missing_modules()
+    num_missing = len(missing_modules)
+    missing_module_str = ", ".join(missing_modules)
+
+    if missing_modules:
+        print(f"Missing {num_missing} modules from inspect. 💥")
+        for module in missing_modules:
+            print(f"  - {module}")
+        print("Ensure the above modules are imported (even indirectly) to __init__")
+    else:
+        print("All modules accounted for! 👍")
+    sys.exit(num_missing > 0)


Test patch:
diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml
index cb09b538..9c2d300f 100644
--- a/.github/workflows/run-tests.yml
+++ b/.github/workflows/run-tests.yml
@@ -33,6 +33,8 @@ jobs:
         run: coverage run -m unittest discover
       - name: Lint markdown files
         uses: bewuethr/mdl-action@v1
+      - name: Check if all modules are visible to inspect
+        run: python scripts/find_missing_modules.py
       - name: Check if methods are alphabetical
         run: python scripts/alphabetic.py
       - name: Check for missing kwargs
diff --git a/scripts/run_tests.sh b/scripts/run_tests.sh
index c8f3809e..00ae4cac 100755
--- a/scripts/run_tests.sh
+++ b/scripts/run_tests.sh
@@ -7,5 +7,6 @@ black --check canvasapi tests
 isort --check canvasapi tests
 flake8 canvasapi tests
 mdl . .github
+python scripts/find_missing_modules.py
 python scripts/alphabetic.py
 python scripts/find_missing_kwargs.py