Skip to content

Commit d91207d

Browse files
committed
Merge branch 'main' of https://github.com/Bandwidth/python-sdk into SWI-9203
2 parents 6fdb60c + 79cb63e commit d91207d

39 files changed

+1477
-255
lines changed

.github/workflows/deploy.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ jobs:
1313
BW_ACCOUNT_ID: ${{ secrets.BW_ACCOUNT_ID }}
1414
BW_USERNAME: ${{ secrets.BW_USERNAME }}
1515
BW_PASSWORD: ${{ secrets.BW_PASSWORD }}
16+
BW_CLIENT_ID: ${{ secrets.BW_CLIENT_ID }}
17+
BW_CLIENT_SECRET: ${{ secrets.BW_CLIENT_SECRET }}
1618
BW_USERNAME_FORBIDDEN: ${{ secrets.BW_USERNAME_FORBIDDEN }}
1719
BW_PASSWORD_FORBIDDEN: ${{ secrets.BW_PASSWORD_FORBIDDEN }}
1820
BW_VOICE_APPLICATION_ID: ${{ secrets.BW_VOICE_APPLICATION_ID }}

.github/workflows/test-pr.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ env:
1313
BW_ACCOUNT_ID: ${{ secrets.BW_ACCOUNT_ID }}
1414
BW_USERNAME: ${{ secrets.BW_USERNAME }}
1515
BW_PASSWORD: ${{ secrets.BW_PASSWORD }}
16+
BW_CLIENT_ID: ${{ secrets.BW_CLIENT_ID }}
17+
BW_CLIENT_SECRET: ${{ secrets.BW_CLIENT_SECRET }}
1618
BW_USERNAME_FORBIDDEN: ${{ secrets.BW_USERNAME_FORBIDDEN }}
1719
BW_PASSWORD_FORBIDDEN: ${{ secrets.BW_PASSWORD_FORBIDDEN }}
1820
BW_VOICE_APPLICATION_ID: ${{ secrets.BW_VOICE_APPLICATION_ID }}

.github/workflows/test-smoke.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ env:
2727
OPERATING_SYSTEM: ubuntu
2828
BW_USERNAME: ${{ secrets.BW_USERNAME }}
2929
BW_PASSWORD: ${{ secrets.BW_PASSWORD }}
30+
BW_CLIENT_ID: ${{ secrets.BW_CLIENT_ID }}
31+
BW_CLIENT_SECRET: ${{ secrets.BW_CLIENT_SECRET }}
3032
BW_USERNAME_FORBIDDEN: ${{ secrets.BW_USERNAME_FORBIDDEN }}
3133
BW_PASSWORD_FORBIDDEN: ${{ secrets.BW_PASSWORD_FORBIDDEN }}
3234
USER_NUMBER: ${{ secrets.USER_NUMBER }}

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,11 @@ configuration = bandwidth.Configuration(
7373
password = os.environ["PASSWORD"]
7474
)
7575

76-
configuration.access_token = os.environ["ACCESS_TOKEN"]
76+
# Configure your client ID and secret for OAuth
77+
configuration = bandwidth.Configuration(
78+
client_id = os.environ["CLIENT_ID"],
79+
client_secret = os.environ["CLIENT_SECRET"]
80+
)
7781

7882

7983
# Enter a context with an instance of the API client

bandwidth.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ info:
88
99
version: 1.0.0
1010
security:
11+
- OAuth2: []
1112
- Basic: []
1213
- OAuth2: []
1314
tags:

bandwidth/configuration.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
""" # noqa: E501
1414

1515

16+
import time
17+
import base64
1618
import copy
1719
import http.client as httplib
1820
import logging
@@ -150,6 +152,8 @@ class Configuration:
150152
:param username: Username for HTTP basic authentication.
151153
:param password: Password for HTTP basic authentication.
152154
:param access_token: Access token.
155+
:param client_id: Client ID for OAuth2 authentication.
156+
:param client_secret: Client Secret for OAuth2 authentication.
153157
:param server_index: Index to servers configuration.
154158
:param server_variables: Mapping with string values to replace variables in
155159
templated server configuration. The validation of enums is performed for
@@ -197,6 +201,8 @@ def __init__(
197201
username: Optional[str]=None,
198202
password: Optional[str]=None,
199203
access_token: Optional[str]=None,
204+
client_id: Optional[str]=None,
205+
client_secret: Optional[str]=None,
200206
server_index: Optional[int]=None,
201207
server_variables: Optional[ServerVariablesT]=None,
202208
server_operation_index: Optional[Dict[int, int]]=None,
@@ -252,6 +258,18 @@ def __init__(
252258
self.access_token = access_token
253259
"""Access token
254260
"""
261+
self.client_id = client_id
262+
"""Client ID for OAuth2 authentication
263+
"""
264+
self.client_secret = client_secret
265+
"""Client Secret for OAuth2 authentication
266+
"""
267+
self.temp_access_token = None
268+
"""Temporary access token for OAuth2
269+
"""
270+
self.temp_access_token_expiration = 0
271+
"""Expiration time of the temporary access token
272+
"""
255273
self.logger = {}
256274
"""Logging Settings
257275
"""
@@ -508,6 +526,32 @@ def get_basic_auth_token(self) -> Optional[str]:
508526
basic_auth=username + ':' + password
509527
).get('authorization')
510528

529+
def get_access_token(self) -> str:
530+
"""Gets HTTP bearer authentication header (string).
531+
532+
:return: The token for bearer HTTP authentication.
533+
"""
534+
now = int(time.time())
535+
if self.temp_access_token and self.temp_access_token_expiration > now + 60:
536+
return self.temp_access_token
537+
else:
538+
_bytes = f"{self.client_id}:{self.client_secret}".encode('utf-8')
539+
_encoded_string = base64.b64encode(_bytes).decode('utf-8')
540+
auth_header = f"Basic {_encoded_string}"
541+
resp = urllib3.request(
542+
'POST',
543+
'https://api.bandwidth.com/api/v1/oauth2/token',
544+
headers={
545+
'Authorization': auth_header,
546+
'Content-Type': 'application/x-www-form-urlencoded',
547+
},
548+
body='grant_type=client_credentials'
549+
)
550+
body = resp.json()
551+
self.temp_access_token = body['access_token']
552+
self.temp_access_token_expiration = now + body['expires_in']
553+
return self.temp_access_token
554+
511555
def auth_settings(self)-> AuthSettings:
512556
"""Gets Auth Settings dict for api client.
513557
@@ -528,6 +572,13 @@ def auth_settings(self)-> AuthSettings:
528572
'key': 'Authorization',
529573
'value': 'Bearer ' + self.access_token
530574
}
575+
if self.client_id is not None and self.client_secret is not None:
576+
auth['OAuth2'] = {
577+
'type': 'oauth2',
578+
'in': 'header',
579+
'key': 'Authorization',
580+
'value': 'Bearer ' + self.get_access_token(),
581+
}
531582
return auth
532583

533584
def to_debug_report(self) -> str:

0 commit comments

Comments
 (0)