77from twilio .http import HttpClient
88from twilio .http .http_client import TwilioHttpClient
99from twilio .http .response import Response
10- from twilio .auth_strategy .auth_type import AuthType
1110from twilio .credential .credential_provider import CredentialProvider
1211
1312
@@ -88,27 +87,26 @@ def request(
8887
8988 :returns: Response from the Twilio API
9089 """
91-
9290 headers = self .get_headers (method , headers )
9391
9492 ##If credential provider is provided by user, get the associated auth strategy
9593 ##Using the auth strategy, fetch the auth string and set it to authorization header
9694 if self .credential_provider :
95+
9796 auth_strategy = self .credential_provider .to_auth_strategy ()
9897 headers ["Authorization" ] = auth_strategy .get_auth_string ()
9998 elif self .username is not None and self .password is not None :
10099 auth = self .get_auth (auth )
101100 else :
102101 auth = None
103102
104-
105103 uri = self .get_hostname (uri )
106-
104+ filtered_data = self . copy_non_none_values ( data )
107105 return self .http_client .request (
108106 method ,
109107 uri ,
110108 params = params ,
111- data = data ,
109+ data = filtered_data ,
112110 headers = headers ,
113111 auth = auth ,
114112 timeout = timeout ,
@@ -147,7 +145,6 @@ async def request_async(
147145 "http_client must be asynchronous to support async API requests"
148146 )
149147
150-
151148 headers = self .get_headers (method , headers )
152149
153150 ##If credential provider is provided by user, get the associated auth strategy
@@ -162,18 +159,25 @@ async def request_async(
162159 auth = None
163160
164161 uri = self .get_hostname (uri )
165-
162+ filtered_data = self . copy_non_none_values ( data )
166163 return await self .http_client .request (
167164 method ,
168165 uri ,
169166 params = params ,
170- data = data ,
167+ data = filtered_data ,
171168 headers = headers ,
172169 auth = auth ,
173170 timeout = timeout ,
174171 allow_redirects = allow_redirects ,
175172 )
176173
174+ def copy_non_none_values (self , data ):
175+ if isinstance (data , dict ):
176+ return {k : self .copy_non_none_values (v ) for k , v in data .items () if v is not None }
177+ elif isinstance (data , list ):
178+ return [self .copy_non_none_values (item ) for item in data if item is not None ]
179+ return data
180+
177181 def get_auth (self , auth : Optional [Tuple [str , str ]]) -> Tuple [str , str ]:
178182 """
179183 Get the request authentication object
@@ -252,6 +256,20 @@ def get_hostname(self, uri: str) -> str:
252256 )
253257 return str (urlunparse (parsed_url ))
254258
259+ def remove_nulls (self , data ):
260+ res = {}
261+ for key , sub_dict in data .items ():
262+ temp_dict = {}
263+ if type (sub_dict ) != str and sub_dict is not None :
264+ for sub_key , sub_value in sub_dict .items ():
265+ if sub_value is not None :
266+ temp_dict [sub_key ] = sub_value
267+ if type (sub_dict ) == str :
268+ temp_dict = sub_dict
269+ if temp_dict :
270+ res [key ] = temp_dict
271+ return res
272+
255273 def __repr__ (self ) -> str :
256274 """
257275 Provide a friendly representation
0 commit comments