Reading the documentation for Python's requests
library, the API for the basic request function has several parameters that seem redundant:
data -- (optional) Dictionary or list of tuples [(key, value)] (will be form-encoded), bytes, or file-like object to send in the body of the Request.
json -- (optional) json data to send in the body of the Request.
files -- (optional) Dictionary of 'name': file-like-objects (or {'name': file-tuple}) for multipart encoding upload. file-tuple can be a 2-tuple ('filename', fileobj), 3-tuple ('filename', fileobj, 'content_type') or a 4-tuple ('filename', fileobj, 'content_type', custom_headers), where 'content-type' is a string defining the content type of the given file and custom_headers a dict-like object containing additional headers to add for the file.
The same is the case for the rest of the interface, e.g., post, get, etc. I find this a bit confusing.
Suppose I'm trying to send files to an endpoint somewhere along with instructions on how to use them. Can I/would there ever be any reason not to just jam everything into the data parameter, rather than use files, json, etc.?
In other words, is there any difference between:
requests.post('http://some.api.endpoint',
data={'command': 'foo',
'options': {'the_thing':'gimmie', 'the_answer': 42},
'the_file': open('myfile.pdf', 'rb')})
versus
requests.post('http://some.api.endpoint',
data={'command': 'foo'},
json=json.dumps({'options': {'the_thing':'gimmie', 'the_answer': 42}}),
files={'the_file': open('myfile.pdf', 'rb')})
The most natural reading of the quoted bit of the documentation is that those two calls would be equivalent...?
Maybe I'm misreading the documentation for the data parameter, and it can't take a dictionary of files? It's a little unclear to me. Does the documentation explanation of data
mean "dictionary or list [of triples, bytes, or file-like object[s]], or does it mean "[dictionary or list of tuples], bytes, or file-like object? Either is a little bit grammatically uncomfortable.