def get_conversation(self, conversation, **kwargs): """ Return single Conversation :calls: `GET /api/v1/conversations/:id \ <https://canvas.instructure.com/doc/api/conversations.html#method.conversations.show>`_ :param conversation: The object or ID of the conversation. :type conversation: :class:`canvasapi.conversation.Conversation` or int :rtype: :class:`canvasapi.conversation.Conversation` """ from canvasapi.conversation import Conversation conversation_id = obj_or_id(conversation, "conversation", (Conversation, )) response = self.__requester.request( 'GET', 'conversations/{}'.format(conversation_id), _kwargs=combine_kwargs(**kwargs)) return Conversation(self.__requester, response.json())
def update_score_and_comments(self, **kwargs): """ Update the amount of points a student has scored for questions they've answered, provide comments for the student about their answer(s), or simply fudge the total score by a specific amount of points. :calls: `PUT /api/v1/courses/:course_id/quizzes/:quiz_id/submissions/:id \ <https://canvas.instructure.com/doc/api/quiz_submissions.html#method.quizzes/quiz_submissions_api.update>`_ :returns: The updated quiz. :rtype: :class:`canvasapi.quiz.QuizSubmission` """ response = self._requester.request( "PUT", "courses/{}/quizzes/{}/submissions/{}".format( self.course_id, self.quiz_id, self.id), _kwargs=combine_kwargs(**kwargs), ) response_json = response.json()["quiz_submissions"][0] response_json.update({"course_id": self.course_id}) return QuizSubmission(self._requester, response_json)
def get_course_nickname(self, course, **kwargs): """ Return the nickname for the given course. :calls: `GET /api/v1/users/self/course_nicknames/:course_id \ <https://canvas.instructure.com/doc/api/users.html#method.course_nicknames.show>`_ :param course: The object or ID of the course. :type course: :class:`canvasapi.course.Course` or int :rtype: :class:`canvasapi.course.CourseNickname` """ from canvasapi.course import CourseNickname course_id = obj_or_id(course, "course", (Course, )) response = self.__requester.request( "GET", "users/self/course_nicknames/{}".format(course_id), _kwargs=combine_kwargs(**kwargs), ) return CourseNickname(self.__requester, response.json())
def reorder_question_group(self, id, order, **kwargs): """ Update the order of questions within a given group :calls: `POST /api/v1/courses/:course_id/quizzes/:quiz_id/groups/:id/reorder \ <https://canvas.instructure.com/doc/api/quiz_question_groups.html#method.quizzes/quiz_groups.reorder>`_ :param id: The ID of the question group. :type id: int :param order: A list of dictionaries containing the key 'id' of the question to be placed at order's index. :type order: list[dict] :returns: True if the result was successful (Status code of 204) :rtype: bool """ if not isinstance(order, list) or not order: raise ValueError("Param `order` must be a non-empty list.") for question in order: if not isinstance(question, dict): raise ValueError( "`order` must consist only of dictionaries representing " "Question items.") if "id" not in question: raise ValueError( "Dictionaries in `order` must contain an `id` key.") kwargs["order"] = order response = self._requester.request( "POST", "courses/{}/quizzes/{}/groups/{}/reorder".format( self.course_id, self.quiz_id, id), _kwargs=combine_kwargs(**kwargs), ) return response.status_code == 204
def get_file(self, file, **kwargs): """ Return the standard attachment json object for a file. :calls: `GET /api/v1/users/:group_id/files/:id \ <https://canvas.instructure.com/doc/api/files.html#method.files.api_show>`_ :param file: The object or ID of the file to retrieve. :type file: :class:`canvasapi.file.File` or int :rtype: :class:`canvasapi.file.File` """ from canvasapi.file import File file_id = obj_or_id(file, "file", (File,)) response = self._requester.request( 'GET', 'users/{}/files/{}'.format(self.id, file_id), _kwargs=combine_kwargs(**kwargs) ) return File(self._requester, response.json())
def get_sessionless_launch_url(self, **kwargs): """ Return a sessionless launch url for an external tool. :calls: `GET /api/v1/courses/:course_id/external_tools/sessionless_launch <https://canvas.instructure.com/doc/api/external_tools.html#method.external_tools.generate_sessionless_launch>`_ or `GET /api/v1/accounts/:account_id/external_tools/sessionless_launch \ <https://canvas.instructure.com/doc/api/external_tools.html#method.external_tools.generate_sessionless_launch>`_ :rtype: str """ kwargs["id"] = self.id response = self._requester.request( "GET", "{}s/{}/external_tools/sessionless_launch".format( self.parent_type, self.parent_id), _kwargs=combine_kwargs(**kwargs), ) try: return response.json()["url"] except KeyError: raise CanvasException("Canvas did not respond with a valid URL")
def update_membership(self, user, **kwargs): """ Accept a membership request, or add/remove moderator rights. :calls: `PUT /api/v1/groups/:group_id/users/:user_id \ <https://canvas.instructure.com/doc/api/groups.html#method.group_memberships.update>`_ :param user: The object or ID of the user. :type user: :class:`canvasapi.user.User` or int :rtype: :class:`canvasapi.group.GroupMembership` """ from canvasapi.user import User user_id = obj_or_id(user, "user", (User,)) response = self._requester.request( "PUT", "groups/{}/users/{}".format(self.id, user_id), _kwargs=combine_kwargs(**kwargs), ) return GroupMembership(self._requester, response.json())
def get_submission(self, poll_submission, **kwargs): """ Returns the poll submission with the given id. :calls: `GET /api/v1/polls/:poll_id/poll_sessions/:poll_session_id/poll_submissions/:id \ <https://canvas.instructure.com/doc/api/poll_submissions.html#method.polling/poll_submissions.show>`_ :param poll_submission: Takes a poll submission id (int) or object. :type poll_submission: int or :class:`canvasapi.poll_submission.PollSubmission` :rtype: :class:`canvasapi.poll_submission.PollSubmission` """ poll_submission_id = obj_or_id(poll_submission, "poll_submission", (PollSubmission, )) response = self._requester.request( 'GET', 'polls/{}/poll_sessions/{}/poll_submissions/{}'.format( self.poll_id, self.id, poll_submission_id), _kwargs=combine_kwargs(**kwargs)) return PollSubmission(self._requester, response.json()['poll_submissions'][0])
def export_content(self, export_type, **kwargs): """ Begin a content export job for a group. :calls: `POST /api/v1/groups/:group_id/content_exports\ <https://canvas.instructure.com/doc/api/content_exports.html#method.content_exports_api.create>`_ :param export_type: The type of content to export. :type export_type: str :rtype: :class:`canvasapi.content_export.ContentExport` """ from canvasapi.content_export import ContentExport kwargs["export_type"] = export_type response = self._requester.request( "POST", "groups/{}/content_exports".format(self.id), _kwargs=combine_kwargs(**kwargs), ) return ContentExport(self._requester, response.json())
def remove_user(self, user, **kwargs): """ Leave a group if allowed. :calls: `DELETE /api/v1/groups/:group_id/users/:user_id \ <https://canvas.instructure.com/doc/api/groups.html#method.group_memberships.destroy>`_ :param user: The user object or ID to remove from the group. :type user: :class:`canvasapi.user.User` or int :rtype: :class:`canvasapi.user.User` """ from canvasapi.user import User user_id = obj_or_id(user, "user", (User,)) response = self._requester.request( "DELETE", "groups/{}/users/{}".format(self.id, user_id), _kwargs=combine_kwargs(**kwargs), ) return User(self._requester, response.json())
def delete_external_feed(self, feed, **kwargs): """ Deletes the external feed. :calls: `DELETE /api/v1/groups/:group_id/external_feeds/:external_feed_id \ <https://canvas.instructure.com/doc/api/announcement_external_feeds.html#method.external_feeds.destroy>`_ :param feed: The object or id of the feed to be deleted. :type feed: :class:`canvasapi.external_feed.ExternalFeed` or int :rtype: :class:`canvasapi.external_feed.ExternalFeed` """ from canvasapi.external_feed import ExternalFeed feed_id = obj_or_id(feed, "feed", (ExternalFeed,)) response = self._requester.request( "DELETE", "groups/{}/external_feeds/{}".format(self.id, feed_id), _kwargs=combine_kwargs(**kwargs), ) return ExternalFeed(self._requester, response.json())
def get_submission(self, assignment_id, user_id, **kwargs): """ Get a single submission, based on user id. :calls: `GET /api/v1/sections/:section_id/assignments/:assignment_id/submissions/:user_id \ <https://canvas.instructure.com/doc/api/submissions.html#method.submissions_api.show>`_ :param assignment_id: The ID of the assignment. :type assignment_id: int :param user_id: The ID of the user. :type user_id: str :rtype: :class:`canvasapi.submission.Submission` """ response = self._requester.request( 'GET', 'sections/%s/assignments/%s/submissions/%s' % (self.id, assignment_id, user_id), _kwargs=combine_kwargs(**kwargs)) response_json = response.json() response_json.update(section_id=self.id) return Submission(self._requester, response_json)
def cross_list_section(self, new_course, **kwargs): """ Move the Section to another course. :calls: `POST /api/v1/sections/:id/crosslist/:new_course_id \ <https://canvas.instructure.com/doc/api/sections.html#method.sections.crosslist>`_ :param new_course: The object or ID of the new course. :type new_course: :class:`canvasapi.course.Course` or int :rtype: :class:`canvasapi.section.Section` """ from canvasapi.course import Course new_course_id = obj_or_id(new_course, "new_course", (Course, )) response = self._requester.request( "POST", "sections/{}/crosslist/{}".format(self.id, new_course_id), _kwargs=combine_kwargs(**kwargs), ) return Section(self._requester, response.json())
def list_entry_replies(self, entry_id, **kwargs): """ Retrieves the replies to a top-level entry in a discussion topic. :calls: `GET /api/v1/courses/:course_id/discussion_topics/:topic_id/entries/:entry_id/replies \ <https://canvas.instructure.com/doc/api/discussion_topics.html#method.discussion_topics_api.replies>`_ or `GET /api/v1/groups/:group_id/discussion_topics/:topic_id/entries/:entry_id/replies \ <https://canvas.instructure.com/doc/api/discussion_topics.html#method.discussion_topics_api.replies>`_ :param entry_id: ID of an entry. :type entry_id: int :rtype: :class:`canvasapi.paginated_list.PaginatedList` of :class:`canvasapi.discussion_topic.DiscussionTopic` """ return PaginatedList( DiscussionTopic, self._requester, 'GET', '%ss/%s/discussion_topics/%s/entries/%s/replies' % (self.parent_type, self.parent_id, self.id, entry_id), **combine_kwargs(**kwargs))
def create_bookmark(self, name, url, **kwargs): """ Create a new Bookmark. :calls: `POST /api/v1/users/self/bookmarks \ <https://canvas.instructure.com/doc/api/bookmarks.html#method.bookmarks/bookmarks.create>`_ :param name: The name of the bookmark. :type name: `str` :param url: The url of the bookmark. :type url: `str` :rtype: :class:`canvasapi.bookmark.Bookmark` """ from canvasapi.bookmark import Bookmark response = self._requester.request('POST', 'users/self/bookmarks', name=name, url=url, _kwargs=combine_kwargs(**kwargs)) return Bookmark(self._requester, response.json())
def list_blueprint_imports(self, **kwargs): """ Return a list of migrations imported into a course associated with a blueprint. :calls: `GET /api/v1/courses/:course_id/blueprint_subscriptions/:subscription_id/\ migrations\ <https://canvas.instructure.com/doc/api/blueprint_courses.html#method.\ master_courses/master_templates.imports_index>`_ :rtype: :class:`canvasapi.paginated_list.PaginatedList` of :class:`canvasapi.blueprint.BlueprintMigration` """ return PaginatedList( BlueprintMigration, self._requester, "GET", "courses/{}/blueprint_subscriptions/{}/migrations".format( self.course_id, self.id), {"course_id": self.id}, kwargs=combine_kwargs(**kwargs), )
def get_migration_issues(self, **kwargs): """ List issues for this content migration :calls: `GET /api/v1/accounts/:account_id/content_migrations/:content_migration_id/migration_issues <https://canvas.instructure.com/doc/api/content_migrations.html#method.migration_issues.index>`_ or `GET /api/v1/courses/:course_id/content_migrations/:content_migration_id/migration_issues <https://canvas.instructure.com/doc/api/content_migrations.html#method.migration_issues.index>`_ or `GET /api/v1/groups/:group_id/content_migrations/:content_migration_id/migration_issues <https://canvas.instructure.com/doc/api/content_migrations.html#method.migration_issues.index>`_ or `GET /api/v1/users/:user_id/content_migrations/:content_migration_id/migration_issues <https://canvas.instructure.com/doc/api/content_migrations.html#method.migration_issues.index>`_ :rtype: :class:`canvasapi.content_migration.MigrationIssue` """ from canvasapi.content_migration import MigrationIssue return PaginatedList( MigrationIssue, self._requester, "GET", "{}s/{}/content_migrations/{}/migration_issues/".format( self._parent_type, self._parent_id, self.id), { "context_type": self._parent_type, "context_id": self._parent_id, "content_migration_id": self.id, }, _kwargs=combine_kwargs(**kwargs), )
def create_appointment_group(self, appointment_group, **kwargs): """ Create a new Appointment Group. :calls: `POST /api/v1/appointment_groups \ <https://canvas.instructure.com/doc/api/appointment_groups.html#method.appointment_groups.create>`_ :param appointment_group: The attributes of the appointment group. :type appointment_group: `dict` :param title: The title of the appointment group. :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 and "title" in appointment_group ): kwargs["appointment_group"] = appointment_group elif ( isinstance(appointment_group, dict) and "context_codes" not in appointment_group ): raise RequiredFieldMissing( "Dictionary with key 'context_codes' is missing." ) elif isinstance(appointment_group, dict) and "title" not in appointment_group: raise RequiredFieldMissing("Dictionary with key 'title' is missing.") response = self.__requester.request( "POST", "appointment_groups", _kwargs=combine_kwargs(**kwargs) ) return AppointmentGroup(self.__requester, response.json())
def get_account(self, account_id, use_sis_id=False, **kwargs): """ Retrieve information on an individual account. :calls: `GET /api/v1/accounts/:id \ <https://canvas.instructure.com/doc/api/accounts.html#method.accounts.show>`_ :param account_id: The ID of the account to retrieve. :type account_id: int or str :param use_sis_id: Whether or not account_id is an sis ID. Defaults to `False`. :type use_sis_id: bool :rtype: :class:`canvasapi.account.Account` """ if use_sis_id: uri_str = 'accounts/sis_account_id:{}' else: uri_str = 'accounts/{}' response = self.__requester.request('GET', uri_str.format(account_id), **combine_kwargs(**kwargs)) return Account(self.__requester, response.json())
def get_section(self, section_id, use_sis_id=False, **kwargs): """ Get details about a specific section. :calls: `GET /api/v1/sections/:id \ <https://canvas.instructure.com/doc/api/sections.html#method.sections.show>`_ :param section_id: The ID of the section to get. :type section_id: int or str :param use_sis_id: Whether or not section_id is an sis ID. Defaults to `False`. :type use_sis_id: bool :rtype: :class:`canvasapi.section.Section` """ if use_sis_id: uri_str = 'sections/sis_section_id:{}' else: uri_str = 'sections/{}' response = self.__requester.request('GET', uri_str.format(section_id), **combine_kwargs(**kwargs)) return Section(self.__requester, response.json())
def create_membership(self, user, **kwargs): """ Join, or request to join, a group, depending on the join_level of the group. If the membership or join request already exists, then it is simply returned. :calls: `POST /api/v1/groups/:group_id/memberships \ <https://canvas.instructure.com/doc/api/groups.html#method.group_memberships.create>`_ :param user: The object or ID of the user. :type user: :class:`canvasapi.user.User` or int :rtype: :class:`canvasapi.group.GroupMembership` """ from canvasapi.user import User user_id = obj_or_id(user, "user", (User, )) response = self._requester.request('POST', 'groups/{}/memberships'.format( self.id), user_id=user_id, _kwargs=combine_kwargs(**kwargs)) return GroupMembership(self._requester, response.json())
def update(self, **kwargs): """ Updates an existing discussion entry. :calls: `PUT /api/v1/courses/:course_id/discussion_topics/:topic_id/entries/:id \ <https://canvas.instructure.com/doc/api/discussion_topics.html#method.discussion_entries.update>`_ or `PUT /api/v1/groups/:group_id/discussion_topics/:topic_id/entries/:id \ <https://canvas.instructure.com/doc/api/discussion_topics.html#method.discussion_entries.update>`_ :rtype: bool """ response = self._requester.request( 'PUT', '{}s/{}/discussion_topics/{}/entries/{}'.format( self._discussion_parent_type, self._discussion_parent_id, self.discussion_id, self.id), _kwargs=combine_kwargs(**kwargs)) if response.json().get('updated_at'): super(DiscussionEntry, self).set_attributes(response.json()) return 'updated_at' in response.json()
def get_topic_entries(self, **kwargs): """ Retreive the top-level entries in a discussion topic. :calls: `GET /api/v1/courses/:course_id/discussion_topics/:topic_id/entries \ <https://canvas.instructure.com/doc/api/discussion_topics.html#method.discussion_topics_api.entries>`_ or `GET /api/v1/groups/:group_id/discussion_topics/:topic_id/entries \ <https://canvas.instructure.com/doc/api/discussion_topics.html#method.discussion_topics_api.entries>`_ :rtype: :class:`canvasapi.paginated_list.PaginatedList` of :class:`canvasapi.discussion_topic.DiscussionEntry` """ return PaginatedList( DiscussionEntry, self._requester, 'GET', '{}s/{}/discussion_topics/{}/entries'.format( self._parent_type, self._parent_id, self.id), { 'discussion_id': self.id, '{}_id'.format(self._parent_type): self._parent_id }, _kwargs=combine_kwargs(**kwargs))
def post_entry(self, **kwargs): """ Creates a new entry in a discussion topic. :calls: `POST /api/v1/courses/:course_id/discussion_topics/:topic_id/entries \ <https://canvas.instructure.com/doc/api/discussion_topics.html#method.discussion_topics_api.add_entry>`_ or `POST /api/v1/groups/:group_id/discussion_topics/:topic_id/entries \ <https://canvas.instructure.com/doc/api/discussion_topics.html#method.discussion_topics_api.add_entry>`_ :rtype: :class:`canvasapi.discussion_topic.DiscussionEntry` """ response = self._requester.request( 'POST', '{}s/{}/discussion_topics/{}/entries'.format( self._parent_type, self._parent_id, self.id), _kwargs=combine_kwargs(**kwargs)) response_json = response.json() response_json.update({ 'discussion_id': self.id, '{}_id'.format(self._parent_type): self._parent_id }) return DiscussionEntry(self._requester, response_json)
def create_user(self, pseudonym, **kwargs): """ Create and return a new user and pseudonym for an account. :calls: `POST /api/v1/accounts/:account_id/users \ <https://canvas.instructure.com/doc/api/users.html#method.users.create>`_ :param pseudonym: The pseudonym of the account. :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: raise RequiredFieldMissing( "Dictionary with key 'unique_id' is required.") response = self._requester.request('POST', 'accounts/{}/users'.format(self.id), _kwargs=combine_kwargs(**kwargs)) return User(self._requester, response.json())
def get_multiple_submissions(self, **kwargs): """ List submissions for multiple assignments. Get all existing submissions for a given set of students and assignments. :calls: `GET /api/v1/sections/:section_id/students/submissions \ <https://canvas.instructure.com/doc/api/submissions.html#method.submissions_api.for_students>`_ :rtype: :class:`canvasapi.paginated_list.PaginatedList` of :class:`canvasapi.submission.Submission` """ if 'grouped' in kwargs: warnings.warn('The `grouped` parameter must be empty. Removing kwarg `grouped`.') del kwargs['grouped'] return PaginatedList( Submission, self._requester, 'GET', 'sections/{}/students/submissions'.format(self.id), {'section_id': self.id}, _kwargs=combine_kwargs(**kwargs) )
def get_override(self, override, **kwargs): """ Get a single assignment override with the given override id. :calls: `GET /api/v1/courses/:course_id/assignments/:assignment_id/overrides/:id \ <https://canvas.instructure.com/doc/api/assignments.html#method.assignment_overrides.show>`_ :param override: The object or ID of the override to get :type override: :class:`canvasapi.assignment.AssignmentOverride` or int :rtype: :class:`canvasapi.assignment.AssignmentOverride` """ override_id = obj_or_id(override, "override", (AssignmentOverride, )) response = self._requester.request( "GET", "courses/{}/assignments/{}/overrides/{}".format( self.course_id, self.id, override_id), _kwargs=combine_kwargs(**kwargs), ) response_json = response.json() response_json.update(course_id=self.course_id) return AssignmentOverride(self._requester, response_json)
def copy_file(self, source_file, **kwargs): """ Copies a file into the current folder. :calls: `POST /api/v1/folders/:dest_folder_id/copy_file \ <https://canvas.instructure.com/doc/api/files.html#method.folders.copy_file>`_ :param source_file: The object or id of the source file. :type source_file: int or :class:`canvasapi.file.File` :rtype: :class:`canvasapi.folder.Folder` """ from canvasapi.file import File file_id = obj_or_id(source_file, "source_file", (File, )) kwargs['source_file_id'] = file_id response = self._requester.request('POST', 'folders/{}/copy_file'.format( self.id), _kwargs=combine_kwargs(**kwargs)) return File(self._requester, response.json())
def enroll_user(self, user, enrollment_type, **kwargs): """ Create a new user enrollment for a course or a section. :calls: `POST /api/v1/courses/:course_id/enrollments \ <https://canvas.instructure.com/doc/api/enrollments.html#method.enrollments_api.create>`_ :param user: The user to enroll in this course. :type user: :class:`canvasapi.user.User` :param enrollment_type: The type of enrollment. :type enrollment_type: str :rtype: :class:`canvasapi.enrollment.Enrollment` """ from canvasapi.enrollment import Enrollment kwargs['enrollment[user_id]'] = user.id kwargs['enrollment[type]'] = enrollment_type response = self._requester.request( 'POST', 'courses/%s/enrollments' % (self.id), **combine_kwargs(**kwargs)) return Enrollment(self._requester, response.json())
def get_content_export(self, content_export, **kwargs): """ Return information about a single content export. :calls: `GET /api/v1/groups/:group_id/content_exports/:id\ <https://canvas.instructure.com/doc/api/content_exports.html#method.content_exports_api.show>`_ :param content_export: The object or ID of the content export to show. :type content_export: int or :class:`canvasapi.content_export.ContentExport` :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( 'GET', 'groups/{}/content_exports/{}'.format(self.id, export_id), _kwargs=combine_kwargs(**kwargs)) return ContentExport(self._requester, response.json())