diff --git a/canvasapi/canvas.py b/canvasapi/canvas.py
index 687649c..13193ea 100644
--- a/canvasapi/canvas.py
+++ b/canvasapi/canvas.py
@@ -1,5 +1,7 @@
 from __future__ import absolute_import, division, print_function, unicode_literals
 
+import warnings
+
 from canvasapi.account import Account
 from canvasapi.course import Course
 from canvasapi.exceptions import RequiredFieldMissing
@@ -10,7 +12,10 @@ from canvasapi.paginated_list import PaginatedList
 from canvasapi.requester import Requester
 from canvasapi.section import Section
 from canvasapi.user import User
-from canvasapi.util import combine_kwargs, obj_or_id
+from canvasapi.util import combine_kwargs, get_institution_url, obj_or_id
+
+
+warnings.simplefilter('always', DeprecationWarning)
 
 
 class Canvas(object):
@@ -25,6 +30,16 @@ class Canvas(object):
         :param access_token: The API key to authenticate requests with.
         :type access_token: str
         """
+        new_url = get_institution_url(base_url)
+
+        if 'api/v1' in base_url:
+            warnings.warn(
+                "`base_url` no longer requires an API version be specified. "
+                "Rewriting `base_url` to {}".format(new_url),
+                DeprecationWarning
+            )
+        base_url = new_url + '/api/v1/'
+
         self.__requester = Requester(base_url, access_token)
 
     def create_account(self, **kwargs):
diff --git a/canvasapi/util.py b/canvasapi/util.py
index 88c469c..86d6ee4 100644
--- a/canvasapi/util.py
+++ b/canvasapi/util.py
@@ -122,3 +122,19 @@ def obj_or_id(parameter, param_name, object_types):
         obj_type_list = ",".join([obj_type.__name__ for obj_type in object_types])
         message = 'Parameter {} must be of type {} or int.'.format(param_name, obj_type_list)
         raise TypeError(message)
+
+
+def get_institution_url(base_url):
+    """
+    Trim '/api/v1' from a given root URL.
+
+    :param base_url: The base URL of the API.
+    :type base_url: str
+    :rtype: str
+    """
+    index = base_url.find('/api/v1')
+
+    if index != -1:
+        return base_url[0:index]
+
+    return base_url

Deprecate /api/v1 from Canvas constructor
Currently we require `/api/v1/` to be appended to the end of an institution's Canvas URL when initializing the `Canvas` object.

We don't check if the URL is malformed in anyway, and as a result, sometimes unexpected behavior can present itself. We recently ran into this issue with one of our own applications where the base URL was set to `instructure.edu//api/v1/`.

We should implement a fix for this in two ways:

* Remove the `/api/version` requirement in the URL as we don't currently support targeting more than one API version
* Force URLs to be formatted properly (i.e. `*.someurl.com` with no trailing slash, `https://` or `http://` allowed) and manually append the `/api/v1/` string ourselves afterward

We should also warn the user that `/api/v1/` has been deprecated and is no longer required if they include it in their base URL.
diff --git a/tests/settings.py b/tests/settings.py
index 789a25c..e67c5f6 100644
--- a/tests/settings.py
+++ b/tests/settings.py
@@ -1,6 +1,7 @@
 from __future__ import absolute_import, division, print_function, unicode_literals
 
-BASE_URL = 'http://example.com/api/v1/'
+BASE_URL = 'http://example.com'
+BASE_URL_WITH_VERSION = 'http://example.com/api/v1/'
 API_KEY = '123'
 
 INVALID_ID = 9001
diff --git a/tests/test_canvas.py b/tests/test_canvas.py
index dc5ec34..3d75228 100644
--- a/tests/test_canvas.py
+++ b/tests/test_canvas.py
@@ -1,5 +1,7 @@
 from __future__ import absolute_import, division, print_function, unicode_literals
+
 import unittest
+import warnings
 from datetime import datetime
 
 import pytz
@@ -30,6 +32,12 @@ class TestCanvas(unittest.TestCase):
     def setUp(self):
         self.canvas = Canvas(settings.BASE_URL, settings.API_KEY)
 
+    # Canvas()
+    def test_init_deprecate_url_contains_version(self, m):
+        with warnings.catch_warnings(record=True) as w:
+            Canvas(settings.BASE_URL_WITH_VERSION, settings.API_KEY)
+            self.assertTrue(issubclass(w[0].category, DeprecationWarning))
+
     # create_account()
     def test_create_account(self, m):
         register_uris({'account': ['create']}, m)
diff --git a/tests/test_course.py b/tests/test_course.py
index 415f426..fb6e76c 100644
--- a/tests/test_course.py
+++ b/tests/test_course.py
@@ -176,14 +176,16 @@ class TestCourse(unittest.TestCase):
         register_uris({'course': ['upload', 'upload_final']}, m)
 
         filename = 'testfile_course_{}'.format(uuid.uuid4().hex)
-        with open(filename, 'w+') as file:
-            response = self.course.upload(file)
 
-        self.assertTrue(response[0])
-        self.assertIsInstance(response[1], dict)
-        self.assertIn('url', response[1])
+        try:
+            with open(filename, 'w+') as file:
+                response = self.course.upload(file)
 
-        cleanup_file(filename)
+            self.assertTrue(response[0])
+            self.assertIsInstance(response[1], dict)
+            self.assertIn('url', response[1])
+        finally:
+            cleanup_file(filename)
 
     # reset()
     def test_reset(self, m):
diff --git a/tests/test_group.py b/tests/test_group.py
index 526eb23..e948c44 100644
--- a/tests/test_group.py
+++ b/tests/test_group.py
@@ -152,13 +152,14 @@ class TestGroup(unittest.TestCase):
         register_uris({'group': ['upload', 'upload_final']}, m)
 
         filename = 'testfile_group_{}'.format(uuid.uuid4().hex)
-        with open(filename, 'w+') as file:
-            response = self.group.upload(file)
-        self.assertTrue(response[0])
-        self.assertIsInstance(response[1], dict)
-        self.assertIn('url', response[1])
-
-        cleanup_file(filename)
+        try:
+            with open(filename, 'w+') as file:
+                response = self.group.upload(file)
+            self.assertTrue(response[0])
+            self.assertIsInstance(response[1], dict)
+            self.assertIn('url', response[1])
+        finally:
+            cleanup_file(filename)
 
     # preview_processed_html()
     def test_preview_processed_html(self, m):
diff --git a/tests/test_submission.py b/tests/test_submission.py
index 8a083e0..2ccc29c 100644
--- a/tests/test_submission.py
+++ b/tests/test_submission.py
@@ -37,14 +37,16 @@ class TestSubmission(unittest.TestCase):
         register_uris({'submission': ['upload_comment', 'upload_comment_final']}, m)
 
         filename = 'testfile_submission_{}'.format(uuid.uuid4().hex)
-        with open(filename, 'w+') as file:
-            response = self.submission_course.upload_comment(file)
 
-        self.assertTrue(response[0])
-        self.assertIsInstance(response[1], dict)
-        self.assertIn('url', response[1])
+        try:
+            with open(filename, 'w+') as file:
+                response = self.submission_course.upload_comment(file)
 
-        cleanup_file(filename)
+            self.assertTrue(response[0])
+            self.assertIsInstance(response[1], dict)
+            self.assertIn('url', response[1])
+        finally:
+            cleanup_file(filename)
 
     def test_upload_comment_section(self, m):
         # Sections do not support uploading file comments
diff --git a/tests/test_uploader.py b/tests/test_uploader.py
index a72ecd2..6cea063 100644
--- a/tests/test_uploader.py
+++ b/tests/test_uploader.py
@@ -22,7 +22,6 @@ class TestUploader(unittest.TestCase):
 
     def tearDown(self):
         self.file.close()
-
         cleanup_file(self.filename)
 
     # start()
diff --git a/tests/test_user.py b/tests/test_user.py
index fa5d5b7..d2ed67c 100644
--- a/tests/test_user.py
+++ b/tests/test_user.py
@@ -203,14 +203,16 @@ class TestUser(unittest.TestCase):
         register_uris({'user': ['upload', 'upload_final']}, m)
 
         filename = 'testfile_user_{}'.format(uuid.uuid4().hex)
-        with open(filename, 'w+') as file:
-            response = self.user.upload(file)
 
-        self.assertTrue(response[0])
-        self.assertIsInstance(response[1], dict)
-        self.assertIn('url', response[1])
+        try:
+            with open(filename, 'w+') as file:
+                response = self.user.upload(file)
 
-        cleanup_file(filename)
+            self.assertTrue(response[0])
+            self.assertIsInstance(response[1], dict)
+            self.assertIn('url', response[1])
+        finally:
+            cleanup_file(filename)
 
     # list_groups()
     def test_list_groups(self, m):
diff --git a/tests/test_util.py b/tests/test_util.py
index 71677d0..472b4f1 100644
--- a/tests/test_util.py
+++ b/tests/test_util.py
@@ -6,7 +6,9 @@ import requests_mock
 from canvasapi import Canvas
 from canvasapi.course import CourseNickname
 from canvasapi.user import User
-from canvasapi.util import combine_kwargs, is_multivalued, obj_or_id
+from canvasapi.util import (
+    combine_kwargs, get_institution_url, is_multivalued, obj_or_id
+)
 from itertools import chain
 from six import integer_types, iterkeys, itervalues, iteritems
 from six.moves import zip
@@ -408,3 +410,8 @@ class TestUtil(unittest.TestCase):
 
         with self.assertRaises(TypeError):
             obj_or_id(nick, 'nickname_id', (CourseNickname,))
+
+    # get_institution_url()
+    def test_get_institution_url(self, m):
+        base_url = 'https://my.canvas.edu/api/v1'
+        self.assertEqual(get_institution_url(base_url), 'https://my.canvas.edu')
diff --git a/tests/util.py b/tests/util.py
index 3b92514..89a2616 100644
--- a/tests/util.py
+++ b/tests/util.py
@@ -4,6 +4,7 @@ import os
 
 import requests_mock
 
+from canvasapi.util import get_institution_url
 from tests import settings
 
 
@@ -17,7 +18,6 @@ def register_uris(requirements, requests_mocker):
     :param requests_mocker: requests_mock.mocker.Mocker
     """
     for fixture, objects in requirements.items():
-
         try:
             with open('tests/fixtures/{}.json'.format(fixture)) as file:
                 data = json.loads(file.read())
@@ -40,7 +40,7 @@ def register_uris(requirements, requests_mocker):
             if obj['endpoint'] == 'ANY':
                 url = requests_mock.ANY
             else:
-                url = settings.BASE_URL + obj['endpoint']
+                url = get_institution_url(settings.BASE_URL) + '/api/v1/' + obj['endpoint']
 
             try:
                 requests_mocker.register_uri(

pip install -e .[dev]
parse_log_pytest
requirements.txt
pytest flake8 pycodestyle requests_mock
apt-get update apt-get install -y gcc
3.9
requirements.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
-e git+https://github.com/ucfopen/canvasapi.git@d265d4a49df7041dca888247f48feda7e288cf15#egg=canvasapi
certifi==2025.1.31
charset-normalizer==3.4.1
exceptiongroup==1.2.2
flake8==7.2.0
idna==3.10
iniconfig==2.1.0
mccabe==0.7.0
packaging==24.2
pluggy==1.5.0
pycodestyle==2.13.0
pyflakes==3.3.1
pytest==8.3.5
pytz==2025.2
requests==2.32.3
requests-mock==1.12.1
six==1.17.0
tomli==2.2.1
urllib3==2.3.0

name: canvasapi
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - pip=25.0=py39h06a4308_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - setuptools=75.8.0=py39h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tzdata=2025a=h04d1e81_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - certifi==2025.1.31
      - charset-normalizer==3.4.1
      - exceptiongroup==1.2.2
      - flake8==7.2.0
      - idna==3.10
      - iniconfig==2.1.0
      - mccabe==0.7.0
      - packaging==24.2
      - pluggy==1.5.0
      - pycodestyle==2.13.0
      - pyflakes==3.3.1
      - pytest==8.3.5
      - pytz==2025.2
      - requests==2.32.3
      - requests-mock==1.12.1
      - six==1.17.0
      - tomli==2.2.1
      - urllib3==2.3.0
prefix: /opt/conda/envs/canvasapi

tests/test_canvas.py::TestCanvas::test_clear_course_nicknames tests/test_canvas.py::TestCanvas::test_conversations_batch_update tests/test_canvas.py::TestCanvas::test_conversations_batch_updated_fail_on_event tests/test_canvas.py::TestCanvas::test_conversations_batch_updated_fail_on_ids tests/test_canvas.py::TestCanvas::test_conversations_get_running_batches tests/test_canvas.py::TestCanvas::test_conversations_mark_all_as_read tests/test_canvas.py::TestCanvas::test_conversations_unread_count tests/test_canvas.py::TestCanvas::test_create_account tests/test_canvas.py::TestCanvas::test_create_appointment_group tests/test_canvas.py::TestCanvas::test_create_appointment_group_fail_on_context_codes tests/test_canvas.py::TestCanvas::test_create_appointment_group_fail_on_title tests/test_canvas.py::TestCanvas::test_create_calendar_event tests/test_canvas.py::TestCanvas::test_create_calendar_event_fail tests/test_canvas.py::TestCanvas::test_create_conversation tests/test_canvas.py::TestCanvas::test_create_group tests/test_canvas.py::TestCanvas::test_get_account tests/test_canvas.py::TestCanvas::test_get_account_fail tests/test_canvas.py::TestCanvas::test_get_account_sis_id tests/test_canvas.py::TestCanvas::test_get_accounts tests/test_canvas.py::TestCanvas::test_get_activity_stream_summary tests/test_canvas.py::TestCanvas::test_get_appointment_group tests/test_canvas.py::TestCanvas::test_get_calendar_event tests/test_canvas.py::TestCanvas::test_get_conversation tests/test_canvas.py::TestCanvas::test_get_conversations tests/test_canvas.py::TestCanvas::test_get_course tests/test_canvas.py::TestCanvas::test_get_course_accounts tests/test_canvas.py::TestCanvas::test_get_course_fail tests/test_canvas.py::TestCanvas::test_get_course_nickname tests/test_canvas.py::TestCanvas::test_get_course_nickname_fail tests/test_canvas.py::TestCanvas::test_get_course_nicknames tests/test_canvas.py::TestCanvas::test_get_course_non_unicode_char tests/test_canvas.py::TestCanvas::test_get_course_sis_id tests/test_canvas.py::TestCanvas::test_get_course_with_start_date tests/test_canvas.py::TestCanvas::test_get_courses tests/test_canvas.py::TestCanvas::test_get_file tests/test_canvas.py::TestCanvas::test_get_group tests/test_canvas.py::TestCanvas::test_get_group_category tests/test_canvas.py::TestCanvas::test_get_group_sis_id tests/test_canvas.py::TestCanvas::test_get_outcome tests/test_canvas.py::TestCanvas::test_get_outcome_group tests/test_canvas.py::TestCanvas::test_get_root_outcome_group tests/test_canvas.py::TestCanvas::test_get_section tests/test_canvas.py::TestCanvas::test_get_section_sis_id tests/test_canvas.py::TestCanvas::test_get_todo_items tests/test_canvas.py::TestCanvas::test_get_upcoming_events tests/test_canvas.py::TestCanvas::test_get_user tests/test_canvas.py::TestCanvas::test_get_user_by_id_type tests/test_canvas.py::TestCanvas::test_get_user_fail tests/test_canvas.py::TestCanvas::test_get_user_self tests/test_canvas.py::TestCanvas::test_list_appointment_groups tests/test_canvas.py::TestCanvas::test_list_calendar_events tests/test_canvas.py::TestCanvas::test_list_group_participants tests/test_canvas.py::TestCanvas::test_list_user_participants tests/test_canvas.py::TestCanvas::test_reserve_time_slot tests/test_canvas.py::TestCanvas::test_reserve_time_slot_by_participant_id tests/test_canvas.py::TestCanvas::test_search_accounts tests/test_canvas.py::TestCanvas::test_search_all_courses tests/test_canvas.py::TestCanvas::test_search_recipients tests/test_canvas.py::TestCanvas::test_set_course_nickname tests/test_course.py::TestCourse::test__str__ tests/test_course.py::TestCourse::test_add_grading_standards tests/test_course.py::TestCourse::test_add_grading_standards_empty_list tests/test_course.py::TestCourse::test_add_grading_standards_missing_name_key tests/test_course.py::TestCourse::test_add_grading_standards_missing_value_key tests/test_course.py::TestCourse::test_add_grading_standards_non_dict_list tests/test_course.py::TestCourse::test_conclude tests/test_course.py::TestCourse::test_course_files tests/test_course.py::TestCourse::test_create_assignment tests/test_course.py::TestCourse::test_create_assignment_fail tests/test_course.py::TestCourse::test_create_assignment_group tests/test_course.py::TestCourse::test_create_course_section tests/test_course.py::TestCourse::test_create_discussion_topic tests/test_course.py::TestCourse::test_create_external_feed tests/test_course.py::TestCourse::test_create_external_tool tests/test_course.py::TestCourse::test_create_folder tests/test_course.py::TestCourse::test_create_group_category tests/test_course.py::TestCourse::test_create_module tests/test_course.py::TestCourse::test_create_module_fail tests/test_course.py::TestCourse::test_create_page tests/test_course.py::TestCourse::test_create_page_fail tests/test_course.py::TestCourse::test_create_quiz tests/test_course.py::TestCourse::test_create_quiz_fail tests/test_course.py::TestCourse::test_delete tests/test_course.py::TestCourse::test_delete_external_feed tests/test_course.py::TestCourse::test_edit_front_page tests/test_course.py::TestCourse::test_enroll_user tests/test_course.py::TestCourse::test_get_assignment tests/test_course.py::TestCourse::test_get_assignment_group tests/test_course.py::TestCourse::test_get_assignments tests/test_course.py::TestCourse::test_get_course_level_assignment_data tests/test_course.py::TestCourse::test_get_course_level_participation_data tests/test_course.py::TestCourse::test_get_course_level_student_summary_data tests/test_course.py::TestCourse::test_get_discussion_topic tests/test_course.py::TestCourse::test_get_discussion_topics tests/test_course.py::TestCourse::test_get_enrollments tests/test_course.py::TestCourse::test_get_external_tool tests/test_course.py::TestCourse::test_get_external_tools tests/test_course.py::TestCourse::test_get_file tests/test_course.py::TestCourse::test_get_folder tests/test_course.py::TestCourse::test_get_full_discussion_topic tests/test_course.py::TestCourse::test_get_grading_standards tests/test_course.py::TestCourse::test_get_module tests/test_course.py::TestCourse::test_get_modules tests/test_course.py::TestCourse::test_get_outcome_group tests/test_course.py::TestCourse::test_get_outcome_groups_in_context tests/test_course.py::TestCourse::test_get_outcome_links_in_context tests/test_course.py::TestCourse::test_get_outcome_result_rollups tests/test_course.py::TestCourse::test_get_outcome_results tests/test_course.py::TestCourse::test_get_page tests/test_course.py::TestCourse::test_get_pages tests/test_course.py::TestCourse::test_get_quiz tests/test_course.py::TestCourse::test_get_quiz_fail tests/test_course.py::TestCourse::test_get_quizzes tests/test_course.py::TestCourse::test_get_recent_students tests/test_course.py::TestCourse::test_get_root_outcome_group tests/test_course.py::TestCourse::test_get_section tests/test_course.py::TestCourse::test_get_settings tests/test_course.py::TestCourse::test_get_single_grading_standard tests/test_course.py::TestCourse::test_get_submission tests/test_course.py::TestCourse::test_get_user tests/test_course.py::TestCourse::test_get_user_id_type tests/test_course.py::TestCourse::test_get_user_in_a_course_level_assignment_data tests/test_course.py::TestCourse::test_get_user_in_a_course_level_messaging_data tests/test_course.py::TestCourse::test_get_user_in_a_course_level_participation_data tests/test_course.py::TestCourse::test_get_users tests/test_course.py::TestCourse::test_list_assignment_groups tests/test_course.py::TestCourse::test_list_external_feeds tests/test_course.py::TestCourse::test_list_folders tests/test_course.py::TestCourse::test_list_gradeable_students tests/test_course.py::TestCourse::test_list_group_categories tests/test_course.py::TestCourse::test_list_groups tests/test_course.py::TestCourse::test_list_multiple_submissions tests/test_course.py::TestCourse::test_list_multiple_submissions_grouped_param tests/test_course.py::TestCourse::test_list_sections tests/test_course.py::TestCourse::test_list_submissions tests/test_course.py::TestCourse::test_list_tabs tests/test_course.py::TestCourse::test_mark_submission_as_read tests/test_course.py::TestCourse::test_mark_submission_as_unread tests/test_course.py::TestCourse::test_preview_html tests/test_course.py::TestCourse::test_reorder_pinned_topics tests/test_course.py::TestCourse::test_reorder_pinned_topics_comma_separated_string tests/test_course.py::TestCourse::test_reorder_pinned_topics_invalid_input tests/test_course.py::TestCourse::test_reorder_pinned_topics_tuple tests/test_course.py::TestCourse::test_reset tests/test_course.py::TestCourse::test_show_front_page tests/test_course.py::TestCourse::test_subit_assignment_fail tests/test_course.py::TestCourse::test_submit_assignment tests/test_course.py::TestCourse::test_update tests/test_course.py::TestCourse::test_update_settings tests/test_course.py::TestCourse::test_update_submission tests/test_course.py::TestCourse::test_update_tab tests/test_course.py::TestCourse::test_upload tests/test_course.py::TestCourseNickname::test__str__ tests/test_course.py::TestCourseNickname::test_remove tests/test_group.py::TestGroup::test__str__ tests/test_group.py::TestGroup::test_create_discussion_topic tests/test_group.py::TestGroup::test_create_external_feed tests/test_group.py::TestGroup::test_create_folder tests/test_group.py::TestGroup::test_create_membership tests/test_group.py::TestGroup::test_create_page tests/test_group.py::TestGroup::test_create_page_fail tests/test_group.py::TestGroup::test_delete tests/test_group.py::TestGroup::test_delete_external_feed tests/test_group.py::TestGroup::test_edit tests/test_group.py::TestGroup::test_edit_front_page tests/test_group.py::TestGroup::test_get_activity_stream_summary tests/test_group.py::TestGroup::test_get_discussion_topic tests/test_group.py::TestGroup::test_get_discussion_topics tests/test_group.py::TestGroup::test_get_file tests/test_group.py::TestGroup::test_get_folder tests/test_group.py::TestGroup::test_get_full_discussion_topic tests/test_group.py::TestGroup::test_get_membership tests/test_group.py::TestGroup::test_get_page tests/test_group.py::TestGroup::test_get_pages tests/test_group.py::TestGroup::test_group_files tests/test_group.py::TestGroup::test_invite tests/test_group.py::TestGroup::test_list_external_feeds tests/test_group.py::TestGroup::test_list_folders tests/test_group.py::TestGroup::test_list_memberships tests/test_group.py::TestGroup::test_list_tabs tests/test_group.py::TestGroup::test_list_users tests/test_group.py::TestGroup::test_preview_processed_html tests/test_group.py::TestGroup::test_remove_user tests/test_group.py::TestGroup::test_reorder_pinned_topics tests/test_group.py::TestGroup::test_reorder_pinned_topics_comma_separated_string tests/test_group.py::TestGroup::test_reorder_pinned_topics_invalid_input tests/test_group.py::TestGroup::test_reorder_pinned_topics_tuple tests/test_group.py::TestGroup::test_show_front_page tests/test_group.py::TestGroup::test_update_membership tests/test_group.py::TestGroup::test_upload tests/test_group.py::TestGroupMembership::test__str__ tests/test_group.py::TestGroupMembership::test_remove_self tests/test_group.py::TestGroupMembership::test_remove_user tests/test_group.py::TestGroupMembership::test_update tests/test_group.py::TestGroupCategory::test__str__ tests/test_group.py::TestGroupCategory::test_assign_members tests/test_group.py::TestGroupCategory::test_create_group tests/test_group.py::TestGroupCategory::test_delete_category tests/test_group.py::TestGroupCategory::test_list_groups tests/test_group.py::TestGroupCategory::test_list_users tests/test_group.py::TestGroupCategory::test_update tests/test_submission.py::TestSubmission::test__str__ tests/test_submission.py::TestSubmission::test_upload_comment tests/test_submission.py::TestSubmission::test_upload_comment_section tests/test_uploader.py::TestUploader::test_start tests/test_uploader.py::TestUploader::test_start_file_does_not_exist tests/test_uploader.py::TestUploader::test_start_path tests/test_uploader.py::TestUploader::test_upload_fail tests/test_uploader.py::TestUploader::test_upload_no_upload_params tests/test_uploader.py::TestUploader::test_upload_no_upload_url tests/test_user.py::TestUser::test__str__ tests/test_user.py::TestUser::test_add_observee tests/test_user.py::TestUser::test_add_observee_with_credentials tests/test_user.py::TestUser::test_create_bookmark tests/test_user.py::TestUser::test_create_folder tests/test_user.py::TestUser::test_edit tests/test_user.py::TestUser::test_get_avatars tests/test_user.py::TestUser::test_get_bookmark tests/test_user.py::TestUser::test_get_color tests/test_user.py::TestUser::test_get_colors tests/test_user.py::TestUser::test_get_courses tests/test_user.py::TestUser::test_get_file tests/test_user.py::TestUser::test_get_folder tests/test_user.py::TestUser::test_get_missing_submissions tests/test_user.py::TestUser::test_get_page_views tests/test_user.py::TestUser::test_get_profile tests/test_user.py::TestUser::test_list_bookmarks tests/test_user.py::TestUser::test_list_calendar_events_for_user tests/test_user.py::TestUser::test_list_communication_channels tests/test_user.py::TestUser::test_list_enrollments tests/test_user.py::TestUser::test_list_folders tests/test_user.py::TestUser::test_list_groups tests/test_user.py::TestUser::test_list_observees tests/test_user.py::TestUser::test_list_user_logins tests/test_user.py::TestUser::test_merge_into_id tests/test_user.py::TestUser::test_merge_into_user tests/test_user.py::TestUser::test_remove_observee tests/test_user.py::TestUser::test_show_observee tests/test_user.py::TestUser::test_update_color tests/test_user.py::TestUser::test_update_color_no_hashtag tests/test_user.py::TestUser::test_update_settings tests/test_user.py::TestUser::test_upload tests/test_user.py::TestUser::test_user_files tests/test_user.py::TestUser::test_user_get_assignments tests/test_user.py::TestUserDisplay::test__str__ tests/test_util.py::TestUtil::test_combine_kwargs_empty tests/test_util.py::TestUtil::test_combine_kwargs_multiple_dicts tests/test_util.py::TestUtil::test_combine_kwargs_multiple_mixed tests/test_util.py::TestUtil::test_combine_kwargs_multiple_nested_dicts tests/test_util.py::TestUtil::test_combine_kwargs_nested_dict tests/test_util.py::TestUtil::test_combine_kwargs_single tests/test_util.py::TestUtil::test_combine_kwargs_single_dict tests/test_util.py::TestUtil::test_combine_kwargs_single_generator_empty tests/test_util.py::TestUtil::test_combine_kwargs_single_generator_multiple_items tests/test_util.py::TestUtil::test_combine_kwargs_single_generator_single_item tests/test_util.py::TestUtil::test_combine_kwargs_single_list_empty tests/test_util.py::TestUtil::test_combine_kwargs_single_list_multiple_items tests/test_util.py::TestUtil::test_combine_kwargs_single_list_single_item tests/test_util.py::TestUtil::test_combine_kwargs_super_nested_dict tests/test_util.py::TestUtil::test_combine_kwargs_the_gauntlet tests/test_util.py::TestUtil::test_get_institution_url tests/test_util.py::TestUtil::test_is_multivalued_bool tests/test_util.py::TestUtil::test_is_multivalued_bytes tests/test_util.py::TestUtil::test_is_multivalued_chain tests/test_util.py::TestUtil::test_is_multivalued_dict tests/test_util.py::TestUtil::test_is_multivalued_dict_items tests/test_util.py::TestUtil::test_is_multivalued_dict_iter tests/test_util.py::TestUtil::test_is_multivalued_dict_keys tests/test_util.py::TestUtil::test_is_multivalued_dict_values tests/test_util.py::TestUtil::test_is_multivalued_generator_call tests/test_util.py::TestUtil::test_is_multivalued_generator_expr tests/test_util.py::TestUtil::test_is_multivalued_integer_types tests/test_util.py::TestUtil::test_is_multivalued_list tests/test_util.py::TestUtil::test_is_multivalued_list_iter tests/test_util.py::TestUtil::test_is_multivalued_set tests/test_util.py::TestUtil::test_is_multivalued_set_iter tests/test_util.py::TestUtil::test_is_multivalued_str tests/test_util.py::TestUtil::test_is_multivalued_tuple tests/test_util.py::TestUtil::test_is_multivalued_tuple_iter tests/test_util.py::TestUtil::test_is_multivalued_unicode tests/test_util.py::TestUtil::test_is_multivalued_zip tests/test_util.py::TestUtil::test_obj_or_id_int tests/test_util.py::TestUtil::test_obj_or_id_obj tests/test_util.py::TestUtil::test_obj_or_id_obj_no_id tests/test_util.py::TestUtil::test_obj_or_id_str_invalid tests/test_util.py::TestUtil::test_obj_or_id_str_valid
tests/test_canvas.py::TestCanvas::test_init_deprecate_url_contains_version
canvasapi/util.py canvasapi/canvas.py
canvasapi/util.py canvasapi/canvas.py