Summary:
There is no built-in option to use the params
parameter and have bool values converted from python True
|False
to json true
|false
.
We must manually process the bool values to turn them into lowercase strings. Several methods for processing are presented below.
ex:
encode the individual values with
'true' if x else 'false'
or json.dumps(x)
Why
The internal methods of requests.request use stringification to convert any non-string value. See prepare_url in PreparedRequest
.
If query and params are both used, then enc_params are converted to string by '%s&%s' % (query, enc_params)
. If not, then the query=enc_params
is string encoded inside requote_url
.
### excerpt from PreparedRequest.prepare_url
enc_params = self._encode_params(params)
if enc_params:
if query:
query = '%s&%s' % (query, enc_params)
else:
query = enc_params
url = requote_uri(urlunparse([scheme, netloc, path, None, query, fragment]))
self.url = url
str(True) # 'True'
str(False) # 'False'
'%s' % True # 'True
import json
json_dumps(None) # 'null' <-- probably want to avoid null for Boolean values
json.dumps(True) # 'true' <-- lowercase
json.dumps(False) # 'false' <-- lowercase
How
For one or two values you could use a simple ternary, but this gets verbose quickly.
is_coming_soon, is_paid = False, True
params = {'is_coming_soon': 'true' if is_coming_soon else 'false',
'is_paid': 'true' if is_paid else 'false',
'limit': 100, 'skip': 0}
or maybe a quick function to do it for you:
encode_bool = lambda x: 'true' if x else 'false'
is_coming_soon, is_paid = False, True
params = {'is_coming_soon': encode_bool(is_coming_soon),
'is_paid': encode_bool(is_paid),
'limit': 100, 'skip': 0}
Or we could move up the stack and make a function to modify all the Booleans
# Caveat: this only encodes one level of structure.
def encode_boolean_values(kv):
""" convert bool values to 'true'/'false' strings for json compat """
enc = lambda x : x if not isinstance(x, bool) else 'true' if x else 'false'
{k: enc(v) for k,v in kv.items()}
is_coming_soon, is_paid = False, True
params = {'is_coming_soon': is_coming_soon,
'is_paid': is_paid,
'limit': 100, 'skip': 0}
params = encode_boolean_values(params)
Note: you could use json.dumps() instead of the ternary. I use the ternary to collapse Null in with False rather than making it 'null'