diff --git a/tests/unit/rest/test_client.py b/tests/unit/rest/test_client.py index 9623dc52ad..1043d6dcf8 100644 --- a/tests/unit/rest/test_client.py +++ b/tests/unit/rest/test_client.py @@ -1,7 +1,10 @@ import unittest +import warnings + import aiounittest from mock import AsyncMock, Mock + from twilio.http.response import Response from twilio.rest import Client @@ -18,16 +21,16 @@ def test_set_client_edge_default_region(self): ) def test_set_client_region(self): - self.client.region = "region" + self.client.region = "us1" self.assertEqual( self.client.get_hostname("https://api.twilio.com"), - "https://api.region.twilio.com", + "https://api.us1.twilio.com", ) def test_set_uri_region(self): self.assertEqual( - self.client.get_hostname("https://api.region.twilio.com"), - "https://api.region.twilio.com", + self.client.get_hostname("https://api.us1.twilio.com"), + "https://api.us1.twilio.com", ) def test_set_client_edge_region(self): @@ -75,6 +78,27 @@ def test_periods_in_query(self): "https://api.edge.region.twilio.com/path/to/something.json?foo=12.34", ) + def test_edge_deprecation_warning_when_only_edge_is_set(self): + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter("always") # Ensure all warnings are caught + Client(username="username", password="password", edge="edge") # Trigger the warning + + # Check if a warning was raised + self.assertGreater(len(w), 0) + self.assertTrue(issubclass(w[-1].category, DeprecationWarning)) + self.assertIn("For regional processing, DNS is of format product...twilio.com; otherwise use product.twilio.com.", str(w[-1].message)) + + def test_edge_deprecation_warning_when_only_region_is_set(self): + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter("always") # Ensure all warnings are caught + Client(username="username", password="password", region="us1") # Trigger the warning + + # Check if a warning was raised + self.assertGreater(len(w), 0) + self.assertTrue(issubclass(w[-1].category, DeprecationWarning)) + self.assertIn("For regional processing, DNS is of format product...twilio.com; otherwise use product.twilio.com.", str(w[-1].message)) + + class TestUserAgentClients(unittest.TestCase): def setUp(self): diff --git a/twilio/base/client_base.py b/twilio/base/client_base.py index b16f85bf5b..2fac31b80a 100644 --- a/twilio/base/client_base.py +++ b/twilio/base/client_base.py @@ -1,5 +1,6 @@ import os import platform +import warnings from typing import Dict, List, MutableMapping, Optional, Tuple from urllib.parse import urlparse, urlunparse @@ -12,7 +13,17 @@ class ClientBase(object): """A client for accessing the Twilio API.""" - + region_mappings = { + "au1": "sydney", + "br1": "sao-paulo", + "de1": "frankfurt", + "ie1": "dublin", + "jp1": "tokyo", + "jp2": "osaka", + "sg1": "singapore", + "us1": "ashburn", + "us2": "umatilla" + } def __init__( self, username: Optional[str] = None, @@ -34,7 +45,7 @@ def __init__( :param region: Twilio Region to make requests to, defaults to 'us1' if an edge is provided :param http_client: HttpClient, defaults to TwilioHttpClient :param environment: Environment to look for auth details, defaults to os.environ - :param edge: Twilio Edge to make requests to, defaults to None + :param edge: Twilio Edge to make requests to, defaults to None. :param user_agent_extensions: Additions to the user agent string :param credential_provider: credential provider for authentication method that needs to be used """ @@ -45,7 +56,13 @@ def __init__( """ :type : str """ self.password = password or environment.get("TWILIO_AUTH_TOKEN") """ :type : str """ - self.edge = edge or environment.get("TWILIO_EDGE") + if (edge is not None and region is None) or (region is not None and edge is None): + warnings.warn( + "For regional processing, DNS is of format product...twilio.com; otherwise use product.twilio.com.", + DeprecationWarning, + stacklevel=2 + ) + self.edge = edge or environment.get("TWILIO_EDGE") or (self.region_mappings[region] if region is not None else "") """ :type : str """ self.region = region or environment.get("TWILIO_REGION") """ :type : str """