How to call Blob.Attach via REST API in Python?

Hello,

I am trying to use Python to POST data to the Nuxeo Automation API. Unfortunately I am unable to compose the “multipart/related” portion of the message correctly – I always receive the message “Failed to parse multipart request” with cause “Missing start boundary.”

Here is the code I've extracted:

Here is what the output looks like when sent to netcat:

This looks similar enough to the output at http://doc.nuxeo.com/display/NXDOC/REST+API that I am stumped.

Thank you for any help.

0 votes

1 answers

5890 views

ANSWER



Hello,

This worked for me:

1: Go and clone sfermigier source as suggested in Rest API documentation

2: Rewrite this method

 def _attach_blob(self, blob, **params):
    filename = os.path.basename(blob)

    container = MIMEMultipart("related",
            type="application/json+nxrequest",
            start="request")

    d = {'params': params}
    json_data = json.dumps(d)
    json_part = MIMEBase("application", "json+nxrequest")
    json_part.add_header("Content-ID", "request")
    json_part.set_payload(json_data)
    container.attach(json_part)

    ctype, encoding = mimetypes.guess_type(filename)
    if ctype:
        maintype, subtype = ctype.split('/', 1)
    else:
        maintype, subtype = "application", "binary"
    blob_part = MIMEBase(maintype, subtype)
    blob_part.add_header("Content-ID", "input")
    blob_part.add_header("Content-Transfer-Encoding", "binary")
    blob_part.add_header("Content-Disposition",
        "attachment;filename=%s" % filename)

    blob_part.set_payload(open(blob,"rb").read())
    container.attach(blob_part)

    # Create data by hand :(
    boundary = "====Part=%s=%s===" % (time.time, random.randint(0, 1000000000))
    headers = {
            "Accept": "application/json+nxentity, */*",
            "Authorization": self.auth,
            "Content-Type": 'multipart/related;boundary="%s";type="application/json+nxrequest";start="request"'
                % boundary,
    }
    data = "--" + boundary + "\r\n" \
            + json_part.as_string() + "\r\n" \
            + "--" + boundary + "\r\n" \
            + blob_part.as_string() + "\r\n" \
            + "--" + boundary + "--"

    req = urllib2.Request(self.root + "Blob.Attach", data, headers)
    try:
        resp = self.opener.open(req)
    except Exception, e:
        self._handle_error(e)
        raise

    s = resp.read()
    return s

3: Call the method:

session = Session(operationURI, user, password)
session._attach_blob('c:\\hop.pdf', document=aDocID)

Where aDocID is the UID of the document you want to fill in.

Notice that I may just not have found the proper way to make it work as given but my binary attachment went its way like this.

1 votes