Esempio n. 1
0
 def test_post_merges_with_data_key(self, call_mock, merge_mock):
     """
     Test that the call to post method calls merge helper with 'data' as
     dictionary key (second positional parameter)
     """
     client.post(self.req_ctx, self.url)
     merge_mock.assert_called_once_with(mock.ANY, "data", mock.ANY)
Esempio n. 2
0
 def test_post_makes_call_with_action_url_and_context(self, call_mock, merge_mock):
     """
     Test that the call to get method sends expected action, url, and request
     context.
     """
     client.post(self.req_ctx, self.url)
     call_mock.assert_called_once_with("POST", self.url, self.req_ctx)
Esempio n. 3
0
 def test_post_merges_with_request_kwargs(self, call_mock, merge_mock):
     """
     Test that the call to post method calls merge helper with request_kwargs
     dictionary as first positional parameter
     """
     client.post(self.req_ctx, self.url, **self.request_kwargs)
     merge_mock.assert_called_once_with(self.request_kwargs, mock.ANY, mock.ANY)
Esempio n. 4
0
 def test_post_merges_with_payload(self, call_mock, merge_mock):
     """
     Test that the call to put method with a payload calls merge helper and passes
     in the payload as the value parameter.
     """
     client.post(self.req_ctx, self.url, self.payload)
     merge_mock.assert_called_once_with(mock.ANY, mock.ANY, self.payload)
Esempio n. 5
0
 def test_post_with_request_kwargs_and_payload(self, call_mock, merge_mock):
     """
     Test that the call to post method with payload and request kwargs passes through
     properly
     """
     client.post(self.req_ctx, self.url, self.payload, **self.request_kwargs)
     call_mock.assert_called_once_with(mock.ANY, mock.ANY, mock.ANY, **self.request_kwargs)
Esempio n. 6
0
 def test_post_merges_with_payload(self, call_mock, merge_mock):
     """
     Test that the call to put method with a payload calls merge helper and
     passes in the payload as the value parameter.
     """
     client.post(self.req_ctx, self.url, self.payload)
     merge_mock.assert_called_once_with(mock.ANY, mock.ANY, self.payload)
Esempio n. 7
0
 def test_post_merges_with_data_key(self, call_mock, merge_mock):
     """
     Test that the call to post method calls merge helper with 'data' as
     dictionary key (second positional parameter)
     """
     client.post(self.req_ctx, self.url)
     merge_mock.assert_called_once_with(mock.ANY, 'data', mock.ANY)
Esempio n. 8
0
 def test_post_makes_call_with_action_url_and_context(
         self, call_mock, merge_mock):
     """
     Test that the call to get method sends expected action, url, and request
     context.
     """
     client.post(self.req_ctx, self.url)
     call_mock.assert_called_once_with("POST", self.url, self.req_ctx)
Esempio n. 9
0
 def test_post_merges_with_request_kwargs(self, call_mock, merge_mock):
     """
     Test that the call to post method calls merge helper with request_kwargs
     dictionary as first positional parameter
     """
     client.post(self.req_ctx, self.url, **self.request_kwargs)
     merge_mock.assert_called_once_with(self.request_kwargs, mock.ANY,
                                        mock.ANY)
Esempio n. 10
0
 def test_post_with_request_kwargs_and_payload(self, call_mock, merge_mock):
     """
     Test that the call to post method with payload and request kwargs passes
     through properly.
     """
     client.post(self.req_ctx, self.url, self.payload,
                 **self.request_kwargs)
     call_mock.assert_called_once_with(mock.ANY, mock.ANY, mock.ANY,
                                       **self.request_kwargs)
def create_assignment_group(request_ctx, course_id, name=None, position=None, group_weight=None, rules=None, **request_kwargs):
    """
    Create a new assignment group for this course.

        :param request_ctx: The request context
        :type request_ctx: :class:RequestContext
        :param course_id: (required) ID
        :type course_id: string
        :param name: (optional) The assignment group's name
        :type name: string or None
        :param position: (optional) The position of this assignment group in relation to the other assignment groups
        :type position: integer or None
        :param group_weight: (optional) The percent of the total grade that this assignment group represents
        :type group_weight: float or None
        :param rules: (optional) The grading rules that are applied within this assignment group See the Assignment Group object definition for format
        :type rules: string or None
        :return: Create an Assignment Group
        :rtype: requests.Response (with AssignmentGroup data)

    """

    path = '/v1/courses/{course_id}/assignment_groups'
    payload = {
        'name' : name,
        'position' : position,
        'group_weight' : group_weight,
        'rules' : rules,
    }
    url = request_ctx.base_api_url + path.format(course_id=course_id)
    response = client.post(request_ctx, url, payload=payload, **request_kwargs)

    return response
Esempio n. 12
0
def upload_file(request_ctx, user_id, **request_kwargs):
    """
    Upload a file to the user's personal files section.
    
    This API endpoint is the first step in uploading a file to a user's files.
    See the {file:file_uploads.html File Upload Documentation} for details on
    the file upload workflow.
    
    Note that typically users will only be able to upload files to their
    own files section. Passing a user_id of +self+ is an easy shortcut
    to specify the current user.

        :param request_ctx: The request context
        :type request_ctx: :class:RequestContext
        :param user_id: (required) ID
        :type user_id: string
        :return: Upload a file
        :rtype: requests.Response (with void data)

    """

    path = '/v1/users/{user_id}/files'
    url = request_ctx.base_api_url + path.format(user_id=user_id)
    response = client.post(request_ctx, url, **request_kwargs)

    return response
Esempio n. 13
0
def upload_file(request_ctx, folder_id, **request_kwargs):
    """
    Upload a file to a folder.
    
    This API endpoint is the first step in uploading a file.
    See the {file:file_uploads.html File Upload Documentation} for details on
    the file upload workflow.
    
    Only those with the "Manage Files" permission on a course or group can
    upload files to a folder in that course or group.

        :param request_ctx: The request context
        :type request_ctx: :class:RequestContext
        :param folder_id: (required) ID
        :type folder_id: string
        :return: Upload a file
        :rtype: requests.Response (with void data)

    """

    path = '/v1/folders/{folder_id}/files'
    url = request_ctx.base_api_url + path.format(folder_id=folder_id)
    response = client.post(request_ctx, url, **request_kwargs)

    return response
def create_communication_channel(request_ctx, user_id, communication_channel_address, communication_channel_type, skip_confirmation=None, **request_kwargs):
    """
    Creates a new communication channel for the specified user.

        :param request_ctx: The request context
        :type request_ctx: :class:RequestContext
        :param user_id: (required) ID
        :type user_id: string
        :param communication_channel_address: (required) An email address or SMS number.
        :type communication_channel_address: string
        :param communication_channel_type: (required) The type of communication channel. In order to enable push notification support, the server must be properly configured (via sns.yml) to communicate with Amazon Simple Notification Services, and the developer key used to create the access token from this request must have an SNS ARN configured on it.
        :type communication_channel_type: string
        :param skip_confirmation: (optional) Only valid for site admins and account admins making requests; If true, the channel is automatically validated and no confirmation email or SMS is sent. Otherwise, the user must respond to a confirmation message to confirm the channel.
        :type skip_confirmation: boolean or None
        :return: Create a communication channel
        :rtype: requests.Response (with CommunicationChannel data)

    """

    communication_channel_type_types = ('email', 'sms', 'push')
    utils.validate_attr_is_acceptable(communication_channel_type, communication_channel_type_types)
    path = '/v1/users/{user_id}/communication_channels'
    payload = {
        'communication_channel[address]' : communication_channel_address,
        'communication_channel[type]' : communication_channel_type,
        'skip_confirmation' : skip_confirmation,
    }
    url = request_ctx.base_api_url + path.format(user_id=user_id)
    response = client.post(request_ctx, url, payload=payload, **request_kwargs)

    return response
Esempio n. 15
0
 def test_post_returns_call(self, call_mock, merge_mock):
     """
     Test that the call to post method returns the result of 'call'
     """
     result = client.post(self.req_ctx, self.url)
     self.assertEqual(result, call_mock.return_value,
                      "Call to 'post' should return result of 'call' method")
Esempio n. 16
0
def upload_file(request_ctx, user_id, **request_kwargs):
    """
    Upload a file to the user's personal files section.
    
    This API endpoint is the first step in uploading a file to a user's files.
    See the {file:file_uploads.html File Upload Documentation} for details on
    the file upload workflow.
    
    Note that typically users will only be able to upload files to their
    own files section. Passing a user_id of +self+ is an easy shortcut
    to specify the current user.

        :param request_ctx: The request context
        :type request_ctx: :class:RequestContext
        :param user_id: (required) ID
        :type user_id: string
        :return: Upload a file
        :rtype: requests.Response (with void data)

    """

    path = '/v1/users/{user_id}/files'
    url = request_ctx.base_api_url + path.format(user_id=user_id)
    response = client.post(request_ctx, url, **request_kwargs)

    return response
Esempio n. 17
0
def create_course_section(request_ctx, course_id, course_section_name, course_section_sis_section_id=None, course_section_start_at=None, course_section_end_at=None, **request_kwargs):
    """
    Creates a new section for this course.

        :param request_ctx: The request context
        :type request_ctx: :class:RequestContext
        :param course_id: (required) ID
        :type course_id: string
        :param course_section_name: (required) The name of the section
        :type course_section_name: string
        :param course_section_sis_section_id: (optional) The sis ID of the section
        :type course_section_sis_section_id: string or None
        :param course_section_start_at: (optional) Section start date in ISO8601 format, e.g. 2011-01-01T01:00Z
        :type course_section_start_at: datetime or None
        :param course_section_end_at: (optional) Section end date in ISO8601 format. e.g. 2011-01-01T01:00Z
        :type course_section_end_at: datetime or None
        :return: Create course section
        :rtype: requests.Response (with Section data)

    """

    path = '/v1/courses/{course_id}/sections'
    payload = {
        'course_section[name]' : course_section_name,
        'course_section[sis_section_id]' : course_section_sis_section_id,
        'course_section[start_at]' : course_section_start_at,
        'course_section[end_at]' : course_section_end_at,
    }
    url = request_ctx.base_api_url + path.format(course_id=course_id)
    response = client.post(request_ctx, url, payload=payload, **request_kwargs)

    return response
def create_single_poll_submission(request_ctx, poll_id, poll_session_id, poll_submissions_poll_choice_id, **request_kwargs):
    """
    Create a new poll submission for this poll session

        :param request_ctx: The request context
        :type request_ctx: :class:RequestContext
        :param poll_id: (required) ID
        :type poll_id: string
        :param poll_session_id: (required) ID
        :type poll_session_id: string
        :param poll_submissions_poll_choice_id: (required) The chosen poll choice for this submission.
        :type poll_submissions_poll_choice_id: integer
        :return: Create a single poll submission
        :rtype: requests.Response (with void data)

    """

    path = '/v1/polls/{poll_id}/poll_sessions/{poll_session_id}/poll_submissions'
    payload = {
        'poll_submissions[poll_choice_id]' : poll_submissions_poll_choice_id,
    }
    url = request_ctx.base_api_url + path.format(poll_id=poll_id, poll_session_id=poll_session_id)
    response = client.post(request_ctx, url, payload=payload, **request_kwargs)

    return response
def create_user_login(request_ctx, account_id, user_id, login_unique_id, login_password=None, login_sis_user_id=None, **request_kwargs):
    """
    Create a new login for an existing user in the given account.

        :param request_ctx: The request context
        :type request_ctx: :class:RequestContext
        :param account_id: (required) ID
        :type account_id: string
        :param user_id: (required) The ID of the user to create the login for.
        :type user_id: string
        :param login_unique_id: (required) The unique ID for the new login.
        :type login_unique_id: string
        :param login_password: (optional) The new login's password.
        :type login_password: string or None
        :param login_sis_user_id: (optional) SIS ID for the login. To set this parameter, the caller must be able to manage SIS permissions on the account.
        :type login_sis_user_id: string or None
        :return: Create a user login
        :rtype: requests.Response (with void data)

    """

    path = '/v1/accounts/{account_id}/logins'
    payload = {
        'user[id]' : user_id,
        'login[unique_id]' : login_unique_id,
        'login[password]' : login_password,
        'login[sis_user_id]' : login_sis_user_id,
    }
    url = request_ctx.base_api_url + path.format(account_id=account_id)
    response = client.post(request_ctx, url, payload=payload, **request_kwargs)

    return response
def upload_file(request_ctx, course_id, quiz_id, name, on_duplicate, **request_kwargs):
    """
    Associate a new quiz submission file
    
    This API endpoint is the first step in uploading a quiz submission file.
    See the {file:file_uploads.html File Upload Documentation} for details on
    the file upload workflow as these parameters are interpreted as per the
    documentation there.

        :param request_ctx: The request context
        :type request_ctx: :class:RequestContext
        :param course_id: (required) ID
        :type course_id: string
        :param quiz_id: (required) ID
        :type quiz_id: string
        :param name: (required) The name of the quiz submission file
        :type name: string
        :param on_duplicate: (required) How to handle duplicate names
        :type on_duplicate: string
        :return: Upload a file
        :rtype: requests.Response (with void data)

    """

    path = "/v1/courses/{course_id}/quizzes/{quiz_id}/submissions/self/files"
    payload = {"name": name, "on_duplicate": on_duplicate}
    url = request_ctx.base_api_url + path.format(course_id=course_id, quiz_id=quiz_id)
    response = client.post(request_ctx, url, payload=payload, **request_kwargs)

    return response
Esempio n. 21
0
def reserve_time_slot_participant_id(request_ctx, id, participant_id=None, cancel_existing=None, **request_kwargs):
    """
    Reserves a particular time slot and return the new reservation

        :param request_ctx: The request context
        :type request_ctx: :class:RequestContext
        :param id: (required) ID
        :type id: string
        :param participant_id: (optional) User or group id for whom you are making the reservation (depends on the participant type). Defaults to the current user (or user's candidate group).
        :type participant_id: string or None
        :param cancel_existing: (optional) Defaults to false. If true, cancel any previous reservation(s) for this participant and appointment group.
        :type cancel_existing: boolean or None
        :return: Reserve a time slot
        :rtype: requests.Response (with void data)

    """

    path = '/v1/calendar_events/{id}/reservations/{participant_id}'
    payload = {
        'cancel_existing' : cancel_existing,
    }
    url = request_ctx.base_api_url + path.format(id=id, participant_id=participant_id)
    response = client.post(request_ctx, url, payload=payload, **request_kwargs)

    return response
def reorder_custom_columns(request_ctx, course_id, order, **request_kwargs):
    """
    Puts the given columns in the specified order
    
    <b>200 OK</b> is returned if successful

        :param request_ctx: The request context
        :type request_ctx: :class:RequestContext
        :param course_id: (required) ID
        :type course_id: string
        :param order: (required) no description
        :type order: integer
        :return: Reorder custom columns
        :rtype: requests.Response (with void data)

    """

    path = '/v1/courses/{course_id}/custom_gradebook_columns/reorder'
    payload = {
        'order': order,
    }
    url = request_ctx.base_api_url + path.format(course_id=course_id)
    response = client.post(request_ctx, url, payload=payload, **request_kwargs)

    return response
Esempio n. 23
0
def upload_file(request_ctx, folder_id, **request_kwargs):
    """
    Upload a file to a folder.
    
    This API endpoint is the first step in uploading a file.
    See the {file:file_uploads.html File Upload Documentation} for details on
    the file upload workflow.
    
    Only those with the "Manage Files" permission on a course or group can
    upload files to a folder in that course or group.

        :param request_ctx: The request context
        :type request_ctx: :class:RequestContext
        :param folder_id: (required) ID
        :type folder_id: string
        :return: Upload a file
        :rtype: requests.Response (with void data)

    """

    path = "/v1/folders/{folder_id}/files"
    url = request_ctx.base_api_url + path.format(folder_id=folder_id)
    response = client.post(request_ctx, url, **request_kwargs)

    return response
Esempio n. 24
0
def create_single_poll_submission(request_ctx, poll_id, poll_session_id,
                                  poll_submissions_poll_choice_id,
                                  **request_kwargs):
    """
    Create a new poll submission for this poll session

        :param request_ctx: The request context
        :type request_ctx: :class:RequestContext
        :param poll_id: (required) ID
        :type poll_id: string
        :param poll_session_id: (required) ID
        :type poll_session_id: string
        :param poll_submissions_poll_choice_id: (required) The chosen poll choice for this submission.
        :type poll_submissions_poll_choice_id: integer
        :return: Create a single poll submission
        :rtype: requests.Response (with void data)

    """

    path = '/v1/polls/{poll_id}/poll_sessions/{poll_session_id}/poll_submissions'
    payload = {
        'poll_submissions[poll_choice_id]': poll_submissions_poll_choice_id,
    }
    url = request_ctx.base_api_url + path.format(
        poll_id=poll_id, poll_session_id=poll_session_id)
    response = client.post(request_ctx, url, payload=payload, **request_kwargs)

    return response
Esempio n. 25
0
def upload_file(request_ctx, group_id, **request_kwargs):
    """
    Upload a file to the group.
    
    This API endpoint is the first step in uploading a file to a group.
    See the {file:file_uploads.html File Upload Documentation} for details on
    the file upload workflow.
    
    Only those with the "Manage Files" permission on a group can upload files
    to the group. By default, this is anybody participating in the
    group, or any admin over the group.

        :param request_ctx: The request context
        :type request_ctx: :class:RequestContext
        :param group_id: (required) ID
        :type group_id: string
        :return: Upload a file
        :rtype: requests.Response (with void data)

    """

    path = "/v1/groups/{group_id}/files"
    url = request_ctx.base_api_url + path.format(group_id=group_id)
    response = client.post(request_ctx, url, **request_kwargs)

    return response
Esempio n. 26
0
def reserve_time_slot_participant_id(request_ctx,
                                     id,
                                     participant_id=None,
                                     cancel_existing=None,
                                     **request_kwargs):
    """
    Reserves a particular time slot and return the new reservation

        :param request_ctx: The request context
        :type request_ctx: :class:RequestContext
        :param id: (required) ID
        :type id: string
        :param participant_id: (optional) User or group id for whom you are making the reservation (depends on the participant type). Defaults to the current user (or user's candidate group).
        :type participant_id: string or None
        :param cancel_existing: (optional) Defaults to false. If true, cancel any previous reservation(s) for this participant and appointment group.
        :type cancel_existing: boolean or None
        :return: Reserve a time slot
        :rtype: requests.Response (with void data)

    """

    path = '/v1/calendar_events/{id}/reservations/{participant_id}'
    payload = {
        'cancel_existing': cancel_existing,
    }
    url = request_ctx.base_api_url + path.format(id=id,
                                                 participant_id=participant_id)
    response = client.post(request_ctx, url, payload=payload, **request_kwargs)

    return response
def upload_file(request_ctx, course_id, quiz_id, name, on_duplicate,
                **request_kwargs):
    """
    Associate a new quiz submission file
    
    This API endpoint is the first step in uploading a quiz submission file.
    See the {file:file_uploads.html File Upload Documentation} for details on
    the file upload workflow as these parameters are interpreted as per the
    documentation there.

        :param request_ctx: The request context
        :type request_ctx: :class:RequestContext
        :param course_id: (required) ID
        :type course_id: string
        :param quiz_id: (required) ID
        :type quiz_id: string
        :param name: (required) The name of the quiz submission file
        :type name: string
        :param on_duplicate: (required) How to handle duplicate names
        :type on_duplicate: string
        :return: Upload a file
        :rtype: requests.Response (with void data)

    """

    path = '/v1/courses/{course_id}/quizzes/{quiz_id}/submissions/self/files'
    payload = {
        'name': name,
        'on_duplicate': on_duplicate,
    }
    url = request_ctx.base_api_url + path.format(course_id=course_id,
                                                 quiz_id=quiz_id)
    response = client.post(request_ctx, url, payload=payload, **request_kwargs)

    return response
Esempio n. 28
0
def export_course_content(request_ctx, course_id, export_type, **request_kwargs):
    """
    Begin a content export job for a course.
    
    You can use the `ProgressController#show <https://github.com/instructure/canvas-lms/blob/master/app/controllers/progress_controller.rb>`_ to track the
    progress of the export. The migration's progress is linked to with the
    _progress_url_ value.
    
    When the export completes, use the `ContentExportsApiController#show <https://github.com/instructure/canvas-lms/blob/master/app/controllers/content_exports_api_controller.rb>`_ endpoint
    to retrieve a download URL for the exported content.

        :param request_ctx: The request context
        :type request_ctx: :class:RequestContext
        :param course_id: (required) ID
        :type course_id: string
        :param export_type: (required) "common_cartridge":: Export the contents of the course in the Common Cartridge (.imscc) format "qti":: Export quizzes in the QTI format
        :type export_type: string
        :return: Export course content
        :rtype: requests.Response (with ContentExport data)

    """

    export_type_types = ("common_cartridge", "qti")
    utils.validate_attr_is_acceptable(export_type, export_type_types)
    path = "/v1/courses/{course_id}/content_exports"
    payload = {"export_type": export_type}
    url = request_ctx.base_api_url + path.format(course_id=course_id)
    response = client.post(request_ctx, url, payload=payload, **request_kwargs)

    return response
Esempio n. 29
0
def start_report(request_ctx, account_id, report, parameters,
                 **request_kwargs):
    """
    Generates a report instance for the account.

        :param request_ctx: The request context
        :type request_ctx: :class:RequestContext
        :param account_id: (required) ID
        :type account_id: string
        :param report: (required) ID
        :type report: string
        :param parameters: (required) The parameters will vary for each report
        :type parameters: dict
        :return: Start a Report
        :rtype: requests.Response (with Report data)

    """

    path = '/v1/accounts/{account_id}/reports/{report}'

    # if the parameters dict has keys like 'enrollments', 'xlist', 'include_deleted'
    # we need to translate them to be like 'parameters[enrollments]'
    ppat = re.compile('parameters\[.+\]')
    fix_key = lambda (k, v): (k if ppat.match(str(k)) else 'parameters[{}]'.
                              format(k), v)
    payload = map(fix_key, parameters.items())
    url = request_ctx.base_api_url + path.format(account_id=account_id,
                                                 report=report)
    response = client.post(request_ctx, url, payload=payload, **request_kwargs)

    return response
def create_external_feed_groups(request_ctx, group_id, url, verbosity, header_match=None, **request_kwargs):
    """
    Create a new external feed for the course or group.

        :param request_ctx: The request context
        :type request_ctx: :class:RequestContext
        :param group_id: (required) ID
        :type group_id: string
        :param url: (required) The url to the external rss or atom feed
        :type url: string
        :param verbosity: (required) no description
        :type verbosity: string
        :param header_match: (optional) If given, only feed entries that contain this string in their title will be imported
        :type header_match: boolean or None
        :return: Create an external feed
        :rtype: requests.Response (with ExternalFeed data)

    """

    verbosity_types = ('full', 'truncate', 'link_only')
    utils.validate_attr_is_acceptable(verbosity, verbosity_types)
    path = '/v1/groups/{group_id}/external_feeds'
    payload = {
        'url' : url,
        'header_match' : header_match,
        'verbosity' : verbosity,
    }
    url = request_ctx.base_api_url + path.format(group_id=group_id)
    response = client.post(request_ctx, url, payload=payload, **request_kwargs)

    return response
def reorder_question_groups(request_ctx, course_id, quiz_id, id, order_id, order_type, **request_kwargs):
    """
    Change the order of the quiz questions within the group
    
    <b>204 No Content<b> response code is returned if the reorder was successful.

        :param request_ctx: The request context
        :type request_ctx: :class:RequestContext
        :param course_id: (required) ID
        :type course_id: string
        :param quiz_id: (required) ID
        :type quiz_id: string
        :param id: (required) ID
        :type id: string
        :param order_id: (required) The associated item's unique identifier
        :type order_id: integer
        :param order_type: (required) The type of item is always 'question' for a group
        :type order_type: string
        :return: Reorder question groups
        :rtype: requests.Response (with void data)

    """

    order_type_types = ('question')
    utils.validate_attr_is_acceptable(order_type, order_type_types)
    path = '/v1/courses/{course_id}/quizzes/{quiz_id}/groups/{id}/reorder'
    payload = {
        'order[id]' : order_id,
        'order[type]' : order_type,
    }
    url = request_ctx.base_api_url + path.format(course_id=course_id, quiz_id=quiz_id, id=id)
    response = client.post(request_ctx, url, payload=payload, **request_kwargs)

    return response
Esempio n. 32
0
def create_single_poll_session(request_ctx, poll_id, poll_sessions_course_id, poll_sessions_course_section_id=None, poll_sessions_has_public_results=None, **request_kwargs):
    """
    Create a new poll session for this poll

        :param request_ctx: The request context
        :type request_ctx: :class:RequestContext
        :param poll_id: (required) ID
        :type poll_id: string
        :param poll_sessions_course_id: (required) The id of the course this session is associated with.
        :type poll_sessions_course_id: integer
        :param poll_sessions_course_section_id: (optional) The id of the course section this session is associated with.
        :type poll_sessions_course_section_id: integer or None
        :param poll_sessions_has_public_results: (optional) Whether or not results are viewable by students.
        :type poll_sessions_has_public_results: boolean or None
        :return: Create a single poll session
        :rtype: requests.Response (with void data)

    """

    path = '/v1/polls/{poll_id}/poll_sessions'
    payload = {
        'poll_sessions[course_id]' : poll_sessions_course_id,
        'poll_sessions[course_section_id]' : poll_sessions_course_section_id,
        'poll_sessions[has_public_results]' : poll_sessions_has_public_results,
    }
    url = request_ctx.base_api_url + path.format(poll_id=poll_id)
    response = client.post(request_ctx, url, payload=payload, **request_kwargs)

    return response
Esempio n. 33
0
def make_account_admin(request_ctx, account_id, user_id, role=None, send_confirmation=None, **request_kwargs):
    """
    Flag an existing user as an admin within the account.

        :param request_ctx: The request context
        :type request_ctx: :class:RequestContext
        :param account_id: (required) ID
        :type account_id: string
        :param user_id: (required) The id of the user to promote.
        :type user_id: integer
        :param role: (optional) The user's admin relationship with the account will be created with the given role. Defaults to 'AccountAdmin'.
        :type role: string or None
        :param send_confirmation: (optional) Send a notification email to the new admin if true. Default is true.
        :type send_confirmation: boolean or None
        :return: Make an account admin
        :rtype: requests.Response (with Admin data)

    """

    path = '/v1/accounts/{account_id}/admins'
    payload = {
        'user_id' : user_id,
        'role' : role,
        'send_confirmation' : send_confirmation,
    }
    url = request_ctx.base_api_url + path.format(account_id=account_id)
    response = client.post(request_ctx, url, payload=payload, **request_kwargs)

    return response
def start_report(request_ctx, account_id, report, parameters, **request_kwargs):
    """
    Generates a report instance for the account.

        :param request_ctx: The request context
        :type request_ctx: :class:RequestContext
        :param account_id: (required) ID
        :type account_id: string
        :param report: (required) ID
        :type report: string
        :param parameters: (required) The parameters will vary for each report
        :type parameters: dict
        :return: Start a Report
        :rtype: requests.Response (with Report data)

    """

    path = '/v1/accounts/{account_id}/reports/{report}'

    # if the parameters dict has keys like 'enrollments', 'xlist', 'include_deleted'
    # we need to translate them to be like 'parameters[enrollments]'
    ppat = re.compile('parameters\[.+\]')
    fix_key = lambda (k, v): (k if ppat.match(str(k)) else 'parameters[{}]'.format(k), v)
    payload = map(fix_key, parameters.items())
    url = request_ctx.base_api_url + path.format(account_id=account_id, report=report)
    response = client.post(request_ctx, url, payload=payload, **request_kwargs)

    return response
def export_course_content(request_ctx, course_id, export_type, **request_kwargs):
    """
    Begin a content export job for a course.
    
    You can use the `ProgressController#show <https://github.com/instructure/canvas-lms/blob/master/app/controllers/progress_controller.rb>`_ to track the
    progress of the export. The migration's progress is linked to with the
    _progress_url_ value.
    
    When the export completes, use the `ContentExportsApiController#show <https://github.com/instructure/canvas-lms/blob/master/app/controllers/content_exports_api_controller.rb>`_ endpoint
    to retrieve a download URL for the exported content.

        :param request_ctx: The request context
        :type request_ctx: :class:RequestContext
        :param course_id: (required) ID
        :type course_id: string
        :param export_type: (required) "common_cartridge":: Export the contents of the course in the Common Cartridge (.imscc) format "qti":: Export quizzes in the QTI format
        :type export_type: string
        :return: Export course content
        :rtype: requests.Response (with ContentExport data)

    """

    export_type_types = ('common_cartridge', 'qti')
    utils.validate_attr_is_acceptable(export_type, export_type_types)
    path = '/v1/courses/{course_id}/content_exports'
    payload = {
        'export_type' : export_type,
    }
    url = request_ctx.base_api_url + path.format(course_id=course_id)
    response = client.post(request_ctx, url, payload=payload, **request_kwargs)

    return response
Esempio n. 36
0
def upload_file_sections(request_ctx, section_id, assignment_id, user_id, **request_kwargs):
    """
    Upload a file to a submission.
    
    This API endpoint is the first step in uploading a file to a submission as a student.
    See the {file:file_uploads.html File Upload Documentation} for details on the file upload workflow.
    
    The final step of the file upload workflow will return the attachment data,
    including the new file id. The caller can then POST to submit the
    +online_upload+ assignment with these file ids.

        :param request_ctx: The request context
        :type request_ctx: :class:RequestContext
        :param section_id: (required) ID
        :type section_id: string
        :param assignment_id: (required) ID
        :type assignment_id: string
        :param user_id: (required) ID
        :type user_id: string
        :return: Upload a file
        :rtype: requests.Response (with void data)

    """

    path = '/v1/sections/{section_id}/assignments/{assignment_id}/submissions/{user_id}/files'
    url = request_ctx.base_api_url + path.format(section_id=section_id, assignment_id=assignment_id, user_id=user_id)
    response = client.post(request_ctx, url, **request_kwargs)

    return response
Esempio n. 37
0
def upload_file(request_ctx, group_id, **request_kwargs):
    """
    Upload a file to the group.
    
    This API endpoint is the first step in uploading a file to a group.
    See the {file:file_uploads.html File Upload Documentation} for details on
    the file upload workflow.
    
    Only those with the "Manage Files" permission on a group can upload files
    to the group. By default, this is anybody participating in the
    group, or any admin over the group.

        :param request_ctx: The request context
        :type request_ctx: :class:RequestContext
        :param group_id: (required) ID
        :type group_id: string
        :return: Upload a file
        :rtype: requests.Response (with void data)

    """

    path = '/v1/groups/{group_id}/files'
    url = request_ctx.base_api_url + path.format(group_id=group_id)
    response = client.post(request_ctx, url, **request_kwargs)

    return response
Esempio n. 38
0
def upload_file_sections(request_ctx, section_id, assignment_id, user_id,
                         **request_kwargs):
    """
    Upload a file to a submission.
    
    This API endpoint is the first step in uploading a file to a submission as a student.
    See the {file:file_uploads.html File Upload Documentation} for details on the file upload workflow.
    
    The final step of the file upload workflow will return the attachment data,
    including the new file id. The caller can then POST to submit the
    +online_upload+ assignment with these file ids.

        :param request_ctx: The request context
        :type request_ctx: :class:RequestContext
        :param section_id: (required) ID
        :type section_id: string
        :param assignment_id: (required) ID
        :type assignment_id: string
        :param user_id: (required) ID
        :type user_id: string
        :return: Upload a file
        :rtype: requests.Response (with void data)

    """

    path = '/v1/sections/{section_id}/assignments/{assignment_id}/submissions/{user_id}/files'
    url = request_ctx.base_api_url + path.format(
        section_id=section_id, assignment_id=assignment_id, user_id=user_id)
    response = client.post(request_ctx, url, **request_kwargs)

    return response
def reorder_custom_columns(request_ctx, course_id, order, **request_kwargs):
    """
    Puts the given columns in the specified order
    
    <b>200 OK</b> is returned if successful

        :param request_ctx: The request context
        :type request_ctx: :class:RequestContext
        :param course_id: (required) ID
        :type course_id: string
        :param order: (required) no description
        :type order: integer
        :return: Reorder custom columns
        :rtype: requests.Response (with void data)

    """

    path = '/v1/courses/{course_id}/custom_gradebook_columns/reorder'
    payload = {
        'order' : order,
    }
    url = request_ctx.base_api_url + path.format(course_id=course_id)
    response = client.post(request_ctx, url, payload=payload, **request_kwargs)

    return response
def create_single_poll_choice(request_ctx,
                              poll_id,
                              poll_choices_text,
                              poll_choices_is_correct=None,
                              poll_choices_position=None,
                              **request_kwargs):
    """
    Create a new poll choice for this poll

        :param request_ctx: The request context
        :type request_ctx: :class:RequestContext
        :param poll_id: (required) ID
        :type poll_id: string
        :param poll_choices_text: (required) The descriptive text of the poll choice.
        :type poll_choices_text: string
        :param poll_choices_is_correct: (optional) Whether this poll choice is considered correct or not. Defaults to false.
        :type poll_choices_is_correct: boolean or None
        :param poll_choices_position: (optional) The order this poll choice should be returned in the context it's sibling poll choices.
        :type poll_choices_position: integer or None
        :return: Create a single poll choice
        :rtype: requests.Response (with void data)

    """

    path = '/v1/polls/{poll_id}/poll_choices'
    payload = {
        'poll_choices[text]': poll_choices_text,
        'poll_choices[is_correct]': poll_choices_is_correct,
        'poll_choices[position]': poll_choices_position,
    }
    url = request_ctx.base_api_url + path.format(poll_id=poll_id)
    response = client.post(request_ctx, url, payload=payload, **request_kwargs)

    return response
def create_custom_gradebook_column(request_ctx, course_id, column_title, column_position, column_hidden=None, column_teacher_notes=None, **request_kwargs):
    """
    Create a custom gradebook column

        :param request_ctx: The request context
        :type request_ctx: :class:RequestContext
        :param course_id: (required) ID
        :type course_id: string
        :param column_title: (required) no description
        :type column_title: string
        :param column_position: (required) The position of the column relative to other custom columns
        :type column_position: int
        :param column_hidden: (optional) Hidden columns are not displayed in the gradebook
        :type column_hidden: boolean or None
        :param column_teacher_notes: (optional) Set this if the column is created by a teacher. The gradebook only supports one teacher_notes column.
        :type column_teacher_notes: boolean or None
        :return: Create a custom gradebook column
        :rtype: requests.Response (with CustomColumn data)

    """

    path = '/v1/courses/{course_id}/custom_gradebook_columns'
    payload = {
        'column[title]' : column_title,
        'column[position]' : column_position,
        'column[hidden]' : column_hidden,
        'column[teacher_notes]' : column_teacher_notes,
    }
    url = request_ctx.base_api_url + path.format(course_id=course_id)
    response = client.post(request_ctx, url, payload=payload, **request_kwargs)

    return response
Esempio n. 42
0
def create_single_poll(request_ctx,
                       polls_question,
                       polls_description=None,
                       **request_kwargs):
    """
    Create a new poll for the current user

        :param request_ctx: The request context
        :type request_ctx: :class:RequestContext
        :param polls_question: (required) The title of the poll.
        :type polls_question: string
        :param polls_description: (optional) A brief description or instructions for the poll.
        :type polls_description: string or None
        :return: Create a single poll
        :rtype: requests.Response (with void data)

    """

    path = '/v1/polls'
    payload = {
        'polls[question]': polls_question,
        'polls[description]': polls_description,
    }
    url = request_ctx.base_api_url + path.format()
    response = client.post(request_ctx, url, payload=payload, **request_kwargs)

    return response
def assign_unassigned_members(request_ctx,
                              group_category_id,
                              sync=None,
                              **request_kwargs):
    """
    Assign all unassigned members as evenly as possible among the existing
    student groups.

        :param request_ctx: The request context
        :type request_ctx: :class:RequestContext
        :param group_category_id: (required) ID
        :type group_category_id: string
        :param sync: (optional) The assigning is done asynchronously by default. If you would like to override this and have the assigning done synchronously, set this value to true.
        :type sync: boolean or None
        :return: Assign unassigned members
        :rtype: requests.Response (with GroupMembership | Progress data)

    """

    path = '/v1/group_categories/{group_category_id}/assign_unassigned_members'
    payload = {
        'sync': sync,
    }
    url = request_ctx.base_api_url + path.format(
        group_category_id=group_category_id)
    response = client.post(request_ctx, url, payload=payload, **request_kwargs)

    return response
Esempio n. 44
0
def add_observee_with_credentials(request_ctx, user_id, observee_unique_id=None, observee_password=None, **request_kwargs):
    """
    Register the given user to observe another user, given the observee's credentials.
    
    *Note:* all users are allowed to add their own observees, given the observee's
    credentials are provided. Administrators can add observees given credentials or
    the `UserObserveesController#update <https://github.com/instructure/canvas-lms/blob/master/app/controllers/user_observees_controller.rb>`_.

        :param request_ctx: The request context
        :type request_ctx: :class:RequestContext
        :param user_id: (required) ID
        :type user_id: string
        :param observee_unique_id: (optional) The login id for the user to observe.
        :type observee_unique_id: string or None
        :param observee_password: (optional) The password for the user to observe.
        :type observee_password: string or None
        :return: Add an observee with credentials
        :rtype: requests.Response (with User data)

    """

    path = '/v1/users/{user_id}/observees'
    payload = {
        'observee[unique_id]' : observee_unique_id,
        'observee[password]' : observee_password,
    }
    url = request_ctx.base_api_url + path.format(user_id=user_id)
    response = client.post(request_ctx, url, payload=payload, **request_kwargs)

    return response
Esempio n. 45
0
def create_membership(request_ctx, group_id, user_id, **request_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

        :param request_ctx: The request context
        :type request_ctx: :class:RequestContext
        :param group_id: (required) ID
        :type group_id: string
        :param user_id: (required) no description
        :type user_id: string
        :return: Create a membership
        :rtype: requests.Response (with GroupMembership data)

    """

    path = '/v1/groups/{group_id}/memberships'
    payload = {
        'user_id': user_id,
    }
    url = request_ctx.base_api_url + path.format(group_id=group_id)
    response = client.post(request_ctx, url, payload=payload, **request_kwargs)

    return response
Esempio n. 46
0
def start_report(request_ctx, account_id, report, parameters, **request_kwargs):
    """
    Generates a report instance for the account.

        :param request_ctx: The request context
        :type request_ctx: :class:RequestContext
        :param account_id: (required) ID
        :type account_id: string
        :param report: (required) ID
        :type report: string
        :param parameters: (required) The parameters will vary for each report
        :type parameters: string
        :return: Start a Report
        :rtype: requests.Response (with Report data)

    """

    path = '/v1/accounts/{account_id}/reports/{report}'
    payload = {
        '[parameters]' : parameters,
    }
    url = request_ctx.base_api_url + path.format(account_id=account_id, report=report)
    response = client.post(request_ctx, url, payload=payload, **request_kwargs)

    return response
def create_single_poll_session(request_ctx,
                               poll_id,
                               poll_sessions_course_id,
                               poll_sessions_course_section_id=None,
                               poll_sessions_has_public_results=None,
                               **request_kwargs):
    """
    Create a new poll session for this poll

        :param request_ctx: The request context
        :type request_ctx: :class:RequestContext
        :param poll_id: (required) ID
        :type poll_id: string
        :param poll_sessions_course_id: (required) The id of the course this session is associated with.
        :type poll_sessions_course_id: integer
        :param poll_sessions_course_section_id: (optional) The id of the course section this session is associated with.
        :type poll_sessions_course_section_id: integer or None
        :param poll_sessions_has_public_results: (optional) Whether or not results are viewable by students.
        :type poll_sessions_has_public_results: boolean or None
        :return: Create a single poll session
        :rtype: requests.Response (with void data)

    """

    path = '/v1/polls/{poll_id}/poll_sessions'
    payload = {
        'poll_sessions[course_id]': poll_sessions_course_id,
        'poll_sessions[course_section_id]': poll_sessions_course_section_id,
        'poll_sessions[has_public_results]': poll_sessions_has_public_results,
    }
    url = request_ctx.base_api_url + path.format(poll_id=poll_id)
    response = client.post(request_ctx, url, payload=payload, **request_kwargs)

    return response
Esempio n. 48
0
def reorder_quiz_items(request_ctx, course_id, id, order_id, order_type, **request_kwargs):
    """
    Change order of the quiz questions or groups within the quiz
    
    <b>204 No Content<b> response code is returned if the reorder was successful.

        :param request_ctx: The request context
        :type request_ctx: :class:RequestContext
        :param course_id: (required) ID
        :type course_id: string
        :param id: (required) ID
        :type id: string
        :param order_id: (required) The associated item's unique identifier
        :type order_id: integer
        :param order_type: (required) The type of item is either 'question' or 'group'
        :type order_type: string
        :return: Reorder quiz items
        :rtype: requests.Response (with void data)

    """

    order_type_types = ("question", "group")
    utils.validate_attr_is_acceptable(order_type, order_type_types)
    path = "/v1/courses/{course_id}/quizzes/{id}/reorder"
    payload = {"order[id]": order_id, "order[type]": order_type}
    url = request_ctx.base_api_url + path.format(course_id=course_id, id=id)
    response = client.post(request_ctx, url, payload=payload, **request_kwargs)

    return response
Esempio n. 49
0
def upload_file(request_ctx, course_id, assignment_id, user_id, **request_kwargs):
    """
    Upload a file to attach to a submission comment
    
    See the {file:file_uploads.html File Upload Documentation} for details on the file upload workflow.
    
    The final step of the file upload workflow will return the attachment data,
    including the new file id. The caller can then PUT the file_id to the
    submission API to attach it to a comment

        :param request_ctx: The request context
        :type request_ctx: :class:RequestContext
        :param course_id: (required) ID
        :type course_id: string
        :param assignment_id: (required) ID
        :type assignment_id: string
        :param user_id: (required) ID
        :type user_id: string
        :return: Upload a file
        :rtype: requests.Response (with void data)

    """

    path = '/v1/courses/{course_id}/assignments/{assignment_id}/submissions/{user_id}/comments/files'
    url = request_ctx.base_api_url + path.format(course_id=course_id, assignment_id=assignment_id, user_id=user_id)
    response = client.post(request_ctx, url, **request_kwargs)

    return response
def upload_file(request_ctx, course_id, **request_kwargs):
    """
    Upload a file to the course.

    This API endpoint is the first step in uploading a file to a course.
    See the {file:file_uploads.html File Upload Documentation} for details on
    the file upload workflow.

    Only those with the "Manage Files" permission on a course can upload files
    to the course. By default, this is Teachers, TAs and Designers.

        :param request_ctx: The request context
        :type request_ctx: :class:RequestContext
        :param course_id: (required) ID
        :type course_id: string
        :return: Upload a file
        :rtype: requests.Response (with void data)

    """

    path = '/v1/courses/{course_id}/files'
    url = request_ctx.base_api_url + path.format(course_id=course_id)
    response = client.post(request_ctx, url, **request_kwargs)

    return response
Esempio n. 51
0
def create_single_poll_choice(request_ctx, poll_id, poll_choices_text, poll_choices_is_correct=None, poll_choices_position=None, **request_kwargs):
    """
    Create a new poll choice for this poll

        :param request_ctx: The request context
        :type request_ctx: :class:RequestContext
        :param poll_id: (required) ID
        :type poll_id: string
        :param poll_choices_text: (required) The descriptive text of the poll choice.
        :type poll_choices_text: string
        :param poll_choices_is_correct: (optional) Whether this poll choice is considered correct or not. Defaults to false.
        :type poll_choices_is_correct: boolean or None
        :param poll_choices_position: (optional) The order this poll choice should be returned in the context it's sibling poll choices.
        :type poll_choices_position: integer or None
        :return: Create a single poll choice
        :rtype: requests.Response (with void data)

    """

    path = '/v1/polls/{poll_id}/poll_choices'
    payload = {
        'poll_choices[text]' : poll_choices_text,
        'poll_choices[is_correct]' : poll_choices_is_correct,
        'poll_choices[position]' : poll_choices_position,
    }
    url = request_ctx.base_api_url + path.format(poll_id=poll_id)
    response = client.post(request_ctx, url, payload=payload, **request_kwargs)

    return response
Esempio n. 52
0
def create_new_role(request_ctx, account_id, role, base_role_type=None, permissions={}, **request_kwargs):
    """
    Create a new course-level or account-level role.

        :param request_ctx: The request context
        :type request_ctx: :class:RequestContext
        :param account_id: (required) ID
        :type account_id: string
        :param role: (required) Label and unique identifier for the role.
        :type role: string
        :param base_role_type: (optional) Specifies the role type that will be used as a base for the permissions granted to this role. Defaults to 'AccountMembership' if absent
        :type base_role_type: string or None
        :param permissions: (optional) Specifies the permissions that will be granted to this role. See Canvas API docs for details on the structure.
        :type permissions: dict
        :return: Create a new role
        :rtype: requests.Response (with Role data)

    """

    base_role_type_types = ('AccountMembership', 'StudentEnrollment', 'TeacherEnrollment', 'TaEnrollment', 'ObserverEnrollment', 'DesignerEnrollment')
    utils.validate_attr_is_acceptable(base_role_type, base_role_type_types)
    path = '/v1/accounts/{account_id}/roles'
    payload = {
        'role' : role,
        'base_role_type' : base_role_type,
    }
    # flatten the permissions dict
    for p in permissions:
        for a in permissions[p]:
            payload['permissions[{}][{}]'.format(p, a)] = permissions[p][a]

    url = request_ctx.base_api_url + path.format(account_id=account_id)
    response = client.post(request_ctx, url, payload=payload, **request_kwargs)

    return response
Esempio n. 53
0
def upload_file(request_ctx, course_id, **request_kwargs):
    """
    Upload a file to the course.

    This API endpoint is the first step in uploading a file to a course.
    See the {file:file_uploads.html File Upload Documentation} for details on
    the file upload workflow.

    Only those with the "Manage Files" permission on a course can upload files
    to the course. By default, this is Teachers, TAs and Designers.

        :param request_ctx: The request context
        :type request_ctx: :class:RequestContext
        :param course_id: (required) ID
        :type course_id: string
        :return: Upload a file
        :rtype: requests.Response (with void data)

    """

    path = '/v1/courses/{course_id}/files'
    url = request_ctx.base_api_url + path.format(course_id=course_id)
    response = client.post(request_ctx, url, **request_kwargs)

    return response
Esempio n. 54
0
 def test_post_returns_call(self, call_mock, merge_mock):
     """
     Test that the call to post method returns the result of 'call'
     """
     result = client.post(self.req_ctx, self.url)
     self.assertEqual(
         result, call_mock.return_value,
         "Call to 'post' should return result of 'call' method")
Esempio n. 55
0
def create_assignment_override(request_ctx,
                               course_id,
                               assignment_id,
                               assignment_override_student_ids=None,
                               assignment_override_title=None,
                               assignment_override_group_id=None,
                               assignment_override_course_section_id=None,
                               assignment_override_due_at=None,
                               assignment_override_unlock_at=None,
                               assignment_override_lock_at=None,
                               **request_kwargs):
    """
    One of student_ids, group_id, or course_section_id must be present. At most
    one should be present; if multiple are present only the most specific
    (student_ids first, then group_id, then course_section_id) is used and any
    others are ignored.

        :param request_ctx: The request context
        :type request_ctx: :class:RequestContext
        :param course_id: (required) ID
        :type course_id: string
        :param assignment_id: (required) ID
        :type assignment_id: string
        :param assignment_override_student_ids: (optional) The IDs of the override's target students. If present, the IDs must each identify a user with an active student enrollment in the course that is not already targetted by a different adhoc override.
        :type assignment_override_student_ids: integer or None
        :param assignment_override_title: (optional) The title of the adhoc assignment override. Required if student_ids is present, ignored otherwise (the title is set to the name of the targetted group or section instead).
        :type assignment_override_title: string or None
        :param assignment_override_group_id: (optional) The ID of the override's target group. If present, the following conditions must be met for the override to be successful: 1. the assignment MUST be a group assignment (a group_category_id is assigned to it) 2. the ID must identify an active group in the group set the assignment is in 3. the ID must not be targetted by a different override See {Appendix: Group assignments} for more info.
        :type assignment_override_group_id: integer or None
        :param assignment_override_course_section_id: (optional) The ID of the override's target section. If present, must identify an active section of the assignment's course not already targetted by a different override.
        :type assignment_override_course_section_id: integer or None
        :param assignment_override_due_at: (optional) The day/time the overridden assignment is due. Accepts times in ISO 8601 format, e.g. 2014-10-21T18:48:00Z. If absent, this override will not affect due date. May be present but null to indicate the override removes any previous due date.
        :type assignment_override_due_at: timestamp or None
        :param assignment_override_unlock_at: (optional) The day/time the overridden assignment becomes unlocked. Accepts times in ISO 8601 format, e.g. 2014-10-21T18:48:00Z. If absent, this override will not affect the unlock date. May be present but null to indicate the override removes any previous unlock date.
        :type assignment_override_unlock_at: timestamp or None
        :param assignment_override_lock_at: (optional) The day/time the overridden assignment becomes locked. Accepts times in ISO 8601 format, e.g. 2014-10-21T18:48:00Z. If absent, this override will not affect the lock date. May be present but null to indicate the override removes any previous lock date.
        :type assignment_override_lock_at: timestamp or None
        :return: Create an assignment override
        :rtype: requests.Response (with AssignmentOverride data)

    """

    path = '/v1/courses/{course_id}/assignments/{assignment_id}/overrides'
    payload = {
        'assignment_override[student_ids]': assignment_override_student_ids,
        'assignment_override[title]': assignment_override_title,
        'assignment_override[group_id]': assignment_override_group_id,
        'assignment_override[course_section_id]':
        assignment_override_course_section_id,
        'assignment_override[due_at]': assignment_override_due_at,
        'assignment_override[unlock_at]': assignment_override_unlock_at,
        'assignment_override[lock_at]': assignment_override_lock_at,
    }
    url = request_ctx.base_api_url + path.format(course_id=course_id,
                                                 assignment_id=assignment_id)
    response = client.post(request_ctx, url, payload=payload, **request_kwargs)

    return response
def import_sis_data(request_ctx,
                    account_id,
                    attachment,
                    import_type=None,
                    extension=None,
                    batch_mode=None,
                    batch_mode_term_id=None,
                    override_sis_stickiness=None,
                    add_sis_stickiness=None,
                    clear_sis_stickiness=None,
                    **request_kwargs):
    """
    Import SIS data into Canvas. Must be on a root account with SIS imports
    enabled.
    
    For more information on the format that's expected here, please see the
    "SIS CSV" section in the API docs.

        :param request_ctx: The request context
        :type request_ctx: :class:RequestContext
        :param account_id: (required) ID
        :type account_id: string
        :param attachment: (required) There are two ways to post SIS import data - either via a multipart/form-data form-field-style attachment, or via a non-multipart raw post request. 'attachment' is required for multipart/form-data style posts. Assumed to be SIS data from a file upload form field named 'attachment'. Examples: curl -F attachment=@<filename> -H "Authorization: Bearer <token>" \ 'https://<canvas>/api/v1/accounts/<account_id>/sis_imports.json?import_type=instructure_csv' If you decide to do a raw post, you can skip the 'attachment' argument, but you will then be required to provide a suitable Content-Type header. You are encouraged to also provide the 'extension' argument. Examples: curl -H 'Content-Type: application/octet-stream' --data-binary @<filename>.zip \ -H "Authorization: Bearer <token>" \ 'https://<canvas>/api/v1/accounts/<account_id>/sis_imports.json?import_type=instructure_csv&extension=zip' curl -H 'Content-Type: application/zip' --data-binary @<filename>.zip \ -H "Authorization: Bearer <token>" \ 'https://<canvas>/api/v1/accounts/<account_id>/sis_imports.json?import_type=instructure_csv' curl -H 'Content-Type: text/csv' --data-binary @<filename>.csv \ -H "Authorization: Bearer <token>" \ 'https://<canvas>/api/v1/accounts/<account_id>/sis_imports.json?import_type=instructure_csv' curl -H 'Content-Type: text/csv' --data-binary @<filename>.csv \ -H "Authorization: Bearer <token>" \ 'https://<canvas>/api/v1/accounts/<account_id>/sis_imports.json?import_type=instructure_csv&batch_mode=1&batch_mode_term_id=15'
        :type attachment: string
        :param import_type: (optional) Choose the data format for reading SIS data. With a standard Canvas install, this option can only be 'instructure_csv', and if unprovided, will be assumed to be so. Can be part of the query string.
        :type import_type: string or None
        :param extension: (optional) Recommended for raw post request style imports. This field will be used to distinguish between zip, xml, csv, and other file format extensions that would usually be provided with the filename in the multipart post request scenario. If not provided, this value will be inferred from the Content-Type, falling back to zip-file format if all else fails.
        :type extension: string or None
        :param batch_mode: (optional) If set, this SIS import will be run in batch mode, deleting any data previously imported via SIS that is not present in this latest import. See the SIS CSV Format page for details.
        :type batch_mode: boolean or None
        :param batch_mode_term_id: (optional) Limit deletions to only this term. Required if batch mode is enabled.
        :type batch_mode_term_id: string or None
        :param override_sis_stickiness: (optional) Many fields on records in Canvas can be marked "sticky," which means that when something changes in the UI apart from the SIS, that field gets "stuck." In this way, by default, SIS imports do not override UI changes. If this field is present, however, it will tell the SIS import to ignore "stickiness" and override all fields.
        :type override_sis_stickiness: boolean or None
        :param add_sis_stickiness: (optional) This option, if present, will process all changes as if they were UI changes. This means that "stickiness" will be added to changed fields. This option is only processed if 'override_sis_stickiness' is also provided.
        :type add_sis_stickiness: boolean or None
        :param clear_sis_stickiness: (optional) This option, if present, will clear "stickiness" from all fields touched by this import. Requires that 'override_sis_stickiness' is also provided. If 'add_sis_stickiness' is also provided, 'clear_sis_stickiness' will overrule the behavior of 'add_sis_stickiness'
        :type clear_sis_stickiness: boolean or None
        :return: Import SIS data
        :rtype: requests.Response (with SisImport data)

    """

    path = '/v1/accounts/{account_id}/sis_imports'
    payload = {
        'import_type': import_type,
        'attachment': attachment,
        'extension': extension,
        'batch_mode': batch_mode,
        'batch_mode_term_id': batch_mode_term_id,
        'override_sis_stickiness': override_sis_stickiness,
        'add_sis_stickiness': add_sis_stickiness,
        'clear_sis_stickiness': clear_sis_stickiness,
    }
    url = request_ctx.base_api_url + path.format(account_id=account_id)
    response = client.post(request_ctx, url, payload=payload, **request_kwargs)

    return response