@@ -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