0

I'm trying to send a file using Pushbullet following their API docs. This is my function:

def push_file(AccessToken, file_name):
    f = open(file_name, 'rb')
    file_type = mimetypes.guess_type(file_name)[0]

    print("Uploading {0}...".format(file_name))
    try:
        data = {
            'file_name': file_name, 
            'file_type' : file_type
        }

        resp = requests.post(UPLOAD_REQUEST_URL, data=data, auth=(AccessToken, '')).json()
        if resp.get('error') != None:
            print("Error: {0}".format(resp.get('error')['message']))
            return

        file_url = resp.get('file_url')
        print(file_url)
        resp = requests.post(resp.get('upload_url'), data=resp.get('data'), auth=(AccessToken, ''), files={'file': f})

        data = { 
            'type' : 'file', 
            'file_name' : file_name, 
            'file_type' : file_type, 
            'file_url' : file_url, 
            'body' : ''
        }
        resp = requests.post(PUSH_URL, data=data, auth=(AccessToken, '')).json()


    except requests.exceptions.ConnectionError:
        traceback.print_exc()
    f.close()

But I keep getting:

requests.exceptions.ConnectionError: HTTPSConnectionPool(host='s3.amazonaws.com', port=443): Max retries exceeded with url: /pushbullet-uploads (Caused by <class 'ConnectionResetError'>: [Errno 104] Connection reset by peer)

If I use another AccessToken I still get this error, even if it's the first time I post to that url.

andrew
  • 3,879
  • 4
  • 25
  • 43

2 Answers2

2

The upload process is unfortunately not very good and will hopefully be improved soon. It is the one request that does not obey the JSON rule. There is a curl example that shows this (https://docs.pushbullet.com/#upload-request), but understanding curl syntax is basically impossible.

Here's an example that I just typed up and seems to work:

import requests
import json

ACCESS_TOKEN = '<your access token here>'
resp = requests.post('https://api.pushbullet.com/v2/upload-request', data=json.dumps({'file_name': 'image.jpg'}), headers={'Authorization': 'Bearer ' + ACCESS_TOKEN, 'Content-Type': 'application/json'})
if resp.status_code != 200:
    raise Exception('failed to request upload')
r = resp.json()
resp = requests.post(r['upload_url'], data=r['data'], files={'file': open('image.jpg', 'rb')})
if resp.status_code != 204:
    raise Exception('failed to upload file')
print r['file_name'], r['file_type'], r['file_url']
Chris Pushbullet
  • 1,039
  • 9
  • 10
  • Thank you for this! Note to others: you have to add the final push line after Chris's code to actually make the push. For those having problems like "http://stackoverflow.com/questions/29134512/insecureplatformwarning-a-true-sslcontext-object-is-not-available-this-prevent" please follow the guide here: https://github.com/pyca/cryptography/issues/1981 That is manually install the required utilities like cffi, enum34, ipaddress, idna, pycparser, cryptography. – Sujay Phadke Oct 04 '16 at 05:01
0

According to the Pusbullet API

All POST requests should be over HTTPS and use a JSON body with the Content-Type header set to "application/json".

Try changing your requests.post calls like so:

resp = requests.post(UPLOAD_REQUEST_URL, json=data, auth=(AccessToken, '')).json()

Use json=data instead of data=data. Requests will automatically set Content-Type to application/json.

Kedar
  • 1,648
  • 10
  • 20
  • I can't use json=data, I think the version of requests installed on my computer is too old. I also tried to set manually headers={'Content-type': 'application/json'} but I keep getting the same result... – andrew Mar 07 '15 at 20:02
  • Try updating requests? `pip install requests==2.5.3` – Kedar Mar 08 '15 at 02:23