forked from demystify-systems/bigcommerce_v3
-
Notifications
You must be signed in to change notification settings - Fork 1
/
monkey_patches.py
104 lines (88 loc) · 3.37 KB
/
monkey_patches.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# -*- coding: utf-8 -*-
# Copyright © 2018 by IBPort. All rights reserved.
# @Author: Neal Wong
# @Email: [email protected]
import json
import time
try:
from urllib import urlencode
except ImportError:
from urllib.parse import urlencode
from bigcommerce.resources.base import ApiResource
from bigcommerce.connection import Connection
from bigcommerce.connection import log
from bigcommerce.exception import ServerException, RateLimitingException
from wrapt import apply_patch
from requests.exceptions import (ConnectTimeout, ConnectionError, ReadTimeout)
@classmethod
def _make_request(cls, method, url, connection, data=None, params=None, headers=None):
result = None
api_version = getattr(cls, 'api_version') if hasattr(cls, 'api_version') else 'v2'
retries = connection.max_retries
while retries > 0:
try:
result = connection.make_request(
method, url, data, params, headers, api_version=api_version)
if isinstance(result, dict) and 'data' in result:
result = result['data']
break
except ServerException:
log.exception(e)
retries -= 1
log.info('[RetryServerException] Retry remaining: %d', retries)
except RateLimitingException as e:
log.exception(e)
time.sleep(3)
log.info('[RetryRateLimitingException] Retry remaining: %d', retries)
return result
def make_request(self, method, url, data=None, params=None, headers=None, api_version='v2'):
response = self._run_method(method, url, data, params, headers, api_version)
return self._handle_response(url, response)
def _run_method(self, method, url, data=None, query=None, headers=None, api_version='v2'):
if query is None:
query = {}
if headers is None:
headers = {}
# make full path if not given
if url and url[:4] != "http":
if url[0] == '/': # can call with /resource if you want
url = url[1:]
url = self.full_path(url, api_version)
elif not url: # blank path
url = self.full_path(url, api_version)
qs = urlencode(query)
if qs:
qs = "?" + qs
url += qs
# mess with content
if data:
if not headers: # assume JSON
data = json.dumps(data)
headers = {'Content-Type': 'application/json'}
if headers and 'Content-Type' not in headers:
data = json.dumps(data)
headers['Content-Type'] = 'application/json'
log.debug("%s %s" % (method, url))
# make and send the request
max_retries = 12
retries = max_retries
while retries > 0:
try:
response = self._session.request(
method, url, data=data, timeout=self.timeout, headers=headers)
break
except (ConnectTimeout, ReadTimeout):
retries -= 1
if retries <= 0:
raise
else:
time.sleep(12)
except ConnectionError:
retries -= 1
if hasattr(self, '_reset_session'):
self._reset_session()
continue
return response
apply_patch(Connection, 'make_request', make_request)
apply_patch(Connection, '_run_method', _run_method)
apply_patch(ApiResource, '_make_request', _make_request)