pythonpython-3.xpython-requeststrello

Downloading an attachment from Trello cards


I am trying to download all the attachments from my cards on a Trello board using py-trello.

Here is the sample code (private information removed):

from trello import TrelloClient
import requests

personal_token = ''
account_token = ''

client = TrelloClient(api_key=personal_token, api_secret=account_token)

board = client.get_board('')

cards = board.all_cards()
for card in cards:
    for attachment in card.get_attachments():
        response = requests.get(attachment.url)

        if response.status_code == 200:
               with open(attachment.name, 'wb') as file:
                   file.write(response.content)
        else:
            print(response.status_code, response.text)
    
        break
    break

The issue is that I get 401 Unauthorised error when I try to get the URL using requests. I've tried adding basic auth like so:

basic = HTTPBasicAuth(personal_token, account_token)

Same issue. I've also tried adding it to the URL like so:

url = f'{url}?key={personal_token}&token={account_token}'

But it also fails. I had a look at the py-trello code but I wasn't able to easily see if it has a download attachment function.


Solution

  • The issue is the tokens have to be sent in a header. The filename has to be gotten from the url as well.

    Here is the updated code:

    from trello import TrelloClient
    import requests
    
    personal_token = ''
    account_token = ''
    
    client = TrelloClient(api_key=personal_token, api_secret=account_token)
    
    board = client.get_board('')
    
    headers = {
        "Authorization": f'OAuth oauth_consumer_key="{personal_token}", oauth_token="{account_token}"'
    }
    
    cards = board.all_cards()
    for card in cards:
        for attachment in card.get_attachments():
            response = requests.get(attachment.url)
            file_name = attachment.url.split('/')[-1]
    
            if response.status_code == 200:
                   with open(file_name, 'wb') as file:
                       file.write(response.content)
            else:
                print(response.status_code, response.text)
        
            break
        break