0

I am trying to upload a file to a server, using python. The API of the server has to accept the file, together with some other parameters.

This is why i open the file, and then i create a dictionary, containing the file and the other parameters that the web app accepts, and then encode it and perform a POST request with the item.

This is the code:

from urllib import request
from urllib.parse import urlencode
import json
with open('README.md', 'rb') as f:
 upload_credentials = {
 "file": f,
 "descr": "testing",
 "title": "READMEE.md",
 "contentType": "text",
 "editor": username,
 }
 url_for_upload = "" #here you place the upload URL
 
 req = request.Request(url_for_upload, method="POST")
 form_data = urlencode(upload_credentials)
 form_data = form_data.encode()
 
 response = request.urlopen(req, data=form_data)
 http_status_code = response.getcode()
 content = response.read()
 print(http_status_code)
 print(content)

However, i get an error in this line: response = request.urlopen(req, data=form_data) The server responds with a 500 HTTP Status Code.

This is what i get as an error message:

raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 500:

500 error codes can mean a lot of things and i do not know how to progress any further, as everything i did seems by the book...

Does anyone have the experience, given the info provided here, to guide me to some potential solution?

EDIT: I am trying to replicate working js code that does the same thing. This is it:

<input type="file" />
<button onclick="upload()">Upload data</button>
<script>
 upload = async() =>
 { 
 const fileField = document.querySelector('input[type="file"]');
 await uploadDoc(fileField.files[0] );
 };
 
 uploadDoc = async( file ) =>
 { 
 let fd = new FormData();
 fd.append( 'file', file ); 
 fd.append( 'descr', 'demo_upload' );
 fd.append( 'title', name );
 fd.append( 'contentType', 'text' );
 fd.append( 'editor', user );
 let resp = await fetch( url, { method: 'POST', mode: 'cors', body: fd }); 
 };
</script>
asked Jan 14, 2022 at 10:21
9
  • What value should file have in the dict? the contents of the file? cause right now it just has the file handle reference. Commented Jan 14, 2022 at 10:27
  • are you trying to stream the file? you add the filehandle to your "upload_credentials" Commented Jan 14, 2022 at 10:28
  • Could you provide the docs to the API you are using? Commented Jan 14, 2022 at 10:28
  • shouldn't "file": f rather be "file": f.read() ? Commented Jan 14, 2022 at 10:30
  • @SPSharan The server accepts a POST request to a particular url. You can see in the updated question an example of the form that it accepts. Commented Jan 14, 2022 at 10:36

1 Answer 1

2

The js code is doing a multipart/form-data post request.
I do not believe urllib supports multipart/form-data, you can use request instead.

import requests 
with open('README.md', 'rb') as f:
 files = {"file": f}
 upload_credentials = {
 "descr": "testing",
 "title": "READMEE.md",
 "contentType": "text",
 "editor": username,
 }
 r = requests.post("http://httpbin.org/post", files=files, data=upload_credentials) 
 print(r.status_code)
 print(r.text)
answered Jan 15, 2022 at 4:11
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you very much! So the trick was that this was a multipart form POST request. Thanks again!

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.