upload files through http post in Pyside/PyQt

后端 未结 1 1989
攒了一身酷
攒了一身酷 2021-01-03 07:30

I\'m trying to send a file and other POST variables to a xfilesharing script(which is in perl) on my customer server.

There are no good resources on Google and the c

相关标签:
1条回答
  • 2021-01-03 08:14

    This question appears surprisingly difficult. There is indeed no complete examples on this topic.

    PyQt

    In PyQt4 I managed to run example provided in the QHttpMultiPart documentation. Adaptated Python version (requires Qt 4.8):

    from PyQt4 import QtGui, QtCore, QtNetwork
    import sys
    import time
    
    def finished(reply):
      print "Finished: ", reply.readAll()
      app.quit()
    
    def construct_multipart(data, files):
      multiPart = QtNetwork.QHttpMultiPart(QtNetwork.QHttpMultiPart.FormDataType)
      for key, value in data.items():
        textPart = QtNetwork.QHttpPart()
        textPart.setHeader(QtNetwork.QNetworkRequest.ContentDispositionHeader,
          "form-data; name=\"%s\"" % key)
        textPart.setBody(value)
        multiPart.append(textPart)
    
      for key, file in files.items():
        imagePart = QtNetwork.QHttpPart()
        #imagePart.setHeader(QNetworkRequest::ContentTypeHeader, ...);
        fileName = QtCore.QFileInfo(file.fileName()).fileName()
        imagePart.setHeader(QtNetwork.QNetworkRequest.ContentDispositionHeader,
          "form-data; name=\"%s\"; filename=\"%s\"" % (key, fileName))
        imagePart.setBodyDevice(file);
        multiPart.append(imagePart)
      return multiPart
    
    app = QtGui.QApplication(sys.argv)
    file1 = QtCore.QFile('/tmp/1.txt')
    file1.open(QtCore.QFile.ReadOnly)
    url = QtCore.QUrl('http://localhost:3000/qwertytest1');
    data = { 'text1': 'test1', 'text2': 'test2' }
    files = {'file1': file1 }
    multipart = construct_multipart(data, files)
    request_qt = QtNetwork.QNetworkRequest(url)
    request_qt.setHeader(QtNetwork.QNetworkRequest.ContentTypeHeader,
      'multipart/form-data; boundary=%s' % multipart.boundary())
    manager = QtNetwork.QNetworkAccessManager()
    manager.finished.connect(finished)
    request = manager.post(request_qt, multipart)
    
    sys.exit(app.exec_())
    

    PySide

    PySide implementation has QHttpMultiPart missing. The only way is to construct post data contents manually. Luckily, Python has its own libraries to create multipart HTTP requests. Here is what I've written:

    import sys
    from PySide import QtCore, QtGui, QtNetwork
    import requests
    
    def finished(reply):
      print "Finished: ", reply.readAll()
      app.quit()
    
    app = QtGui.QApplication(sys.argv)
    url = 'http://localhost:3000/qwertytest1'
    data = { 'text1': 'test1', 'text2': 'test2' }
    files = {'file1': open('/tmp/1.txt') }
    request = requests.Request('POST', url, data=data, files=files).prepare()
    request_qt = QtNetwork.QNetworkRequest(url)
    for header, value in request.headers.items():
      request_qt.setRawHeader(header, value)
    manager = QtNetwork.QNetworkAccessManager()
    manager.finished.connect(finished)
    request = manager.post(request_qt, request.body)
    
    sys.exit(app.exec_())
    

    Note that this method loads all file content in the memory. It's unacceptable if you're dealing with large files. python-requests module itself supports sending large files dynamically, but there is no way to use this functionality with Qt. You can just use python-requests without Qt if that is the case.

    0 讨论(0)
提交回复
热议问题