Skip to content

Commit 128775b

Browse files
authored
chore: update user-agent string to standardize format (#597)
* [DI-1565] update user agent string format to allow extension and its test cases
1 parent 5011a4b commit 128775b

File tree

3 files changed

+54
-5
lines changed

3 files changed

+54
-5
lines changed

tests/holodeck.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,10 @@ def requests(self):
2828

2929
def add_standard_headers(self, request):
3030
standard_headers = {
31-
'User-Agent': 'twilio-python/{} (Python {})'.format(
31+
'User-Agent': 'twilio-python/{} ({} {}) Python/{}'.format(
3232
__version__,
33+
platform.system(),
34+
platform.machine(),
3335
platform.python_version()),
3436
'X-Twilio-Client': 'python-{}'.format(__version__),
3537
'Accept': 'application/json',

tests/unit/rest/test_client.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import unittest
2+
import platform
23

4+
from twilio import __version__
35
from twilio.rest import (
46
Client,
57
TwilioClient,
@@ -97,3 +99,36 @@ def test_periods_in_query(self):
9799
self.assertEqual(self.client.get_hostname('https://api.twilio.com/path/to/something.json?foo=12.34'),
98100
'https://api.edge.region.twilio.com/path/to/something.json?foo=12.34')
99101

102+
103+
class TestUserAgentClients(unittest.TestCase):
104+
def setUp(self):
105+
self.client = Client('username', 'password')
106+
107+
def tearDown(self):
108+
self.client.http_client.session.close()
109+
110+
def test_set_default_user_agent(self):
111+
self.client.request('GET', 'https://api.twilio.com/')
112+
request_header = self.client.http_client.last_request.headers['User-Agent']
113+
expected_user_agent = 'twilio-python/{} ({} {}) Python/{}'.format(
114+
__version__,
115+
platform.system(),
116+
platform.machine(),
117+
platform.python_version(),
118+
)
119+
self.assertEqual(request_header, expected_user_agent)
120+
121+
def test_set_user_agent_extensions(self):
122+
user_agent_extensions = ['twilio-run/2.0.0-test', 'flex-plugin/3.4.0']
123+
self.client.user_agent_extensions = user_agent_extensions
124+
self.client.request('GET', 'https://api.twilio.com/')
125+
request_header = self.client.http_client.last_request.headers['User-Agent']
126+
expected_user_agent = 'twilio-python/{} ({} {}) Python/{} {} {}'.format(
127+
__version__,
128+
platform.system(),
129+
platform.machine(),
130+
platform.python_version(),
131+
user_agent_extensions[0],
132+
user_agent_extensions[1]
133+
)
134+
self.assertEqual(request_header, expected_user_agent)

twilio/rest/__init__.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ class Client(object):
2222
""" A client for accessing the Twilio API. """
2323

2424
def __init__(self, username=None, password=None, account_sid=None, region=None,
25-
http_client=None, environment=None, edge=None):
25+
http_client=None, environment=None, edge=None,
26+
user_agent_extensions=None):
2627
"""
2728
Initializes the Twilio Client
2829
@@ -33,6 +34,7 @@ def __init__(self, username=None, password=None, account_sid=None, region=None,
3334
:param HttpClient http_client: HttpClient, defaults to TwilioHttpClient
3435
:param dict environment: Environment to look for auth details, defaults to os.environ
3536
:param str edge: Twilio Edge to make requests to, defaults to None
37+
:param list[str] user_agent_extensions: Additions to the user agent string
3638
3739
:returns: Twilio Client
3840
:rtype: twilio.rest.Client
@@ -49,6 +51,8 @@ def __init__(self, username=None, password=None, account_sid=None, region=None,
4951
""" :type : str """
5052
self.region = region or environment.get('TWILIO_REGION')
5153
""" :type : str """
54+
self.user_agent_extensions = user_agent_extensions or []
55+
""" :type : list[str] """
5256

5357
if not self.username or not self.password:
5458
raise TwilioException("Credentials are required to create a TwilioClient")
@@ -113,10 +117,18 @@ def request(self, method, uri, params=None, data=None, headers=None, auth=None,
113117
auth = auth or self.auth
114118
headers = headers or {}
115119

116-
headers['User-Agent'] = 'twilio-python/{} (Python {})'.format(
117-
__version__,
118-
platform.python_version(),
120+
pkg_version = __version__
121+
os_name = platform.system()
122+
os_arch = platform.machine()
123+
python_version = platform.python_version()
124+
headers['User-Agent'] = 'twilio-python/{} ({} {}) Python/{}'.format(
125+
pkg_version,
126+
os_name,
127+
os_arch,
128+
python_version,
119129
)
130+
for extension in self.user_agent_extensions:
131+
headers['User-Agent'] += ' {}'.format(extension)
120132
headers['X-Twilio-Client'] = 'python-{}'.format(__version__)
121133
headers['Accept-Charset'] = 'utf-8'
122134

0 commit comments

Comments
 (0)