From 1e77b0cd3b836423348ae94c2ed926834f9f3957 Mon Sep 17 00:00:00 2001 From: ckoegel Date: Mon, 17 Aug 2026 16:27:37 -0400 Subject: [PATCH 1/2] SWI-12283 Allow Setting Custom Token URL --- bandwidth/configuration.py | 7 ++++++- custom_templates/configuration.mustache | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/bandwidth/configuration.py b/bandwidth/configuration.py index ad32ea05..9d29b5c2 100644 --- a/bandwidth/configuration.py +++ b/bandwidth/configuration.py @@ -152,6 +152,7 @@ class Configuration: :param username: Username for HTTP basic authentication. :param password: Password for HTTP basic authentication. :param access_token: Access token. + :param access_token_url: URL to get access token for OAuth2 authentication. :param client_id: Client ID for OAuth2 authentication. :param client_secret: Client Secret for OAuth2 authentication. :param server_index: Index to servers configuration. @@ -201,6 +202,7 @@ def __init__( username: Optional[str]=None, password: Optional[str]=None, access_token: Optional[str]=None, + access_token_url: Optional[str]=None, client_id: Optional[str]=None, client_secret: Optional[str]=None, server_index: Optional[int]=None, @@ -258,6 +260,9 @@ def __init__( self.access_token = access_token """Access token """ + self.access_token_url = 'https://api.bandwidth.com/api/v1/oauth2/token' if access_token_url is None else access_token_url + """URL to get access token for OAuth2 authentication + """ self.client_id = client_id """Client ID for OAuth2 authentication """ @@ -540,7 +545,7 @@ def get_access_token(self) -> str: auth_header = f"Basic {_encoded_string}" resp = urllib3.request( 'POST', - 'https://api.bandwidth.com/api/v1/oauth2/token', + self.access_token_url, headers={ 'Authorization': auth_header, 'Content-Type': 'application/x-www-form-urlencoded', diff --git a/custom_templates/configuration.mustache b/custom_templates/configuration.mustache index dd059307..63fb11b5 100644 --- a/custom_templates/configuration.mustache +++ b/custom_templates/configuration.mustache @@ -169,6 +169,7 @@ class Configuration: :param username: Username for HTTP basic authentication. :param password: Password for HTTP basic authentication. :param access_token: Access token. + :param access_token_url: URL to get access token for OAuth2 authentication. :param client_id: Client ID for OAuth2 authentication. :param client_secret: Client Secret for OAuth2 authentication. {{#hasHttpSignatureMethods}} @@ -288,6 +289,7 @@ conf = {{{packageName}}}.Configuration( username: Optional[str]=None, password: Optional[str]=None, access_token: Optional[str]=None, + access_token_url: Optional[str]=None, client_id: Optional[str]=None, client_secret: Optional[str]=None, {{#hasHttpSignatureMethods}} @@ -348,6 +350,9 @@ conf = {{{packageName}}}.Configuration( self.access_token = access_token """Access token """ + self.access_token_url = {{#authMethods}}{{#isOAuth}}'{{tokenUrl}}'{{/isOAuth}}{{/authMethods}} if access_token_url is None else access_token_url + """URL to get access token for OAuth2 authentication + """ self.client_id = client_id """Client ID for OAuth2 authentication """ @@ -651,7 +656,7 @@ conf = {{{packageName}}}.Configuration( auth_header = f"Basic {_encoded_string}" resp = urllib3.request( 'POST', - {{#authMethods}}{{#isOAuth}}'{{tokenUrl}}',{{/isOAuth}}{{/authMethods}} + self.access_token_url, headers={ 'Authorization': auth_header, 'Content-Type': 'application/x-www-form-urlencoded', From a7429bd2618516b9d627519469d1b5163e06f986 Mon Sep 17 00:00:00 2001 From: ckoegel Date: Mon, 17 Aug 2026 16:27:46 -0400 Subject: [PATCH 2/2] update unit tests to not hit live oauth url --- test/unit/api/test_calls_api.py | 3 +-- test/unit/api/test_conferences_api.py | 3 +-- test/unit/api/test_endpoints_api.py | 3 +-- test/unit/api/test_media_api.py | 3 +-- test/unit/api/test_messages_api.py | 3 +-- test/unit/api/test_mfa_api.py | 3 +-- test/unit/api/test_multi_channel_api.py | 3 +-- test/unit/api/test_phone_number_lookup_api.py | 3 +-- test/unit/api/test_recordings_api.py | 3 +-- test/unit/api/test_statistics_api.py | 3 +-- test/unit/api/test_toll_free_verification_api.py | 3 +-- test/unit/api/test_transcriptions_api.py | 3 +-- 12 files changed, 12 insertions(+), 24 deletions(-) diff --git a/test/unit/api/test_calls_api.py b/test/unit/api/test_calls_api.py index ee0e4923..e6ea2acc 100644 --- a/test/unit/api/test_calls_api.py +++ b/test/unit/api/test_calls_api.py @@ -38,8 +38,7 @@ class TestCallsApi(unittest.TestCase): @classmethod def setUpClass(cls) -> None: configuration = Configuration( - client_id=BW_CLIENT_ID, - client_secret=BW_CLIENT_SECRET, + access_token='abcd1234', host='http://127.0.0.1:4010', ignore_operation_servers=True ) diff --git a/test/unit/api/test_conferences_api.py b/test/unit/api/test_conferences_api.py index b26f726f..a90dec4f 100644 --- a/test/unit/api/test_conferences_api.py +++ b/test/unit/api/test_conferences_api.py @@ -35,8 +35,7 @@ class TestConferencesApi(unittest.TestCase): @classmethod def setUpClass(cls) -> None: configuration = Configuration( - client_id=BW_CLIENT_ID, - client_secret=BW_CLIENT_SECRET, + access_token='abcd1234', host='http://127.0.0.1:4010', ignore_operation_servers=True ) diff --git a/test/unit/api/test_endpoints_api.py b/test/unit/api/test_endpoints_api.py index 957edb9f..d370737d 100644 --- a/test/unit/api/test_endpoints_api.py +++ b/test/unit/api/test_endpoints_api.py @@ -40,8 +40,7 @@ class TestEndpointsApi(unittest.TestCase): @classmethod def setUpClass(cls) -> None: configuration = Configuration( - client_id=BW_CLIENT_ID, - client_secret=BW_CLIENT_SECRET, + access_token='abcd1234', host='http://127.0.0.1:4010', ignore_operation_servers=True ) diff --git a/test/unit/api/test_media_api.py b/test/unit/api/test_media_api.py index 53632a7a..fe7169a3 100644 --- a/test/unit/api/test_media_api.py +++ b/test/unit/api/test_media_api.py @@ -27,8 +27,7 @@ class TestMediaApi(unittest.TestCase): def setUp(self) -> None: configuration = Configuration( - username=BW_USERNAME, - password=BW_PASSWORD, + access_token='abcd1234', host='http://127.0.0.1:4010', ignore_operation_servers=True ) diff --git a/test/unit/api/test_messages_api.py b/test/unit/api/test_messages_api.py index 74e7b6fd..34493af9 100644 --- a/test/unit/api/test_messages_api.py +++ b/test/unit/api/test_messages_api.py @@ -36,8 +36,7 @@ class TestMessagesApi(unittest.TestCase): def setUp(self) -> None: configuration = Configuration( - username=BW_USERNAME, - password=BW_PASSWORD, + access_token='abcd1234', host='http://127.0.0.1:4010', ignore_operation_servers=True ) diff --git a/test/unit/api/test_mfa_api.py b/test/unit/api/test_mfa_api.py index 06462597..96cd156e 100644 --- a/test/unit/api/test_mfa_api.py +++ b/test/unit/api/test_mfa_api.py @@ -31,8 +31,7 @@ class TestMFAApi(unittest.TestCase): def setUp(self) -> None: configuration = Configuration( - username=BW_USERNAME, - password=BW_PASSWORD, + access_token='abcd1234', host='http://127.0.0.1:4010', ignore_operation_servers=True ) diff --git a/test/unit/api/test_multi_channel_api.py b/test/unit/api/test_multi_channel_api.py index c4bd0022..010ec0e6 100644 --- a/test/unit/api/test_multi_channel_api.py +++ b/test/unit/api/test_multi_channel_api.py @@ -35,8 +35,7 @@ class TestMultiChannelApi(unittest.TestCase): def setUp(self) -> None: configuration = Configuration( - username=BW_USERNAME, - password=BW_PASSWORD, + access_token='abcd1234', host='http://127.0.0.1:4010', ignore_operation_servers=True ) diff --git a/test/unit/api/test_phone_number_lookup_api.py b/test/unit/api/test_phone_number_lookup_api.py index 799358eb..7271c368 100644 --- a/test/unit/api/test_phone_number_lookup_api.py +++ b/test/unit/api/test_phone_number_lookup_api.py @@ -41,8 +41,7 @@ class TestPhoneNumberLookupApi(unittest.TestCase): @classmethod def setUpClass(cls) -> None: configuration = Configuration( - client_id=BW_CLIENT_ID, - client_secret=BW_CLIENT_SECRET, + access_token='abcd1234', host='http://127.0.0.1:4010', ignore_operation_servers=True ) diff --git a/test/unit/api/test_recordings_api.py b/test/unit/api/test_recordings_api.py index ee52c812..4f15102b 100644 --- a/test/unit/api/test_recordings_api.py +++ b/test/unit/api/test_recordings_api.py @@ -37,8 +37,7 @@ class TestRecordingsApi(unittest.TestCase): @classmethod def setUpClass(cls) -> None: configuration = Configuration( - client_id=BW_CLIENT_ID, - client_secret=BW_CLIENT_SECRET, + access_token='abcd1234', host='http://127.0.0.1:4010', ignore_operation_servers=True ) diff --git a/test/unit/api/test_statistics_api.py b/test/unit/api/test_statistics_api.py index 99ee94bd..7d415601 100644 --- a/test/unit/api/test_statistics_api.py +++ b/test/unit/api/test_statistics_api.py @@ -28,8 +28,7 @@ class TestStatisticsApi(unittest.TestCase): @classmethod def setUpClass(cls) -> None: configuration = Configuration( - client_id=BW_CLIENT_ID, - client_secret=BW_CLIENT_SECRET, + access_token='abcd1234', host='http://127.0.0.1:4010', ignore_operation_servers=True ) diff --git a/test/unit/api/test_toll_free_verification_api.py b/test/unit/api/test_toll_free_verification_api.py index 0a2dd3be..0d3fd6bc 100644 --- a/test/unit/api/test_toll_free_verification_api.py +++ b/test/unit/api/test_toll_free_verification_api.py @@ -46,8 +46,7 @@ class TestTollFreeVerificationApi(unittest.TestCase): @classmethod def setUpClass(cls) -> None: configuration = Configuration( - client_id=BW_CLIENT_ID, - client_secret=BW_CLIENT_SECRET, + access_token='abcd1234', host='http://127.0.0.1:4010', ignore_operation_servers=True ) diff --git a/test/unit/api/test_transcriptions_api.py b/test/unit/api/test_transcriptions_api.py index 83a7150b..c4c78984 100644 --- a/test/unit/api/test_transcriptions_api.py +++ b/test/unit/api/test_transcriptions_api.py @@ -32,8 +32,7 @@ class TestTranscriptionsApi(unittest.TestCase): @classmethod def setUpClass(cls) -> None: configuration = Configuration( - client_id=BW_CLIENT_ID, - client_secret=BW_CLIENT_SECRET, + access_token='abcd1234', host='http://127.0.0.1:4010', ignore_operation_servers=True )