Mime types of attachments uploaded to Trello
Asked by Adrian Sutton:

I'm attempting to upload MP3 attachments to a Trello card (using the API, with the Python Trello module). I'm taking care to make sure the mimeType is set to 'audio/mpeg3', and that the file is encoded as multipart/form-data.

The upload itself happens fine, and the response data shows that Trello thinks it's a MIME type of 'audio/mpeg3' as I specified.

However, looking at the card, the attachment doesn't appear as an MP3, just a generic link, meaning that when clicking on the attachment in the card, it thinks I want to download it (i.e. a generic file) rather than listen to it.

Can anyone explain what's happening here?


Answers:
author: Fabio Barbon
body: I've just noticed that this issue happens only for certain mime types. For instance image files (such as "image/jpeg") work as expected, but neither MP3s nor PDFs do.  
Also, note that mp3s uploaded via the GUI result as "audio/mp3" (via the get card attachments endpoint). And unfortunately no, it doesn't work even by "patching" the mime type in this way before posting :(

comments: author: Fabio Barbon
body: Ok, I think I've figured out the issue. Here's a snippet of the body multi-part data generated by the trello.com website when adding attachments:  

```
------WebKitFormBoundaryMpa8IFEcwGeZ3C67
Content-Disposition: form-data; name="token"

5360ecf0889ea2ef01811bc2/bIZEBmZCuwzhyYVrj75WEpC21t1lebRyWKRZgdjLWBZuBg4H92rpWqqthVuvDVdG
------WebKitFormBoundaryMpa8IFEcwGeZ3C67
Content-Disposition: form-data; name="file"; filename="funky-phone.mp3"
Content-Type: audio/mpeg


------WebKitFormBoundaryMpa8IFEcwGeZ3C67--
```

Not all http client libs include the "filename" entry. By manually adding it the attachment mime-type seems correct.  
For example, in PHP with Guzzle you need to explicitly add a "filename" attribute within the request:

```
'multipart' => [ 
  [ 'name' => 'name', 'contents' => $file->getName() ], 
  [ 'name' => 'token', 'contents' => $this::$trelloToken ],
  [ 'name' => 'file', 'contents' => $file->fopen('rb'), 'filename'=>$file->getName() ] 
]
```

<br />

Hope this helps.


author: Iain Dooley
body: [@Fabio Barbon](/t5/user/viewprofilepage/user-id/3924853) awesome! Keen to give this a try


author: Adrian Sutton
body: Thanks Fabio, will try


author: vaprio
body: Hey [@Fabio Barbon](/t5/user/viewprofilepage/user-id/3924853) !

How has the progress on this been? I'm using python and am not at all familiar with PHP. I was wondering if there's any way to apply your solution using a library such as requests, or if you could translate your solution into a curl request? Any help would be appreciated.

Thanks for looking into this!


author: vaprio
body: I've tried to pass the 'filename' attribute as a param to the request and also as a data key:

```
async def attach_card(self, card_id: str, file_bytes, file_name, mime):
? data = {'file': file_bytes, 'filename': file_name} // here
? headers = {"Accept": "application/json"}
? params = {'name': file_name, 'mimeType': mime, 'filename': file_name} // and here
? params.update(BASE_PARAMS)

? await self.session.post(
??? f"{BASE_URL}/cards/{card_id}/attachments",
??? params=params,
??? data=data,
??? headers=headers
  ) 
```

Neither works :(


author: Adrian Sutton
body: Here's what I got to work in the end (this is a method in a class handling everything related to Trello in my application, self._apikey and self._token are the REST credentials etc.)

```
def attachFileToCardID(self, trelloCardID, theFile, theName, theMIMEtype):
    resp = requests.post("https://trello.com/1/cards/{}/attachments".format(trelloCardID),
                          params={'key': self._apikey, 'token': self._token},
                          files={'file': (theName, open(theFile, 'rb'), theMIMEtype)})
    attachmentID = json.loads(resp.text)
    return attachmentID?
```


author: Adrian Sutton
body: Are there any devs from Atlassian here that can explain why this happens?..


author: Iain Dooley
body: [@Adrian Sutton](/t5/user/viewprofilepage/user-id/3905058) yep I've never been able to get Trello uploads to work via the API the same way they do if you upload via the app. What I concluded is that, internally, all attachments are just links and there's something that happens in the Trello interface to set "isUpload" to true and set the mimetype so the icon is displayed differently on the card, but that never happens in the API.

comments: author: Adrian Sutton
body: Thanks Iain


author: vaprio
body: \[object Object\]


Tags: attachment

mime

rest-api