Skip to content

Commit fb61ac6

Browse files
committed
config mustache
1 parent 7b89177 commit fb61ac6

File tree

2 files changed

+60
-15
lines changed

2 files changed

+60
-15
lines changed

bandwidth/configuration.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -525,8 +525,12 @@ def get_basic_auth_token(self) -> Optional[str]:
525525
return urllib3.util.make_headers(
526526
basic_auth=username + ':' + password
527527
).get('authorization')
528-
528+
529529
def get_access_token(self) -> str:
530+
"""Gets HTTP bearer authentication header (string).
531+
532+
:return: The token for bearer HTTP authentication.
533+
"""
530534
now = int(time.time())
531535
print(f"now: {now}, exp: {self.temp_access_token}, token: {self.temp_access_token_expires_at}")
532536
if self.temp_access_token and self.temp_access_token_expires_at > now + 60:

custom_templates/configuration.mustache

Lines changed: 55 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
{{>partial_header}}
44

55

6+
import time
7+
import base64
68
import copy
79
import http.client as httplib
810
import logging
@@ -11,7 +13,7 @@ from logging import FileHandler
1113
import multiprocessing
1214
{{/async}}
1315
import sys
14-
from typing import Any, Callable, ClassVar, Dict, List, Literal, Optional, TypedDict, Union
16+
from typing import Any, ClassVar, Dict, List, Literal, Optional, TypedDict, Union
1517
from typing_extensions import NotRequired, Self
1618

1719
import urllib3
@@ -167,11 +169,8 @@ class Configuration:
167169
:param username: Username for HTTP basic authentication.
168170
:param password: Password for HTTP basic authentication.
169171
:param access_token: Access token.
170-
:param get_access_token: Function to return a string access token.
171-
The function takes any arguments.
172-
If a function is provided, it will be called every time
173-
an access token is required (i.e. for each request).
174-
This is useful for refreshing expired tokens.
172+
:param client_id: Client ID for OAuth2 authentication.
173+
:param client_secret: Client Secret for OAuth2 authentication.
175174
{{#hasHttpSignatureMethods}}
176175
:param signing_info: Configuration parameters for the HTTP signature security scheme.
177176
Must be an instance of {{{packageName}}}.signing.HttpSigningConfiguration
@@ -191,6 +190,8 @@ class Configuration:
191190
:param retries: Number of retries for API requests.
192191
:param ca_cert_data: verify the peer using concatenated CA certificate data
193192
in PEM (str) or DER (bytes) format.
193+
:param cert_file: the path to a client certificate file, for mTLS.
194+
:param key_file: the path to a client key file, for mTLS.
194195

195196
{{#hasAuthMethods}}
196197
:Example:
@@ -287,7 +288,8 @@ conf = {{{packageName}}}.Configuration(
287288
username: Optional[str]=None,
288289
password: Optional[str]=None,
289290
access_token: Optional[str]=None,
290-
get_access_token: Optional[Callable[..., str]]=None,
291+
client_id: Optional[str]=None,
292+
client_secret: Optional[str]=None,
291293
{{#hasHttpSignatureMethods}}
292294
signing_info: Optional[HttpSigningConfiguration]=None,
293295
{{/hasHttpSignatureMethods}}
@@ -299,6 +301,8 @@ conf = {{{packageName}}}.Configuration(
299301
ssl_ca_cert: Optional[str]=None,
300302
retries: Optional[int] = None,
301303
ca_cert_data: Optional[Union[str, bytes]] = None,
304+
cert_file: Optional[str]=None,
305+
key_file: Optional[str]=None,
302306
*,
303307
debug: Optional[bool] = None,
304308
) -> None:
@@ -344,8 +348,17 @@ conf = {{{packageName}}}.Configuration(
344348
self.access_token = access_token
345349
"""Access token
346350
"""
347-
self.get_access_token = get_access_token
348-
"""Function to return a string access token.
351+
self.client_id = client_id
352+
"""Client ID for OAuth2 authentication
353+
"""
354+
self.client_secret = client_secret
355+
"""Client Secret for OAuth2 authentication
356+
"""
357+
self.temp_access_token = None
358+
"""Temporary access token for OAuth2
359+
"""
360+
self.temp_access_token_expires_at = 0
361+
"""Expiration time of the temporary access token
349362
"""
350363
{{#hasHttpSignatureMethods}}
351364
if signing_info is not None:
@@ -390,10 +403,10 @@ conf = {{{packageName}}}.Configuration(
390403
"""Set this to verify the peer using PEM (str) or DER (bytes)
391404
certificate data.
392405
"""
393-
self.cert_file = None
406+
self.cert_file = cert_file
394407
"""client certificate file
395408
"""
396-
self.key_file = None
409+
self.key_file = key_file
397410
"""client key file
398411
"""
399412
self.assert_hostname = None
@@ -624,6 +637,34 @@ conf = {{{packageName}}}.Configuration(
624637
basic_auth=username + ':' + password
625638
).get('authorization')
626639

640+
def get_access_token(self) -> str:
641+
"""Gets HTTP bearer authentication header (string).
642+
643+
:return: The token for bearer HTTP authentication.
644+
"""
645+
now = int(time.time())
646+
print(f"now: {now}, exp: {self.temp_access_token}, token: {self.temp_access_token_expires_at}")
647+
if self.temp_access_token and self.temp_access_token_expires_at > now + 60:
648+
return self.temp_access_token
649+
else:
650+
print("Fetching new access token")
651+
_bytes = f"{self.client_id}:{self.client_secret}".encode('utf-8')
652+
_encoded_string = base64.b64encode(_bytes).decode('utf-8')
653+
auth_header = f"Basic {_encoded_string}"
654+
resp = urllib3.request(
655+
'POST',
656+
'https://id.bandwidth.com/api/v1/oauth2/token',
657+
headers={
658+
'Authorization': auth_header,
659+
'Content-Type': 'application/x-www-form-urlencoded',
660+
},
661+
body='grant_type=client_credentials'
662+
)
663+
body = resp.json()
664+
self.temp_access_token = body['access_token']
665+
self.temp_access_token_expires_at = now + body['expires_in']
666+
return self.temp_access_token
667+
627668
def auth_settings(self)-> AuthSettings:
628669
"""Gets Auth Settings dict for api client.
629670

@@ -677,14 +718,14 @@ conf = {{{packageName}}}.Configuration(
677718
{{/isBasic}}
678719
{{#isOAuth}}
679720
if self.access_token is not None:
680-
auth['{{name}}'] = {
721+
auth['OAuth2'] = {
681722
'type': 'oauth2',
682723
'in': 'header',
683724
'key': 'Authorization',
684725
'value': 'Bearer ' + self.access_token
685726
}
686-
if self.get_access_token is not None:
687-
auth['{{name}}'] = {
727+
if self.client_id is not None and self.client_secret is not None:
728+
auth['OAuth2'] = {
688729
'type': 'oauth2',
689730
'in': 'header',
690731
'key': 'Authorization',

0 commit comments

Comments
 (0)