Skip to content
This repository was archived by the owner on Sep 6, 2025. It is now read-only.

Commit be741f2

Browse files
Add timeout of 30 seconds to all requests (#18)
* Add timeout of 30 seconds
1 parent 218314c commit be741f2

2 files changed

Lines changed: 91 additions & 51 deletions

File tree

crossengage/client.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,8 @@ def batch_process(self, delete_list=[], update_list=[]):
301301
r = self.requests.post(
302302
self.request_url,
303303
data=json.dumps(payload),
304-
headers=self.default_headers
304+
headers=self.default_headers,
305+
timeout=30
305306
)
306307

307308
return r.status_code, r.json()
@@ -322,7 +323,7 @@ def batch_process_async(self, delete_list=[], update_list=[]):
322323
'deleted': delete_list,
323324
}
324325

325-
r = self.requests.post(self.request_url, data=json.dumps(payload), headers=headers)
326+
r = self.requests.post(self.request_url, data=json.dumps(payload), headers=headers, timeout=30)
326327

327328
return r.status_code, r.json()
328329

@@ -337,7 +338,7 @@ def track_user_task(self, tracking_id):
337338
headers = update_dict(self.default_headers, {self.API_VERSION_HEADER: self.API_VERSIONS["v2"]})
338339
self.request_url = "{0}/{1}/{2}".format(self.API_URL, self.TRACK_USER_TASK_ENDPOINT, tracking_id)
339340

340-
r = self.requests.get(self.request_url, headers=headers)
341+
r = self.requests.get(self.request_url, headers=headers, timeout=30)
341342

342343
try:
343344
body = r.json()
@@ -350,16 +351,16 @@ def __create_request(self, payload, request_type, version):
350351
headers = update_dict(self.default_headers, {self.API_VERSION_HEADER: self.API_VERSIONS[version]})
351352
try:
352353
if request_type == self.REQUEST_PUT:
353-
r = self.requests.put(self.request_url, data=json.dumps(payload), headers=headers)
354+
r = self.requests.put(self.request_url, data=json.dumps(payload), headers=headers, timeout=30)
354355

355356
if request_type == self.REQUEST_GET:
356-
r = self.requests.get(self.request_url, headers=headers)
357+
r = self.requests.get(self.request_url, headers=headers, timeout=30)
357358

358359
if request_type == self.REQUEST_POST:
359-
r = self.requests.post(self.request_url, data=json.dumps(payload), headers=headers)
360+
r = self.requests.post(self.request_url, data=json.dumps(payload), headers=headers, timeout=30)
360361

361362
if request_type == self.REQUEST_DELETE:
362-
r = self.requests.delete(self.request_url, data=json.dumps(payload), headers=headers)
363+
r = self.requests.delete(self.request_url, data=json.dumps(payload), headers=headers, timeout=30)
363364

364365
response = {}
365366
if r.text != '':

tests/test_client.py

Lines changed: 83 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,16 @@ def __init__(self):
1313
self.text = 'Some text'
1414
self.request = Mock()
1515

16-
def put(self, request_url, data, headers):
16+
def put(self, request_url, data, headers, timeout):
1717
return self
1818

19-
def delete(self, request_url, data, headers):
19+
def delete(self, request_url, data, headers, timeout):
2020
return self
2121

22-
def post(self, request_url, data, headers):
22+
def post(self, request_url, data, headers, timeout):
2323
return self
2424

25-
def get(self, request_url, headers):
25+
def get(self, request_url, headers, timeout):
2626
return self
2727

2828
@staticmethod
@@ -34,7 +34,7 @@ class DummyRequestException(object):
3434
def __init__(self):
3535
self.status_code = codes.ok
3636

37-
def put(self, request_url, data, headers):
37+
def put(self, request_url, data, headers, timeout):
3838
raise RequestException('Something went wrong')
3939

4040
@staticmethod
@@ -92,7 +92,8 @@ def test_get_user(self):
9292

9393
requests.get.assert_called_once_with(
9494
self.client.request_url,
95-
headers=self.default_headers_api_v2
95+
headers=self.default_headers_api_v2,
96+
timeout=30
9697
)
9798
self.assertEqual(expected_response, result)
9899

@@ -143,7 +144,8 @@ def test_update_users_bulk(self):
143144
'X-XNG-AuthToken': 'SOME_TOKEN',
144145
'X-XNG-ApiVersion': '1',
145146
'Content-Type': 'application/json',
146-
}
147+
},
148+
timeout=30
147149
)
148150

149151
self.assertEqual(response['status_code'], codes.ok)
@@ -176,7 +178,8 @@ def test_update_users_bulk_bad_request(self):
176178
'X-XNG-AuthToken': 'SOME_TOKEN',
177179
'X-XNG-ApiVersion': '1',
178180
'Content-Type': 'application/json',
179-
}
181+
},
182+
timeout=30
180183
)
181184

182185
self.assertEqual(response['status_code'], codes.bad_request)
@@ -299,11 +302,16 @@ def test_send_events_with_user_id(self):
299302

300303
response = self.client.send_events(user_id='some_id', business_unit='de', events=events)
301304

302-
requests.post.assert_called_once_with(self.CROSSENGAGE_URL + 'events', data=json.dumps(payload), headers={
303-
'X-XNG-AuthToken': 'SOME_TOKEN',
304-
'X-XNG-ApiVersion': '1',
305-
'Content-Type': 'application/json',
306-
})
305+
requests.post.assert_called_once_with(
306+
self.CROSSENGAGE_URL + 'events',
307+
data=json.dumps(payload),
308+
headers={
309+
'X-XNG-AuthToken': 'SOME_TOKEN',
310+
'X-XNG-ApiVersion': '1',
311+
'Content-Type': 'application/json',
312+
},
313+
timeout=30
314+
)
307315

308316
self.assertEqual(response['status_code'], codes.accepted)
309317

@@ -323,11 +331,16 @@ def test_send_events_with_email(self):
323331

324332
response = self.client.send_events(email='email@sample.com', events=events)
325333

326-
requests.post.assert_called_once_with(self.CROSSENGAGE_URL + 'events', data=json.dumps(payload), headers={
327-
'X-XNG-AuthToken': 'SOME_TOKEN',
328-
'X-XNG-ApiVersion': '1',
329-
'Content-Type': 'application/json',
330-
})
334+
requests.post.assert_called_once_with(
335+
self.CROSSENGAGE_URL + 'events',
336+
data=json.dumps(payload),
337+
headers={
338+
'X-XNG-AuthToken': 'SOME_TOKEN',
339+
'X-XNG-ApiVersion': '1',
340+
'Content-Type': 'application/json',
341+
},
342+
timeout=30
343+
)
331344

332345
self.assertEqual(response['status_code'], codes.accepted)
333346

@@ -352,11 +365,16 @@ def test_send_events_request_exception_raised(self):
352365

353366
response = self.client.send_events(email='email@sample.com', events=events)
354367

355-
requests.post.assert_called_once_with(self.CROSSENGAGE_URL + 'events', data=json.dumps(payload), headers={
356-
'X-XNG-AuthToken': 'SOME_TOKEN',
357-
'X-XNG-ApiVersion': '1',
358-
'Content-Type': 'application/json',
359-
})
368+
requests.post.assert_called_once_with(
369+
self.CROSSENGAGE_URL + 'events',
370+
data=json.dumps(payload),
371+
headers={
372+
'X-XNG-AuthToken': 'SOME_TOKEN',
373+
'X-XNG-ApiVersion': '1',
374+
'Content-Type': 'application/json',
375+
},
376+
timeout=30
377+
)
360378

361379
self.assertEqual(response['success'], False)
362380
self.assertEqual(response['errors'], {'connection_error': 'exception raised'})
@@ -377,11 +395,16 @@ def test_send_events_exception_raised(self):
377395

378396
response = self.client.send_events(email='email@sample.com', events=events)
379397

380-
requests.post.assert_called_once_with(self.CROSSENGAGE_URL + 'events', data=json.dumps(payload), headers={
381-
'X-XNG-AuthToken': 'SOME_TOKEN',
382-
'X-XNG-ApiVersion': '1',
383-
'Content-Type': 'application/json',
384-
})
398+
requests.post.assert_called_once_with(
399+
self.CROSSENGAGE_URL + 'events',
400+
data=json.dumps(payload),
401+
headers={
402+
'X-XNG-AuthToken': 'SOME_TOKEN',
403+
'X-XNG-ApiVersion': '1',
404+
'Content-Type': 'application/json',
405+
},
406+
timeout=30
407+
)
385408

386409
self.assertEqual(response['success'], False)
387410
self.assertEqual(response['errors'], {'client_error': 'exception raised'})
@@ -402,11 +425,16 @@ def test_send_events_internal_server_error_response(self):
402425

403426
response = self.client.send_events(email='email@sample.com', events=events)
404427

405-
requests.post.assert_called_once_with(self.CROSSENGAGE_URL + 'events', data=json.dumps(payload), headers={
406-
'X-XNG-AuthToken': 'SOME_TOKEN',
407-
'X-XNG-ApiVersion': '1',
408-
'Content-Type': 'application/json',
409-
})
428+
requests.post.assert_called_once_with(
429+
self.CROSSENGAGE_URL + 'events',
430+
data=json.dumps(payload),
431+
headers={
432+
'X-XNG-AuthToken': 'SOME_TOKEN',
433+
'X-XNG-ApiVersion': '1',
434+
'Content-Type': 'application/json',
435+
},
436+
timeout=30
437+
)
410438

411439
self.assertEqual(response['success'], False)
412440
self.assertEqual(response['errors'], {'server_error': 'error on crossengage side'})
@@ -439,11 +467,16 @@ def test_send_events_bad_request_error_response(self):
439467

440468
response = self.client.send_events(email='email+sample.com', events=events)
441469

442-
requests.post.assert_called_once_with(self.CROSSENGAGE_URL + 'events', data=json.dumps(payload), headers={
443-
'X-XNG-AuthToken': 'SOME_TOKEN',
444-
'X-XNG-ApiVersion': '1',
445-
'Content-Type': 'application/json',
446-
})
470+
requests.post.assert_called_once_with(
471+
self.CROSSENGAGE_URL + 'events',
472+
data=json.dumps(payload),
473+
headers={
474+
'X-XNG-AuthToken': 'SOME_TOKEN',
475+
'X-XNG-ApiVersion': '1',
476+
'Content-Type': 'application/json',
477+
},
478+
timeout=30
479+
)
447480

448481
self.assertEqual(response['success'], False)
449482
self.assertEqual(response['errors'], [
@@ -477,7 +510,8 @@ def test_batch_process(self):
477510
requests.post.assert_called_once_with(
478511
self.CROSSENGAGE_URL + 'users/batch',
479512
data=json.dumps(payload),
480-
headers=self.default_headers_api_v1
513+
headers=self.default_headers_api_v1,
514+
timeout=30
481515
)
482516

483517
self.assertEqual(result, (codes.ok, json.loads(response.text)))
@@ -495,7 +529,8 @@ def test_update_user_async(self):
495529
requests.put.assert_called_once_with(
496530
self.CROSSENGAGE_URL + 'users',
497531
data=json.dumps(self.user),
498-
headers=self.default_headers_api_v2
532+
headers=self.default_headers_api_v2,
533+
timeout=30
499534
)
500535
self.assertEqual(expected_response, result)
501536

@@ -512,7 +547,8 @@ def test_delete_user_async(self):
512547
requests.delete.assert_called_once_with(
513548
self.CROSSENGAGE_URL + 'users/' + self.user['id'],
514549
data=json.dumps(self.user),
515-
headers=self.default_headers_api_v2
550+
headers=self.default_headers_api_v2,
551+
timeout=30
516552
)
517553
self.assertEqual(expected_response, result)
518554

@@ -538,7 +574,8 @@ def test_batch_process_async(self):
538574
requests.post.assert_called_once_with(
539575
self.CROSSENGAGE_URL + 'users/batch',
540576
data=json.dumps(payload),
541-
headers=self.default_headers_api_v2
577+
headers=self.default_headers_api_v2,
578+
timeout=30
542579
)
543580

544581
self.assertEqual(result, (codes.accepted, expected_body))
@@ -561,7 +598,8 @@ def test_track_user_task_ok(self):
561598
# THEN
562599
requests.get.assert_called_once_with(
563600
self.CROSSENGAGE_URL + 'users/track/trackingId',
564-
headers=self.default_headers_api_v2
601+
headers=self.default_headers_api_v2,
602+
timeout=30
565603
)
566604

567605
self.assertEqual(result, (codes.ok, expected_body))
@@ -582,7 +620,8 @@ def test_track_user_task_not_found(self):
582620
# THEN
583621
requests.get.assert_called_once_with(
584622
self.CROSSENGAGE_URL + 'users/track/trackingId',
585-
headers=self.default_headers_api_v2
623+
headers=self.default_headers_api_v2,
624+
timeout=30
586625
)
587626

588627
self.assertEqual(result, (codes.not_found, None))

0 commit comments

Comments
 (0)