upload files through http post in Pyside/PyQt

痴心易碎 提交于 2019-11-30 17:53: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 code samples I've found don't work.(actually they were in c++ and I couldn't get them work)

server is using Apache for webserver

I ask a question before and I got a pretty good answer,so I'm using that uploader in here,code just not work for uploading file through http post

so can anyone first of all tell me what I need to do to upload file through HTTP post and then it would be great if you could give me a sample (simple code to upload on a localhost will be enough,I just want to see how to do that and how uploading works)


回答1:


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.



来源:https://stackoverflow.com/questions/21158102/upload-files-through-http-post-in-pyside-pyqt

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!