88from .messages import Messages
99from .number_insight import NumberInsight
1010from .number_management import Numbers
11+ from .proactive_connect import ProactiveConnect
1112from .redact import Redact
1213from .short_codes import ShortCodes
1314from .sms import Sms
@@ -102,6 +103,7 @@ def __init__(
102103 self ._host = "rest.nexmo.com"
103104 self ._api_host = "api.nexmo.com"
104105 self ._meetings_api_host = "api-eu.vonage.com/beta/meetings"
106+ self ._proactive_connect_host = "api-eu.vonage.com"
105107
106108 user_agent = f"vonage-python/{ vonage .__version__ } python/{ python_version ()} "
107109
@@ -116,6 +118,7 @@ def __init__(
116118 self .messages = Messages (self )
117119 self .number_insight = NumberInsight (self )
118120 self .numbers = Numbers (self )
121+ self .proactive_connect = ProactiveConnect (self )
119122 self .short_codes = ShortCodes (self )
120123 self .sms = Sms (self )
121124 self .subaccounts = Subaccounts (self )
@@ -152,6 +155,12 @@ def meetings_api_host(self, value=None):
152155 else :
153156 self ._meetings_api_host = value
154157
158+ def proactive_connect_host (self , value = None ):
159+ if value is None :
160+ return self ._proactive_connect_host
161+ else :
162+ self ._proactive_connect_host = value
163+
155164 def auth (self , params = None , ** kwargs ):
156165 self ._jwt_claims = params or kwargs
157166
@@ -198,12 +207,25 @@ def get(self, host, request_uri, params=None, auth_type=None):
198207 f'Invalid authentication type. Must be one of "jwt", "header" or "params".'
199208 )
200209
201- logger .debug (f"GET to { repr (uri )} with params { repr (params )} , headers { repr (self ._request_headers )} " )
210+ logger .debug (
211+ f"GET to { repr (uri )} with params { repr (params )} , headers { repr (self ._request_headers )} "
212+ )
202213 return self .parse (
203- host , self .session .get (uri , params = params , headers = self ._request_headers , timeout = self .timeout )
214+ host ,
215+ self .session .get (
216+ uri , params = params , headers = self ._request_headers , timeout = self .timeout
217+ ),
204218 )
205219
206- def post (self , host , request_uri , params , auth_type = None , body_is_json = True , supports_signature_auth = False ):
220+ def post (
221+ self ,
222+ host ,
223+ request_uri ,
224+ params ,
225+ auth_type = None ,
226+ body_is_json = True ,
227+ supports_signature_auth = False ,
228+ ):
207229 """
208230 Low-level method to make a post request to an API server.
209231 This method automatically adds authentication, picking the first applicable authentication method from the following:
@@ -229,14 +251,22 @@ def post(self, host, request_uri, params, auth_type=None, body_is_json=True, sup
229251 f'Invalid authentication type. Must be one of "jwt", "header" or "params".'
230252 )
231253
232- logger .debug (f"POST to { repr (uri )} with params { repr (params )} , headers { repr (self ._request_headers )} " )
254+ logger .debug (
255+ f"POST to { repr (uri )} with params { repr (params )} , headers { repr (self ._request_headers )} "
256+ )
233257 if body_is_json :
234258 return self .parse (
235- host , self .session .post (uri , json = params , headers = self ._request_headers , timeout = self .timeout )
259+ host ,
260+ self .session .post (
261+ uri , json = params , headers = self ._request_headers , timeout = self .timeout
262+ ),
236263 )
237264 else :
238265 return self .parse (
239- host , self .session .post (uri , data = params , headers = self ._request_headers , timeout = self .timeout )
266+ host ,
267+ self .session .post (
268+ uri , data = params , headers = self ._request_headers , timeout = self .timeout
269+ ),
240270 )
241271
242272 def put (self , host , request_uri , params , auth_type = None ):
@@ -252,9 +282,14 @@ def put(self, host, request_uri, params, auth_type=None):
252282 f'Invalid authentication type. Must be one of "jwt", "header" or "params".'
253283 )
254284
255- logger .debug (f"PUT to { repr (uri )} with params { repr (params )} , headers { repr (self ._request_headers )} " )
285+ logger .debug (
286+ f"PUT to { repr (uri )} with params { repr (params )} , headers { repr (self ._request_headers )} "
287+ )
256288 # All APIs that currently use put methods require a json-formatted body so don't need to check this
257- return self .parse (host , self .session .put (uri , json = params , headers = self ._request_headers , timeout = self .timeout ))
289+ return self .parse (
290+ host ,
291+ self .session .put (uri , json = params , headers = self ._request_headers , timeout = self .timeout ),
292+ )
258293
259294 def patch (self , host , request_uri , params , auth_type = None ):
260295 uri = f"https://{ host } { request_uri } "
@@ -267,7 +302,9 @@ def patch(self, host, request_uri, params, auth_type=None):
267302 else :
268303 raise InvalidAuthenticationTypeError (f"""Invalid authentication type.""" )
269304
270- logger .debug (f"PATCH to { repr (uri )} with params { repr (params )} , headers { repr (self ._request_headers )} " )
305+ logger .debug (
306+ f"PATCH to { repr (uri )} with params { repr (params )} , headers { repr (self ._request_headers )} "
307+ )
271308 # Only newer APIs (that expect json-bodies) currently use this method, so we will always send a json-formatted body
272309 return self .parse (host , self .session .patch (uri , json = params , headers = self ._request_headers ))
273310
@@ -288,7 +325,10 @@ def delete(self, host, request_uri, params=None, auth_type=None):
288325 if params is not None :
289326 logger .debug (f"DELETE call has params { repr (params )} " )
290327 return self .parse (
291- host , self .session .delete (uri , headers = self ._request_headers , timeout = self .timeout , params = params )
328+ host ,
329+ self .session .delete (
330+ uri , headers = self ._request_headers , timeout = self .timeout , params = params
331+ ),
292332 )
293333
294334 def parse (self , host , response : Response ):
@@ -322,25 +362,33 @@ def parse(self, host, response: Response):
322362 title = error_data ["title" ]
323363 detail = error_data ["detail" ]
324364 type = error_data ["type" ]
325- message = f"{ title } : { detail } ({ type } )"
365+ message = f"{ title } : { detail } ({ type } ){ self . _add_individual_errors ( error_data ) } "
326366 elif 'status' in error_data and 'message' in error_data and 'name' in error_data :
327- message = f'Status Code { error_data [ "status" ] } : { error_data [ "name" ] } : { error_data [ "message" ] } '
328- if 'errors' in error_data :
329- for error in error_data [ 'errors' ]:
330- message += f', error: { error } '
367+ message = (
368+ f'Status Code { error_data [ "status" ] } : { error_data [ "name" ] } : { error_data [ "message" ] } '
369+ f' { self . _add_individual_errors ( error_data ) } '
370+ )
331371 else :
332372 message = error_data
333373 except JSONDecodeError :
334374 pass
335375 raise ClientError (message )
376+
336377 elif 500 <= response .status_code < 600 :
337378 logger .warning (f"Server error: { response .status_code } { repr (response .content )} " )
338379 message = f"{ response .status_code } response from { host } "
339380 raise ServerError (message )
340381
382+ def _add_individual_errors (self , error_data ):
383+ message = ''
384+ if 'errors' in error_data :
385+ for error in error_data ["errors" ]:
386+ message += f"\n Error: { error } "
387+ return message
388+
341389 def _create_jwt_auth_string (self ):
342390 return b"Bearer " + self ._generate_application_jwt ()
343-
391+
344392 def _generate_application_jwt (self ):
345393 try :
346394 return self ._jwt_client .generate_application_jwt (self ._jwt_claims )
0 commit comments