Skip to content

Commit 1b4a7a8

Browse files
committed
moved to use requests.Session(), split network out, added upwrapped code for enterprise log share support
1 parent 91c0cc2 commit 1b4a7a8

1 file changed

Lines changed: 147 additions & 17 deletions

File tree

CloudFlare/cloudflare.py

Lines changed: 147 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,16 @@ class CloudFlare(object):
1919
class _v4base(object):
2020
""" Cloudflare v4 API"""
2121

22-
def __init__(self, email, token, certtoken, base_url, debug, raw):
22+
def __init__(self, email, token, certtoken, base_url, debug, raw, use_sessions):
2323
""" Cloudflare v4 API"""
2424

2525
self.email = email
2626
self.token = token
2727
self.certtoken = certtoken
2828
self.base_url = base_url
2929
self.raw = raw
30+
self.use_sessions = use_sessions
31+
self.session = None
3032
self.user_agent = user_agent()
3133

3234
if debug:
@@ -69,6 +71,28 @@ def call_with_auth(self, method, parts,
6971
identifier1, identifier2, identifier3,
7072
params, data, files)
7173

74+
def call_with_auth_unwrapped(self, method, parts,
75+
identifier1=None, identifier2=None, identifier3=None,
76+
params=None, data=None, files=None):
77+
""" Cloudflare v4 API"""
78+
79+
if self.email is '' or self.token is '':
80+
raise CloudFlareAPIError(0, 'no email and/or token defined')
81+
headers = {
82+
'User-Agent': self.user_agent,
83+
'X-Auth-Email': self.email,
84+
'X-Auth-Key': self.token,
85+
'Content-Type': 'application/json'
86+
}
87+
if files:
88+
# overwrite Content-Type as we are uploading data
89+
headers['Content-Type'] = 'multipart/form-data'
90+
# however something isn't right and this works ... look at again later!
91+
del headers['Content-Type']
92+
return self._call_unwrapped(method, headers, parts,
93+
identifier1, identifier2, identifier3,
94+
params, data, files)
95+
7296
def call_with_certauth(self, method, parts,
7397
identifier1=None, identifier2=None, identifier3=None,
7498
params=None, data=None, files=None):
@@ -85,9 +109,9 @@ def call_with_certauth(self, method, parts,
85109
identifier1, identifier2, identifier3,
86110
params, data, files)
87111

88-
def _raw(self, method, headers, parts,
89-
identifier1=None, identifier2=None, identifier3=None,
90-
params=None, data=None, files=None):
112+
def _network(self, method, headers, parts,
113+
identifier1=None, identifier2=None, identifier3=None,
114+
params=None, data=None, files=None):
91115
""" Cloudflare v4 API"""
92116

93117
if self.logger:
@@ -142,18 +166,34 @@ def _raw(self, method, headers, parts,
142166
if self.logger:
143167
self.logger.debug('Call: doit!')
144168

169+
if self.use_sessions:
170+
if self.session is None:
171+
self.session = requests.Session()
172+
else:
173+
self.session = requests
174+
145175
try:
146176
if method == 'GET':
147-
response = requests.get(url, headers=headers, params=params, data=data)
177+
response = self.session.get(url,
178+
headers=headers,
179+
params=params, data=data)
148180
elif method == 'POST':
149-
response = requests.post(url, headers=headers, params=params, json=data, files=files)
181+
response = self.session.post(url,
182+
headers=headers,
183+
params=params, json=data,
184+
files=files)
150185
elif method == 'PUT':
151-
response = requests.put(url, headers=headers, params=params, json=data)
186+
response = self.session.put(url,
187+
headers=headers,
188+
params=params, json=data)
152189
elif method == 'DELETE':
153-
response = requests.delete(url, headers=headers, json=data)
190+
response = self.session.delete(url,
191+
headers=headers,
192+
json=data)
154193
elif method == 'PATCH':
155-
response = requests.request('PATCH', url,
156-
headers=headers, params=params, json=data)
194+
response = self.session.request('PATCH', url,
195+
headers=headers,
196+
params=params, json=data)
157197
else:
158198
# should never happen
159199
raise CloudFlareAPIError(0, 'method not supported')
@@ -178,7 +218,7 @@ def _raw(self, method, headers, parts,
178218
# API should always response; but if it doesn't; here's the default
179219
response_type = 'application/octet-stream'
180220
response_code = response.status_code
181-
response_data = response.text
221+
response_data = response.content
182222

183223
if self.logger:
184224
self.logger.debug('Response: %d, %s, %s' % (response_code, response_type, response_data))
@@ -223,13 +263,35 @@ def _raw(self, method, headers, parts,
223263
#
224264
# should be a 200 response at this point
225265

266+
return [response_type, response_code, response_data]
267+
268+
def _raw(self, method, headers, parts,
269+
identifier1=None, identifier2=None, identifier3=None,
270+
params=None, data=None, files=None):
271+
""" Cloudflare v4 API"""
272+
273+
[response_type, response_code, response_data] = self._network(method,
274+
headers, parts,
275+
identifier1, identifier2, identifier3,
276+
params, data, files)
277+
226278
if response_type == 'application/json':
227279
# API says it's JSON; so it better be parsable as JSON
228280
try:
229281
response_data = json.loads(response_data)
230282
except ValueError:
231-
# While this should not happen; it's always possible
232-
raise CloudFlareAPIError(0, 'JSON parse failed - report to Cloudflare.')
283+
if response_data == '':
284+
# This should really be 'null' but it isn't. Even then, it's wrong!
285+
if response_code == requests.codes.ok:
286+
# 200 ok
287+
response_data = {'success': True, 'result': None}
288+
else:
289+
# 3xx & 4xx errors
290+
response_data = {'success': False, 'code': response_code, 'result': None}
291+
else:
292+
# While this should not happen; it's always possible
293+
self.logger.debug('Response data not JSON: %r' % (response_data))
294+
raise CloudFlareAPIError(0, 'JSON parse failed - report to Cloudflare.')
233295

234296
if response_code == requests.codes.ok:
235297
# 200 ok - so nothing needs to be done
@@ -332,14 +394,27 @@ def _call(self, method, headers, parts,
332394
result = response_data['result']
333395
return result
334396

397+
def _call_unwrapped(self, method, headers, parts,
398+
identifier1=None, identifier2=None, identifier3=None,
399+
params=None, data=None, files=None):
400+
""" Cloudflare v4 API"""
401+
402+
response_data = self._raw(method, headers, parts,
403+
identifier1, identifier2, identifier3,
404+
params, data, files)
405+
if self.logger:
406+
self.logger.debug('Response: %s' % (response_data))
407+
result = response_data
408+
return result
409+
335410
class _add_unused(object):
336411
""" Cloudflare v4 API"""
337412

338413
def __init__(self, base, api_call_part1, api_call_part2=None, api_call_part3=None):
339414
""" Cloudflare v4 API"""
340415

341416
self._base = base
342-
self._parts = [api_call_part1, api_call_part2, api_call_part3]
417+
self._parts_unused = [api_call_part1, api_call_part2, api_call_part3]
343418

344419
def __call__(self, identifier1=None, identifier2=None, identifier3=None, params=None, data=None):
345420
""" Cloudflare v4 API"""
@@ -350,7 +425,7 @@ def __call__(self, identifier1=None, identifier2=None, identifier3=None, params=
350425
def __str__(self):
351426
""" Cloudflare v4 API"""
352427

353-
return '[%s]' % ('/' + '/:id/'.join(filter(None, self._parts)))
428+
return '[%s]' % ('/' + '/:id/'.join(filter(None, self._parts_unused)))
354429

355430
def get(self, identifier1=None, identifier2=None, identifier3=None, params=None, data=None):
356431
""" Cloudflare v4 API"""
@@ -479,6 +554,61 @@ def delete(self, identifier1=None, identifier2=None, identifier3=None, params=No
479554
identifier1, identifier2, identifier3,
480555
params, data)
481556

557+
class _add_with_auth_unwrapped(object):
558+
""" Cloudflare v4 API"""
559+
560+
def __init__(self, base, api_call_part1, api_call_part2=None, api_call_part3=None):
561+
""" Cloudflare v4 API"""
562+
563+
self._base = base
564+
self._parts = [api_call_part1, api_call_part2, api_call_part3]
565+
566+
def __call__(self, identifier1=None, identifier2=None, identifier3=None, params=None, data=None):
567+
""" Cloudflare v4 API"""
568+
569+
# This is the same as a get()
570+
return self.get(identifier1, identifier2, identifier3, params, data)
571+
572+
def __str__(self):
573+
""" Cloudflare v4 API"""
574+
575+
return '[%s]' % ('/' + '/:id/'.join(filter(None, self._parts)))
576+
577+
def get(self, identifier1=None, identifier2=None, identifier3=None, params=None, data=None):
578+
""" Cloudflare v4 API"""
579+
580+
return self._base.call_with_auth_unwrapped('GET', self._parts,
581+
identifier1, identifier2, identifier3,
582+
params, data)
583+
584+
def patch(self, identifier1=None, identifier2=None, identifier3=None, params=None, data=None):
585+
""" Cloudflare v4 API"""
586+
587+
return self._base.call_with_auth_unwrapped('PATCH', self._parts,
588+
identifier1, identifier2, identifier3,
589+
params, data)
590+
591+
def post(self, identifier1=None, identifier2=None, identifier3=None, params=None, data=None, files=None):
592+
""" Cloudflare v4 API"""
593+
594+
return self._base.call_with_auth_unwrapped('POST', self._parts,
595+
identifier1, identifier2, identifier3,
596+
params, data, files)
597+
598+
def put(self, identifier1=None, identifier2=None, identifier3=None, params=None, data=None):
599+
""" Cloudflare v4 API"""
600+
601+
return self._base.call_with_auth_unwrapped('PUT', self._parts,
602+
identifier1, identifier2, identifier3,
603+
params, data)
604+
605+
def delete(self, identifier1=None, identifier2=None, identifier3=None, params=None, data=None):
606+
""" Cloudflare v4 API"""
607+
608+
return self._base.call_with_auth_unwrapped('DELETE', self._parts,
609+
identifier1, identifier2, identifier3,
610+
params, data)
611+
482612
class _add_with_cert_auth(object):
483613
""" Cloudflare v4 API"""
484614

@@ -557,7 +687,7 @@ def api_list(self, m=None, s=''):
557687
w = w + self.api_list(a, s + '/' + n)
558688
return w
559689

560-
def __init__(self, email=None, token=None, certtoken=None, debug=False, raw=False):
690+
def __init__(self, email=None, token=None, certtoken=None, debug=False, raw=False, use_sessions=True):
561691
""" Cloudflare v4 API"""
562692

563693
base_url = BASE_URL
@@ -572,7 +702,7 @@ def __init__(self, email=None, token=None, certtoken=None, debug=False, raw=Fals
572702
if certtoken is None:
573703
certtoken = conf_certtoken
574704

575-
self._base = self._v4base(email, token, certtoken, base_url, debug, raw)
705+
self._base = self._v4base(email, token, certtoken, base_url, debug, raw, use_sessions)
576706

577707
# add the API calls
578708
api_v4(self)

0 commit comments

Comments
 (0)