@@ -153,6 +153,31 @@ def convert_to_easypost_object(response, api_key, parent=None, name=None):
153
153
return response
154
154
155
155
156
+ def _utf8 (value ):
157
+ if six .PY2 :
158
+ # Python2's urlencode wants bytestrings, not unicode
159
+ if isinstance (value , six .text_type ):
160
+ return value .encode ('utf-8' )
161
+ return value
162
+ elif isinstance (value , six .binary_type ):
163
+ # Python3's six.text_type(bytestring) returns "b'bytestring'"
164
+ # So, have to decode it to unicode
165
+ return value .decode ('utf-8' )
166
+ else :
167
+ # Python3's urlencode can handle unicode
168
+ return value
169
+
170
+
171
+ def _urlencode_list (params ):
172
+ encoded = []
173
+ for key , values in sorted (params .items ()):
174
+ for value in values :
175
+ if isinstance (value , bool ):
176
+ value = str (value ).lower ()
177
+ encoded .append ('{0}[]={1}' .format (key , quote_plus (_utf8 (value ))))
178
+ return '&' .join (encoded )
179
+
180
+
156
181
class Requestor (object ):
157
182
def __init__ (self , local_api_key = None ):
158
183
self ._api_key = local_api_key
@@ -162,35 +187,20 @@ def api_url(cls, url=None):
162
187
url = url or ''
163
188
return '%s%s' % (api_base , url )
164
189
165
- @classmethod
166
- def _utf8 (cls , value ):
167
- if six .PY2 :
168
- # Python2's urlencode wants bytestrings, not unicode
169
- if isinstance (value , six .text_type ):
170
- return value .encode ('utf-8' )
171
- return value
172
- elif isinstance (value , six .binary_type ):
173
- # Python3's six.text_type(bytestring) returns "b'bytestring'"
174
- # So, have to decode it to unicode
175
- return value .decode ('utf-8' )
176
- else :
177
- # Python3's urlencode can handle unicode
178
- return value
179
-
180
190
@classmethod
181
191
def encode_dict (cls , out , key , dict_value ):
182
192
n = {}
183
193
for k , v in sorted (six .iteritems (dict_value )):
184
- k = cls . _utf8 (k )
185
- v = cls . _utf8 (v )
194
+ k = _utf8 (k )
195
+ v = _utf8 (v )
186
196
n ["%s[%s]" % (key , k )] = v
187
197
out .extend (cls ._encode_inner (n ))
188
198
189
199
@classmethod
190
200
def encode_list (cls , out , key , list_value ):
191
201
n = {}
192
202
for k , v in enumerate (list_value ):
193
- v = cls . _utf8 (v )
203
+ v = _utf8 (v )
194
204
n ["%s[%s]" % (key , k )] = v
195
205
out .extend (cls ._encode_inner (n ))
196
206
@@ -218,7 +228,7 @@ def _encode_inner(cls, params):
218
228
219
229
out = []
220
230
for key , value in sorted (six .iteritems (params )):
221
- key = cls . _utf8 (key )
231
+ key = _utf8 (key )
222
232
try :
223
233
encoder = ENCODERS [value .__class__ ]
224
234
encoder (out , key , value )
@@ -575,7 +585,7 @@ def instance_url(self):
575
585
easypost_id = self .get ('id' )
576
586
if not easypost_id :
577
587
raise Error ('%s instance has invalid ID: %r' % (type (self ).__name__ , easypost_id ))
578
- easypost_id = Requestor . _utf8 (easypost_id )
588
+ easypost_id = _utf8 (easypost_id )
579
589
base = self .class_url ()
580
590
param = quote_plus (easypost_id )
581
591
return "{base}/{param}" .format (base = base , param = param )
@@ -635,13 +645,15 @@ def create(cls, api_key=None, verify=None, verify_strict=None, **params):
635
645
requestor = Requestor (api_key )
636
646
url = cls .class_url ()
637
647
638
- if verify or verify_strict :
639
- verify = verify or []
640
- verify_strict = verify_strict or []
641
- url += '?' + '&' .join (
642
- ['verify[]={0}' .format (opt ) for opt in verify ] +
643
- ['verify_strict[]={0}' .format (opt ) for opt in verify_strict ]
644
- )
648
+ verify_params = {}
649
+ for key , value in (('verify' , verify ), ('verify_strict' , verify_strict )):
650
+ if not value :
651
+ continue
652
+ elif isinstance (value , (bool , str )):
653
+ value = [value ]
654
+ verify_params [key ] = value
655
+ if verify_params :
656
+ url += '?' + _urlencode_list (verify_params )
645
657
646
658
wrapped_params = {cls .class_name (): params }
647
659
response , api_key = requestor .request ('post' , url , wrapped_params )
0 commit comments