0

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.

Community
  • 1
  • 1
Paul Gowder
  • 2,409
  • 1
  • 21
  • 36

1 Answers1

0

Using the files argument states "for multipart encoding upload". A multi part http response is not default when using the data argument, therefore the two are not equivalent. See What is http multipart request? Specifically, using the files argument generates a multipart/form-data POST as opposed to application/x-www-form-urlencoded.

Community
  • 1
  • 1
TheoretiCAL
  • 19,461
  • 8
  • 43
  • 65
  • Oooooh, that makes more sense. I had assumed that if it allowed files and data that multipart request would be the default... – Paul Gowder Mar 09 '17 at 19:32