Skip to content

Commit 28ab82e

Browse files
authored
Client: Add ability to specify HTTP timeout. (#116)
1 parent 98db749 commit 28ab82e

File tree

2 files changed

+93
-54
lines changed

2 files changed

+93
-54
lines changed

Adyen/client.py

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -64,15 +64,25 @@ class AdyenClient(object):
6464
skin_code (str, optional): skin_code to place directory_lookup requests
6565
and generate hpp signatures with.
6666
hmac (str, optional): Hmac key that is used for signature calculation.
67+
http_timeout (int, optional): The timeout in seconds for HTTP calls,
68+
default 30.
6769
"""
6870

69-
def __init__(self, username=None, password=None, xapikey=None,
70-
review_payout_username=None, review_payout_password=None,
71-
store_payout_username=None, store_payout_password=None,
72-
platform="test", merchant_account=None,
73-
merchant_specific_url=None, skin_code=None,
74-
hmac=None,
75-
http_force=None, live_endpoint_prefix=None):
71+
def __init__(
72+
self,
73+
username=None,
74+
password=None,
75+
xapikey=None,
76+
review_payout_username=None,
77+
review_payout_password=None,
78+
store_payout_username=None, store_payout_password=None,
79+
platform="test", merchant_account=None,
80+
merchant_specific_url=None, skin_code=None,
81+
hmac=None,
82+
http_force=None,
83+
live_endpoint_prefix=None,
84+
http_timeout=30,
85+
):
7686
self.username = username
7787
self.password = password
7888
self.xapikey = xapikey
@@ -91,6 +101,7 @@ def __init__(self, username=None, password=None, xapikey=None,
91101
self.http_init = False
92102
self.http_force = http_force
93103
self.live_endpoint_prefix = live_endpoint_prefix
104+
self.http_timeout = http_timeout
94105

95106
@staticmethod
96107
def _determine_api_url(platform, service, action):
@@ -199,8 +210,14 @@ def _store_payout_pass(self, **kwargs):
199210
'Adyen.store_payout_password = 'Your payout password'"""
200211
raise AdyenInvalidRequestError(errorstring)
201212

202-
def call_api(self, request_data, service, action, idempotency=False,
203-
**kwargs):
213+
def call_api(
214+
self,
215+
request_data,
216+
service,
217+
action,
218+
idempotency=False,
219+
**kwargs
220+
):
204221
"""This will call the adyen api. username, password, merchant_account,
205222
and platform are pulled from root module level and or self object.
206223
AdyenResult will be returned on 200 response. Otherwise, an exception
@@ -217,12 +234,15 @@ def call_api(self, request_data, service, action, idempotency=False,
217234
https://docs.adyen.com/manuals/api-manual#apiidempotency
218235
Returns:
219236
AdyenResult: The AdyenResult is returned when a request was
220-
succesful.
237+
successful.
221238
"""
222239
if not self.http_init:
223-
self.http_client = HTTPClient(self.USER_AGENT_SUFFIX,
224-
self.LIB_VERSION,
225-
self.http_force)
240+
self.http_client = HTTPClient(
241+
user_agent_suffix=self.USER_AGENT_SUFFIX,
242+
lib_version=self.LIB_VERSION,
243+
force_request=self.http_force,
244+
timeout=self.http_timeout,
245+
)
226246
self.http_init = True
227247

228248
# username at self object has highest priority. fallback to root module

Adyen/httpclient.py

Lines changed: 60 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,13 @@
3535

3636

3737
class HTTPClient(object):
38-
def __init__(self, user_agent_suffix, lib_version, force_request=None):
38+
def __init__(
39+
self,
40+
user_agent_suffix,
41+
lib_version,
42+
force_request=None,
43+
timeout=None,
44+
):
3945
# Check if requests already available, default to urllib
4046
self.user_agent = user_agent_suffix + lib_version
4147
if not force_request:
@@ -53,17 +59,20 @@ def __init__(self, user_agent_suffix, lib_version, force_request=None):
5359
else:
5460
self.request = self._urllib_post
5561

56-
def _pycurl_post(self,
57-
url,
58-
json=None,
59-
data=None,
60-
username="",
61-
password="",
62-
xapikey="",
63-
headers=None,
64-
timeout=30):
62+
self.timeout = timeout
63+
64+
def _pycurl_post(
65+
self,
66+
url,
67+
json=None,
68+
data=None,
69+
username="",
70+
password="",
71+
xapikey="",
72+
headers=None
73+
):
6574
"""This function will POST to the url endpoint using pycurl. returning
66-
an AdyenResult object on 200 HTTP responce. Either json or data has to
75+
an AdyenResult object on 200 HTTP response. Either json or data has to
6776
be provided. If username and password are provided, basic auth will be
6877
used.
6978
@@ -129,7 +138,7 @@ def _pycurl_post(self,
129138
raw_request = json_lib.dumps(json) if json else urlencode(data)
130139
curl.setopt(curl.POSTFIELDS, raw_request)
131140

132-
curl.setopt(curl.TIMEOUT, timeout)
141+
curl.setopt(curl.TIMEOUT, self.timeout)
133142
curl.perform()
134143

135144
# Grab the response content
@@ -143,14 +152,16 @@ def _pycurl_post(self,
143152

144153
return result, raw_request, status_code, response_headers
145154

146-
def _requests_post(self, url,
147-
json=None,
148-
data=None,
149-
username="",
150-
password="",
151-
xapikey="",
152-
headers=None,
153-
timeout=30):
155+
def _requests_post(
156+
self,
157+
url,
158+
json=None,
159+
data=None,
160+
username="",
161+
password="",
162+
xapikey="",
163+
headers=None
164+
):
154165
"""This function will POST to the url endpoint using requests.
155166
Returning an AdyenResult object on 200 HTTP response.
156167
Either json or data has to be provided.
@@ -191,8 +202,14 @@ def _requests_post(self, url,
191202
# can be identified as coming from the Adyen Python library.
192203
headers['User-Agent'] = self.user_agent
193204

194-
request = requests.post(url, auth=auth, data=data, json=json,
195-
headers=headers, timeout=timeout)
205+
request = requests.post(
206+
url=url,
207+
auth=auth,
208+
data=data,
209+
json=json,
210+
headers=headers,
211+
timeout=self.timeout
212+
)
196213

197214
# Ensure either json or data is returned for raw request
198215
# Updated: Only return regular dict,
@@ -201,14 +218,16 @@ def _requests_post(self, url,
201218

202219
return request.text, message, request.status_code, request.headers
203220

204-
def _urllib_post(self, url,
205-
json=None,
206-
data=None,
207-
username="",
208-
password="",
209-
xapikey="",
210-
headers=None,
211-
timeout=30):
221+
def _urllib_post(
222+
self,
223+
url,
224+
json=None,
225+
data=None,
226+
username="",
227+
password="",
228+
xapikey="",
229+
headers=None,
230+
):
212231

213232
"""This function will POST to the url endpoint using urllib2. returning
214233
an AdyenResult object on 200 HTTP responce. Either json or data has to
@@ -228,7 +247,6 @@ def _urllib_post(self, url,
228247
xapikey (str, optional): Adyen API key. Will be used for auth
229248
if username and password are absent.
230249
headers (dict, optional): Key/Value pairs of headers to include
231-
timeout (int, optional): Default 30. Timeout for the request.
232250
233251
Returns:
234252
str: Raw response received
@@ -279,7 +297,7 @@ def _urllib_post(self, url,
279297

280298
# URLlib raises all non 200 responses as en error.
281299
try:
282-
response = urlopen(url_request, timeout=timeout)
300+
response = urlopen(url_request, timeout=self.timeout)
283301
except HTTPError as e:
284302
raw_response = e.read()
285303

@@ -293,13 +311,15 @@ def _urllib_post(self, url,
293311
return (raw_response, raw_request,
294312
response.getcode(), dict(response.info()))
295313

296-
def request(self, url,
297-
json="",
298-
data="",
299-
username="",
300-
password="",
301-
headers=None,
302-
timout=30):
314+
def request(
315+
self,
316+
url,
317+
json="",
318+
data="",
319+
username="",
320+
password="",
321+
headers=None,
322+
):
303323
"""This is overridden on module initialization. This function will make
304324
an HTTP POST to a given url. Either json/data will be what is posted to
305325
the end point. he HTTP request needs to be basicAuth when username and
@@ -313,7 +333,7 @@ def request(self, url,
313333
key/value of request to place as
314334
www-form
315335
username (str, optional): Username for basic auth. Must be
316-
uncluded as part of password.
336+
included as part of password.
317337
password (str, optional): Password for basic auth. Must be
318338
included as part of username.
319339
xapikey (str, optional): Adyen API key. Will be used for auth
@@ -324,7 +344,6 @@ def request(self, url,
324344
str: Raw response received
325345
int: HTTP status code, eg 200,404,401
326346
dict: Key/Value pairs of the headers received.
327-
:param timout:
328347
"""
329348
raise NotImplementedError('request of HTTPClient should have been '
330349
'overridden on initialization. '

0 commit comments

Comments
 (0)