Forum Discussion

jeffshurtliff's avatar
5 years ago

Getting 403 response when creating message with attachment using API v2 and Python

When creating messages using the Community API v2 and the Python requests library, it works fine when not trying to upload an attachment, as shown in the sanitized excerpt below.

 

 

>>> headers = {
    'li-api-session-key': 'XXX-XXXXXXXXXXXXXXX_XXXXXXXXXX-XXXXXXXXXXXXX',
    'Content-Type': 'application/json'
}
>>> payload = {
    'data': {
        'type': 'message',
        'board': {
            'id': 'product-knowledge-base'
        },
        'body': 'This is an <b>API TEST</b> done in Python <i>without</i> an attached file.',
        'subject': 'API Test without Attachment'
    }
}
>>> uri = 'https://khoros-stage.example.com/api/2.0/messages'
>>> response = requests.post(uri, data=json.dumps(payload, default=str), headers=headers)
>>> response
{
    'status': 'success',
    'message': '',
    'http_code': 200,
    'data': {
        'type': 'message',
        'id': '112',
        'href': '/messages/112',
        # ---SNIP---
    }
}

 

 

 

However, when I try to create a message with an attachment (per the documentation) I am getting an HTTP Status 403 response saying Access to the specified resource has been forbidden, as shown below.

 

 

>>> headers = {
    'li-api-session-key': 'XXX-XXXXXXXXXXXXXXX_XXXXXXXXXX-XXXXXXXXXXXXX',
    'Content-Type': 'multipart/form-data'
}
>>> message_json = {
    "data": {
        "type": "message",
        "board": {
            "id": "product-knowledge-base"
        },
        "body": "This is an <b>API TEST</b> done in Python with an attached file.",
        "subject": "API Test with Attachment",
        "attachments": {
            "list_item_type": "attachment",
            "items": [
                {
                    "type": "attachment",
                    "field": "attachment1",
                    "filename": "feedparser.pdf"
                }
            ]
        }
    }
}
>>> payload = {
    'api.request': (None, json.dumps(message_json, default=str)),
    'attachment1': ('feedparser.pdf', open('C:\\Users\\someuser\\Downloads\\feedparser.pdf', 'rb'))
}
>>> uri = 'https://khoros-stage.example.com/api/2.0/messages'
>>> response = requests.post(uri, files=payload, headers=headers)
>>> response
<Response [403]>

>>> response.text
'<html><head><title>Error report</title><style><!--H1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} H2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} H3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} B {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} P {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}A {color : black;}A.name {color : black;}HR {color : #525D76;}--></style> </head><body><h1>HTTP Status 403 - </h1><HR size="1" noshade="noshade"><p><b>type</b> Status report</p><p><b>message</b> <u></u></p><p><b>description</b> <u>Access to the specified resource has been forbidden.</u></p></body></html>'

 

 

I've confirmed that the maximum file size for attachments in our stage environment is 5242880 bytes (5MB) and the attachment is only about 375kb.  I'm also performing the API call with a full admin user.

Does anyone have any idea what I could be doing wrong or why I would be getting that error?  

Thanks!!

  • WillB's avatar
    WillB
    5 years ago

    jeffshurtliff I got it working with the following code: 

     

    import requests
    
    headers = {
        'li-api-session-key': 'XXXXXXXXXX_XXXXXXXXXXX_XXXXXXXXXXXX',
    }
    
    files = {
        'api.request': (None, '{\n"data":{\n"type":"message",\n"subject":"This is the message subject",\n"board":{\n"type":"board",\n"id":"KB1"\n},\n"attachments":{\n"list_item_type":"attachment",\n"items":[\n{\n"type":"attachment",\n"field":"attachment1",\n"filename":"pdf1.PDF"\n},\n{\n"type":"attachment",\n"field":"attachment2",\n"filename":"pdf2.PDF"\n}\n]\n}\n}\n}'),
        'attachment1': ('/Users/will.bowen/Documents/pdf1.PDF', open('/Users/will.bowen/Documents/pdf1.PDF', 'rb')),
        'attachment2': ('/Users/will.bowen/Documents/pdf2.PDF', open('/Users/will.bowen/Documents/pdf2.PDF', 'rb')),
    }
    
    response = requests.post('https://rsalink-stage.rsa.com/api/2.0/messages', headers=headers, files=files)
    
  • WillB's avatar
    WillB
    Khoros Alumni (Retired)

    The error log is indicating the issue may be related to how the message is encoded. Specifically, the message is being rejected because no multipart boundary was found. I'm not too familiar with how python encodes api requests, but if you are able to successfully post a message with an attachment with curl or postman, you may want to double check how request.posts() is handling the attachments.

    • Thanks WillB! Is that error log something that I have access to view or is it only accessible to Khoros employees?

      • WillB's avatar
        WillB
        Khoros Alumni (Retired)

        Unfortunately, it is only accessible to Khoros employees.