Repository: ucfopen/canvasapi

Issue:
try to loop through a PaginatedList of type Course but triggered AttributeError: 'NoneType' object has no attribute 'group'
# Describe the bug
It seems when I try to loop through the `PaginatedList of type Course` and print it out, a traceback error will show up. Like this, see below

Traceback (most recent call last):
  File"C:\Users\qchen\Documents\ITS\Canvas_script\lti_report\generate_term.py", line 51, in <module>
    for i in courses:
File"C:\Users\qchen\AppData\Local\Programs\Python\Python37-32\lib\site packages\canvasapi\paginated_list.py", line 49, in __iter__
    new_elements = self._grow()
File"C:\Users\qchen\AppData\Local\Programs\Python\Python37-32\lib\site-packages\canvasapi\paginated_list.py", line 93, in _grow            
new_elements = self._get_next_page()
File"C:\Users\qchen\AppData\Local\Programs\Python\Python37-32\lib\site-packages\canvasapi\paginated_list.py", line 67, in _get_next_page
re.search(regex,next_link["url"]).group(1) if next_link else None
AttributeError: 'NoneType' object has no attribute 'group'

# To Reproduce

Steps to reproduce the behavior:

1. Go to 'command line'
2. Click on 'run my python script'
my code is like this:
`canvas = Canvas(API_URL, API_KEY)
account=canvas.get_account(147)
courses=account.get_courses(include=['term'])
for i in courses: 
    print(i.term)`

3. See error

# Expected behavior
I want to loop through my list of course and get term information.

# Environment information

<!--(please complete the following information)-->

- Python version (`python --version`): Python 3.7.2
- CanvasAPI version (`pip show canvasapi`): Version: 0.15.0

# Additional context
I can print out the account list but it doesn't work for the course list. After I changed my file for api link nd token, it worked. Then I compare the api link with my previous one, I found there is an extra whitespace at the beginning of my api url. It seems that's the reason why my code doesn't work. 



Discussion:
coveralls: 
[![Coverage Status](https://coveralls.io/builds/31694688/badge)](https://coveralls.io/builds/31694688)

Coverage remained the same at 100.0% when pulling **1a991f2f13db4e887a647d789ef067f389ce17c9 on jessemcbride:issue/370-whitespaces-in-base-url** into **e85c5552b8bd611ab87fbf84ba9d752a86567be8 on ucfopen:develop**.


Patch:
diff --git a/canvasapi/canvas.py b/canvasapi/canvas.py
index 13b7aad..3321e06 100644
--- a/canvasapi/canvas.py
+++ b/canvasapi/canvas.py
@@ -3,6 +3,7 @@ from __future__ import absolute_import, division, print_function, unicode_litera
 import warnings
 
 from canvasapi.account import Account
+from canvasapi.comm_message import CommMessage
 from canvasapi.course import Course
 from canvasapi.course_epub_export import CourseEpubExport
 from canvasapi.current_user import CurrentUser
@@ -14,7 +15,6 @@ from canvasapi.paginated_list import PaginatedList
 from canvasapi.requester import Requester
 from canvasapi.section import Section
 from canvasapi.user import User
-from canvasapi.comm_message import CommMessage
 from canvasapi.util import combine_kwargs, get_institution_url, obj_or_id
 
 
@@ -59,10 +59,10 @@ class Canvas(object):
                 UserWarning,
             )
 
-        # Ensure that the user-supplied access token contains no leading or
-        # trailing spaces that may cause issues when communicating with
-        # the API.
+        # Ensure that the user-supplied access token and base_url contain no leading or
+        # trailing spaces that might cause issues when communicating with the API.
         access_token = access_token.strip()
+        base_url = base_url.strip()
 
         self.__requester = Requester(base_url, access_token)
 


Test patch:
diff --git a/tests/settings.py b/tests/settings.py
index f5dd44f..679cc11 100644
--- a/tests/settings.py
+++ b/tests/settings.py
@@ -6,6 +6,7 @@ BASE_URL_WITH_VERSION = "https://example.com/api/v1/"
 BASE_URL_AS_HTTP = "http://example.com"
 BASE_URL_AS_BLANK = ""
 BASE_URL_AS_INVALID = "example.com"
+BASE_URL_WITH_EXTRA_SPACES = " https://example.com "
 API_KEY = "123"
 
 INVALID_ID = 9001
diff --git a/tests/test_canvas.py b/tests/test_canvas.py
index 77e56be..4256dce 100644
--- a/tests/test_canvas.py
+++ b/tests/test_canvas.py
@@ -12,20 +12,19 @@ from canvasapi import Canvas
 from canvasapi.account import Account
 from canvasapi.appointment_group import AppointmentGroup
 from canvasapi.calendar_event import CalendarEvent
+from canvasapi.comm_message import CommMessage
 from canvasapi.conversation import Conversation
 from canvasapi.course import Course, CourseNickname
 from canvasapi.course_epub_export import CourseEpubExport
 from canvasapi.discussion_topic import DiscussionTopic
-from canvasapi.exceptions import RequiredFieldMissing
+from canvasapi.exceptions import RequiredFieldMissing, ResourceDoesNotExist
 from canvasapi.file import File
 from canvasapi.group import Group, GroupCategory
-from canvasapi.exceptions import ResourceDoesNotExist
 from canvasapi.outcome import Outcome, OutcomeGroup
 from canvasapi.paginated_list import PaginatedList
 from canvasapi.progress import Progress
 from canvasapi.section import Section
 from canvasapi.user import User
-from canvasapi.comm_message import CommMessage
 from tests import settings
 from tests.util import register_uris
 
@@ -75,6 +74,12 @@ class TestCanvas(unittest.TestCase):
         client = Canvas(settings.BASE_URL, " 12345 ")
         self.assertEqual(client._Canvas__requester.access_token, "12345")
 
+    def test_init_strips_extra_spaces_in_base_url(self, m):
+        client = Canvas(settings.BASE_URL_WITH_EXTRA_SPACES, "12345")
+        self.assertEqual(
+            client._Canvas__requester.base_url, settings.BASE_URL_WITH_VERSION
+        )
+
     # create_account()
     def test_create_account(self, m):
         register_uris({"account": ["create"]}, m)