From 729d92209f28cb728a1f6e50999abd4d4ae0f257 Mon Sep 17 00:00:00 2001 From: cchua Date: Thu, 31 Mar 2022 16:29:06 -0600 Subject: [PATCH 1/5] [DI-1565] update user agent string format to allow extension and its test cases --- tests/holodeck.py | 4 +++- tests/unit/rest/test_client.py | 36 ++++++++++++++++++++++++++++++++++ twilio/rest/__init__.py | 20 +++++++++++++++---- 3 files changed, 55 insertions(+), 5 deletions(-) diff --git a/tests/holodeck.py b/tests/holodeck.py index b0390a3064..aea29f7a14 100644 --- a/tests/holodeck.py +++ b/tests/holodeck.py @@ -28,8 +28,10 @@ def requests(self): def add_standard_headers(self, request): standard_headers = { - 'User-Agent': 'twilio-python/{} (Python {})'.format( + 'User-Agent': 'twilio-python/{} ({} {}) Python/{}'.format( __version__, + platform.system(), + platform.machine(), platform.python_version()), 'X-Twilio-Client': 'python-{}'.format(__version__), 'Accept': 'application/json', diff --git a/tests/unit/rest/test_client.py b/tests/unit/rest/test_client.py index c4aa70f359..e814fe8f5d 100644 --- a/tests/unit/rest/test_client.py +++ b/tests/unit/rest/test_client.py @@ -1,5 +1,7 @@ import unittest +import platform +from twilio import __version__ from twilio.rest import ( Client, TwilioClient, @@ -97,3 +99,37 @@ def test_periods_in_query(self): self.assertEqual(self.client.get_hostname('https://api.twilio.com/path/to/something.json?foo=12.34'), 'https://api.edge.region.twilio.com/path/to/something.json?foo=12.34') + +class TestUserAgentClients(unittest.TestCase): + + def setUp(self): + self.client = Client('username', 'password') + + def tearDown(self): + self.client.http_client.session.close() + + def test_set_default_user_agent(self): + self.client.request('GET', 'https://api.twilio.com/') + request_header = self.client.http_client.last_request.headers['User-Agent'] + expected_user_agent = 'twilio-python/{} ({} {}) Python/{}'.format( + __version__, + platform.system(), + platform.machine(), + platform.python_version(), + ) + self.assertEqual(request_header, expected_user_agent) + + def test_set_user_agent_extensions(self): + user_agent_extensions = ['twilio-run/2.0.0-test', 'flex-plugin/3.4.0'] + self.client.user_agent_extensions = user_agent_extensions + self.client.request('GET', 'https://api.twilio.com/') + request_header = self.client.http_client.last_request.headers['User-Agent'] + expected_user_agent = 'twilio-python/{} ({} {}) Python/{} {} {}'.format( + __version__, + platform.system(), + platform.machine(), + platform.python_version(), + user_agent_extensions[0], + user_agent_extensions[1] + ) + self.assertEqual(request_header, expected_user_agent) diff --git a/twilio/rest/__init__.py b/twilio/rest/__init__.py index 7a80481c79..635c2f56e1 100644 --- a/twilio/rest/__init__.py +++ b/twilio/rest/__init__.py @@ -22,7 +22,8 @@ class Client(object): """ A client for accessing the Twilio API. """ def __init__(self, username=None, password=None, account_sid=None, region=None, - http_client=None, environment=None, edge=None): + http_client=None, environment=None, edge=None, + user_agent_extensions=None): """ Initializes the Twilio Client @@ -33,6 +34,7 @@ def __init__(self, username=None, password=None, account_sid=None, region=None, :param HttpClient http_client: HttpClient, defaults to TwilioHttpClient :param dict environment: Environment to look for auth details, defaults to os.environ :param str edge: Twilio Edge to make requests to, defaults to None + :param list[str] user_agent_extensions: Additions to the user agent string :returns: Twilio Client :rtype: twilio.rest.Client @@ -49,6 +51,8 @@ def __init__(self, username=None, password=None, account_sid=None, region=None, """ :type : str """ self.region = region or environment.get('TWILIO_REGION') """ :type : str """ + self.user_agent_extensions = user_agent_extensions or [] + """ :type : list[str] """ if not self.username or not self.password: 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, auth = auth or self.auth headers = headers or {} - headers['User-Agent'] = 'twilio-python/{} (Python {})'.format( - __version__, - platform.python_version(), + pkg_version = __version__ + os_name = platform.system() + os_arch = platform.machine() + python_version = platform.python_version() + headers['User-Agent'] = 'twilio-python/{} ({} {}) Python/{}'.format( + pkg_version, + os_name, + os_arch, + python_version, ) + for extension in self.user_agent_extensions: + headers['User-Agent'] += ' {}'.format(extension) headers['X-Twilio-Client'] = 'python-{}'.format(__version__) headers['Accept-Charset'] = 'utf-8' From 3fc4fc8bbc440efa77a2758ecd4a114bf13f8bf3 Mon Sep 17 00:00:00 2001 From: cchua Date: Thu, 31 Mar 2022 16:59:58 -0600 Subject: [PATCH 2/5] [DI-1565] update test case --- tests/unit/rest/test_client.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/unit/rest/test_client.py b/tests/unit/rest/test_client.py index e814fe8f5d..f749ed7b8e 100644 --- a/tests/unit/rest/test_client.py +++ b/tests/unit/rest/test_client.py @@ -101,7 +101,6 @@ def test_periods_in_query(self): class TestUserAgentClients(unittest.TestCase): - def setUp(self): self.client = Client('username', 'password') From ac049bf01de5729b618c006e1efe493e8d4baae9 Mon Sep 17 00:00:00 2001 From: cchua Date: Fri, 1 Apr 2022 11:30:33 -0600 Subject: [PATCH 3/5] [DI-1565] update deepsource config test pattern --- .deepsource.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.deepsource.toml b/.deepsource.toml index a352c02e4c..5941b50744 100644 --- a/.deepsource.toml +++ b/.deepsource.toml @@ -10,7 +10,8 @@ exclude_patterns = [ ] test_patterns = [ - 'tests/**' + 'tests/**', + 'test_*.py' ] [[analyzers]] From ec3a59acc2af25f61106335a233a633c52153a05 Mon Sep 17 00:00:00 2001 From: cchua Date: Fri, 1 Apr 2022 12:19:40 -0600 Subject: [PATCH 4/5] [DI-1565] undo changes in deepsource config file --- .deepsource.toml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.deepsource.toml b/.deepsource.toml index 5941b50744..a352c02e4c 100644 --- a/.deepsource.toml +++ b/.deepsource.toml @@ -10,8 +10,7 @@ exclude_patterns = [ ] test_patterns = [ - 'tests/**', - 'test_*.py' + 'tests/**' ] [[analyzers]] From 714de592a5984771f0fa24f5195a718d54e8cf9f Mon Sep 17 00:00:00 2001 From: cchua Date: Tue, 5 Apr 2022 16:35:09 -0600 Subject: [PATCH 5/5] modify test cases to test for format --- tests/unit/rest/test_client.py | 25 ++++++------------------- 1 file changed, 6 insertions(+), 19 deletions(-) diff --git a/tests/unit/rest/test_client.py b/tests/unit/rest/test_client.py index f749ed7b8e..3f77d39b18 100644 --- a/tests/unit/rest/test_client.py +++ b/tests/unit/rest/test_client.py @@ -110,25 +110,12 @@ def tearDown(self): def test_set_default_user_agent(self): self.client.request('GET', 'https://api.twilio.com/') request_header = self.client.http_client.last_request.headers['User-Agent'] - expected_user_agent = 'twilio-python/{} ({} {}) Python/{}'.format( - __version__, - platform.system(), - platform.machine(), - platform.python_version(), - ) - self.assertEqual(request_header, expected_user_agent) + self.assertRegex(request_header, r'^twilio-python\/[0-9.]+\s\(\w+\s\w+\)\sPython\/[^\s]+$') def test_set_user_agent_extensions(self): - user_agent_extensions = ['twilio-run/2.0.0-test', 'flex-plugin/3.4.0'] - self.client.user_agent_extensions = user_agent_extensions + expected_user_agent_extensions = ['twilio-run/2.0.0-test', 'flex-plugin/3.4.0'] + self.client.user_agent_extensions = expected_user_agent_extensions self.client.request('GET', 'https://api.twilio.com/') - request_header = self.client.http_client.last_request.headers['User-Agent'] - expected_user_agent = 'twilio-python/{} ({} {}) Python/{} {} {}'.format( - __version__, - platform.system(), - platform.machine(), - platform.python_version(), - user_agent_extensions[0], - user_agent_extensions[1] - ) - self.assertEqual(request_header, expected_user_agent) + user_agent_headers = self.client.http_client.last_request.headers['User-Agent'] + user_agent_extensions = user_agent_headers.split(" ")[-len(expected_user_agent_extensions):] + self.assertEqual(user_agent_extensions, expected_user_agent_extensions)