Upload a large XML file with Python Requests library

前端 未结 3 864
猫巷女王i
猫巷女王i 2021-02-10 02:44

I\'m trying to replace curl with Python & the requests library. With curl, I can upload a single XML file to a REST server with the curl -T option. I have been unable to do

相关标签:
3条回答
  • 2021-02-10 03:09

    To PUT large files, don't read them into memory. Simply pass the file as the data keyword:

    xmlfile = open('trb-1996-219.xml', 'rb')
    headers = {'content-type': 'application/xml'}
    r = requests.put(url, data=xmlfile, headers=headers, auth=HTTPDigestAuth("*", "*"))
    

    Moreover, you were opening the file as unicode (decoding it from UTF-8). As you'll be sending it to a remote server, you need raw bytes, not unicode values, and you should open the file as a binary instead.

    0 讨论(0)
  • 2021-02-10 03:17

    i used requests in python to upload an XML file using the commands. first to open the file use open() file = open("PIR.xsd") fragment = file.read() file.close() copy the data of XML file in the payload of the requests and post it payload = {'key':'PFAkrzjmuZR957','xmlFragment':fragment} r = requests.post(URL,data=payload) to check the html validation code print (r.text)

    0 讨论(0)
  • 2021-02-10 03:23

    Digest authentication always requires you to make at least two request to the server. The first request doesn't contain any authentication data. This first request will fail with a 401 "Authorization required" response code and a digest challenge (called a nounce) to be used for hashing your password etc. (the exact details don't matter here). This is used to make a second request to the server containing your credentials hashed with the challenge.

    The problem is in the this two step authentication: your large file was already send with the first unauthorized request (send in vain) but on the second request the file object is already at the EOF position. Since the file size was also send in the Content-length header of the second request, this causes the server to wait for a file that will never be send.

    You could solve it using a requests Session and first make a simple request for authentication purposes (say a GET request). Then make a second PUT request containing the actual payload using the same digest challenge form the first request.

    sess = requests.Session()
    sess.auth = HTTPDigestAuth("*", "*")
    sess.get(url)
    headers = {'content-type': 'application/xml'}
    with codecs.open('trb-1996-219.xml', 'r', 'utf-8') as xmlfile:
        sess.put(url, data=xmlfile, headers=headers)
    
    0 讨论(0)
提交回复
热议问题