Upload attachment using Insight REST API

I see the documentation for object attachments but it only specifies GET methods. Is there a means of POSTing attachments via the API?

1 answer

1 accepted

This widget could not be displayed.

This should be possible, although I don't have much to go on to help you on this, more then the endpoint to use and what it consumes. So setting this up might be a bit tricky.

/rest/insight/1.0/attachments/object/\{objectid}

Method: POST

 
Path Param                  Type                             Description

objectid                         Integer                          The id of the object where to add the attachment

file                                Collection<FilePart>     The fileparts for the file

encodedComment       FilePart                         The comment for the File

 

Best Regards
Alexander

Are you sure that's a supported endpoint? I have tested this multiple ways and can't get it to work. What's interesting, is I can get it to work attaching via REST API to a JIRA, just not to an Insight object. So, I think my POST formatting is correct. 

Below is my code for reference. 

def loadAttachment():

headers = {'Authorization': 'Basic %s' % encoded_credentials.decode("ascii"), 'X-Atlassian-Token' : 'nocheck'}
print('loadAttachmentHeader: ', headers)

files = {'file': open('tmp.txt', 'rb')}
jiraUrl = baseUrl + '/api/latest/issue/BO-17808/attachments'

#Post file to JIRA (this works)#
r = requests.post(jiraUrl, headers=headers, verify=False, files=files)
print(r)


#Post file to Insight object (this doesn't work = 500 error)#
insightUrl = baseURL + '/insight/1.0/attachments/object/2850/'
r = requests.post(insightUrl, headers=headers, verify=False, files=files)
print(r)

Hi Chad,

Yes, the endpoint I'm referring to is what we use ourself and the signature hasn't changed.

Have you looked at the atlassian-jira.log if it might have logged any errors?

 

Best Regards
Alexander

The log is throwing a nullPointerException:

2017-11-02 08:37:09,351 http-nio-9000-exec-19 ERROR daily-jira-s 517x68317x1 pz6y2m 10.2.18.12,10.105.45.11 /rest/insight/1.0/attachments/object/2850 [c.s.j.spi.container.ContainerResponse] Mapped exception to response: 500 (Internal Server Error)
com.riadalabs.jira.plugins.insight.channel.web.api.rest.exception.ServerErrorWebException: java.lang.NullPointerException
at com.riadalabs.jira.plugins.insight.channel.web.api.rest.services.AttachmentResource.addAttachments(AttachmentResource.java:156)

Hi Chad,

It seems like either the file or the encodedComment is null, could that be the case? Both needs to be provided, and the comment can be empty, but not null.

Best Regards
Alexander 

That did it! I was missing the encodedComment. Didn't realize that was required. In case it helps anyone else along the way here's a working version in Python:

 

def loadAttachment():

headers = {'Authorization': 'Basic %s' % encoded_credentials.decode("ascii"), 'X-Atlassian-Token' : 'no-check'}

print('loadAttachmentHeader: ', headers)

multipart_form_data = {
'file': open('tmp.txt', 'rb'),
'encodedComment': ''
}

r = requests.post(insightBaseURL + 'attachments/object/1325', headers=headers, verify=False, files=multipart_form_data)
print(r)
print(r.text)

@Alexander Sundström - so close but I'm still having an issue. 

The file appears to be uploaded (shows name, link, bytes, etc.) but when clicked on it's throwing an error. I have manually uploaded the same file as I'm trying to do through the API and the manual file works. When I look at the attachment GET method on the object everything looks the same between the two attachments (below) but only the manual one will open. 

{
"id": 27,
"author": "cpeters",
"mimeType": "application/pdf",
"filename": "InsightQuote.pdf",
"filesize": "16.5 kB",
"created": "03/Nov/17 10:18 AM",
"comment": "file uploaded manually",
"commentOutput": "file uploaded manually",
"url": "https://jira-dev.hbk.com/plugins/servlet/com.riadalabs.jira.plugins.insight/attachment/27/InsightQuote.pdf"
},
{
"id": 28,
"author": "cpeters",
"filename": "InsightQuote.pdf",
"filesize": "16.5 kB",
"created": "03/Nov/17 10:21 AM",
"comment": "file uploaded by shredder",
"commentOutput": "file uploaded by shredder",
"url": "https://jira-dev.hbk.com/plugins/servlet/com.riadalabs.jira.plugins.insight/attachment/28/InsightQuote.pdf"
}

Error:

2017-11-03 10:23:37,838 http-nio-9000-exec-10 ERROR [c.a.j.web.servlet.InternalServerErrorServlet] {errorId=0530a290-29da-4296-98e2-9805c23d811f, interpretedMsg=, cause=java.lang.NullPointerException, stacktrace=java.lang.NullPointerException
at com.opensymphony.module.sitemesh.filter.HttpContentType.<init>(HttpContentType.java:15) [sitemesh-2.5-atlassian-11.jar:?]
at com.opensymphony.sitemesh.compatability.PageParser2ContentProcessor.build(PageParser2ContentProcessor.java:46) [sitemesh-2.5-atlassian-11.jar:?]
at com.opensymphony.sitemesh.webapp.ContentBufferingResponse.getContent(ContentBufferingResponse.java:69) [sitemesh-2.5-atlassian-11.jar:?]
at com.opensymphony.sitemesh.webapp.SiteMeshFilter.obtainContent(SiteMeshFilter.java:183) [sitemesh-2.5-atlassian-11.jar:?]......

Hi Chad, Thanks for the update, 

From what I can see, when you upload manually you also get the "mimeType": "application/pdf", but that is missing from the one that you upload using the script.

I'm not sure if this is something that is set in the file parts sent to the server or not, but I guess that this is related to the error.

Best Regards
Alexander

Thanks. I was actually able to get this all working over the weekend. It was an issue with the multipart content type setup, and more specifically the mime type definition. Below is a (newly) working example for anyone interested and for future reference. 

import mimetypes


def loadAttachment(fileName, fileLocation, objectId):
mimetypes.init()
attachment = fileLocation + fileName
attachmentType = mimetypes.guess_type(attachment, strict=True)

m = MultipartEncoder(
fields={'encodedComment': 'file uploaded by shredder'.encode('utf-8'), 'file': (fileName.replace('\\',''), open(attachment, 'rb'), attachmentType[0])}
)

headers = {'Authorization': 'Basic %s' % encoded_credentials.decode("ascii"), 'X-Atlassian-Token' : 'no-check', 'Content-Type': m.content_type}
r = requests.post(insightBaseURL + 'attachments/object/' + str(objectId), headers=headers, verify=False, data=m)

Suggest an answer

Log in or Sign up to answer
Atlassian Summit 2018

Meet the community IRL

Atlassian Summit is an excellent opportunity for in-person support, training, and networking.

Learn more
Community showcase
Published Jul 25, 2018 in Marketplace Apps

Jira Cloud and Bitbucket Cloud Integration with Microsoft Teams

One of the newest products in the Microsoft family - Microsoft Teams,  is a chat-based hub for teamwork that integrates all the people, content, and tools your team needs to be more engaged and ...

733 views 0 3
Read article

Atlassian User Groups

Connect with like-minded Atlassian users at free events near you!

Find a group

Connect with like-minded Atlassian users at free events near you!

Find my local user group

Unfortunately there are no AUG chapters near you at the moment.

Start an AUG

You're one step closer to meeting fellow Atlassian users at your local meet up. Learn more about AUGs

Groups near you