2

I have the following code in C# that I need to convert into Python.

Code in C#:

{
            var fileName = new FileInfo(file);
            
            string requestString = "url to be used"
            var request = (HttpWebRequest)WebRequest.Create(requestString);
            request.KeepAlive = false;      
            request.AllowAutoRedirect = false;
            request.Method = "POST";
            request.Timeout = 50000;

            var boundary = "------WebKitFormBoundaryv4JOuEW2XZeLh2TK";
            byte[] startBoundaryBytes = Encoding.ASCII.GetBytes("--" + boundary + "\r\n");
            string bodyHeader = "Content-Disposition: form-data; name=\"BackupFile\"; filename=\"" + fileName.Name + "\"\r\nContent-Type: application/octet-stream\r\n\r\n";
            byte[] bodyHeaderBytes = Encoding.ASCII.GetBytes(bodyHeader);
            byte[] trailerBytes = Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n");

            request.ContentType = string.Format("multipart/form-data; boundary={0}", boundary);
            using (var requestStream = request.GetRequestStream()) {
                requestStream.Write(startBoundaryBytes, 0, startBoundaryBytes.Length);
                requestStream.Write(bodyHeader2Bytes, 0, bodyHeader2Bytes.Length);
                //read file and add it to request
                using(var fileStream = new FileStream(fileName.FullName, FileMode.Open, FileAccess.Read)) {
                    var buffer = new byte[4096];
                    int bytesRead = 0;
                    do {
                        bytesRead = fileStream.Read(buffer, 0, buffer.Length);
                        if(bytesRead > 0) {
                            requestStream.Write(buffer, 0, bytesRead);
                        }
                    } while(bytesRead > 0);
                }
                //write body trailer bytes
                requestStream.Write(trailerBytes, 0, trailerBytes.Length);
            }
            
            try {
                var response = request.GetResponse();
                using(var reader = new StreamReader(response.GetResponseStream())) {
                    string responseText = reader.ReadToEnd();
                }
            } catch (WebException e) {
                ...
        }

What's the best way to convert this code to Python? So far I have the basics in Python, and from my searches I think I should be using requests library. But how can I add those boundary bytes as well as the file itself to the request?

Code in Python so far (really just the basic stuff, I've been trying different stuff with the requests lib but with no success at all):

        url = "url_to_be_used"

        fileName = "sample.sample"
        boundary = "------WebKitFormBoundaryv4JOuEW2XZeLh2TK"
        startBoundaryBytes = ("--" + boundary + "\r\n").encode("ascii")
        bodyHeader2 = "Content-Disposition: form-data; name=\"BackupFile\"; filename=\"" + fileName + "\"\r\nContent-Type: application/octet-stream\r\n\r\n"
        bodyHeader2Bytes = bodyHeader2.encode("ascii")
        trailerBytes = ("\r\n--" + boundary + "--\r\n").encode("ascii")

        headers = {"Content-Type": "multipart/form-data; boundary={}".format(boundary)}

Any help would be appreciated!

Thank you

s_7
  • 33
  • 1
  • 1
  • 6
  • Does this answer your question? [Send file using POST from a Python script](https://stackoverflow.com/questions/68477/send-file-using-post-from-a-python-script) – Aluan Haddad Sep 13 '20 at 22:21
  • I read that thread before but I coudn't make the file upload to work. Request returns 200 but file is not upload, and I think the issue is that I cannot make the part of the code in C# work in Python: // requestStream.Write(startBoundaryBytes, 0, startBoundaryBytes.Length); // requestStream.Write(bodyHeader2Bytes, 0, bodyHeader2Bytes.Length); The file part I think I can manage, but what about those lines above? Where am I suppose to send this info in the request? – s_7 Sep 13 '20 at 22:30

1 Answers1

2

Just post it without stream bytes and header magic:

file = {'BackupFile': open(file_name, 'rb')}
response = requests.post(url, files=file)

all the rest will make requests: will send a multi-part form POST body with the BackupFile field set to the contents of the file.txt file. Also the filename will be included in the mime header for the specific field.

example:

>>> files = {'BackupFile': open('file.txt', 'rb')}
>>> print(requests.Request('POST', 'http://example.com', files=files).prepare().body.decode('ascii'))
--0c249de0e6243e92307003732e49ffe9
Content-Disposition: form-data; name="BackupFile"; filename="file.txt"
--0c249de0e6243e92307003732e49ffe9--
ujlbu4
  • 1,058
  • 8
  • 8
  • It worked! I basically had the same at some point, just didn't realize that had to call it BackupFile, my bad. Thank you – s_7 Sep 14 '20 at 08:01