-->

Create Docusign envelope with REST API using docum

2019-07-27 10:12发布

问题:

I am following the API walkthrough for creating an envelopes here using Python: http://iodocs.docusign.com/APIWalkthrough/requestSignatureFromDocument

The process works fine with a simple text file. For instance, if I create a text file "file.txt", I can call:

with open('file.txt', 'r') as f:
    file_stream = f.read()

This file_stream works fine with my existing code:

    def makeBody(file_stream, envelopeDef):
    body = "\r\n\r\n--BOUNDARY\r\n" + \
            "Content-Type: application/json\r\n" + \
            "Content-Disposition: form-data\r\n" + \
            "\r\n" + \
            envelopeDef + "\r\n\r\n--BOUNDARY\r\n" + \
            "Content-Type: application/pdf\r\n" + \
            "Content-Disposition: file; filename=\"thesis.pdf\"; documentId=1\r\n" + \
            "\r\n" + \
            file_stream + "\r\n" + \
            "--BOUNDARY--\r\n\r\n"
    return body

def envelope(res):
        envelopeDef = "{\"emailBlurb\":\"Please sign this.\"," + \
            "\"emailSubject\":\"Demo Docusign\"," + \
            "\"documents\":[{" + \
            "\"documentId\":\"1\"," + \
            "\"name\":\"test_doc.pdf\"}]," + \
            "\"recipients\":{" + \
            "\"signers\":[{" + \
            "\"email\":\"email@email.io\"," + \
            "\"name\":\"Name\"," + \
            "\"recipientId\":\"1\"," + \
            "\"clientUserId\":\"1\"," + \
            "}]}," + \
            "\"status\":\"created\"}"
    local_header = res['headers'].copy()
    local_header['Content-Type'] = 'multipart/form-data; boundary=BOUNDARY'
    url = "%s/envelopes" % res['base_url']

    file_stream = ''
    with open('thesis.pdf', 'rb') as f:
        file_stream = f.read()
    file_stream = str(file_stream)
    body = DocusignSignerView.makeBody(file_stream, envelopeDef)
    resp = requests.post(url, headers=local_header, data=body)

This code yields a 400 BAD Request ("data cannot be converted").

From what I've found online, I need to plugin the bytes representation of the file INTO the body of the request. NOT the string representation ( str(file_stream) ).

How do I plug in the bytes representation without first converting it into a string since I am concatenating it?

Any help would be appreciated.

回答1:

The solution was to send everything into bytes:

    def makeBody(file_stream, envelopeDef):
    reqBody = "\r\n\r\n--BOUNDARY\r\n" + \
            "Content-Type: application/json\r\n" + \
            "Content-Disposition: form-data\r\n" + \
            "\r\n" + \
            envelopeDef + "\r\n\r\n--BOUNDARY\r\n" + \
            "Content-Type: application/pdf\r\n" + \
            "Content-Disposition: file; filename=\"thesis.pdf\"; documentId=1\r\n" + \
            "\r\n"
    reqBody2 = "\r\n" + \
            "--BOUNDARY--\r\n\r\n"

    body = b"".join([bytes(reqBody, 'utf-8'), file_stream, bytes(reqBody2, 'utf-8')])
    return body

I'm sorely disappointed in Docusign support and their documentation for not showing in Python how to solve this. They only show the .txt file case. I have also emailed support and talked to them on Live Chat to make this clearer, but they have not responded.