简体   繁体   中英

Dropbox API request token not working with Python 3?

I'm maintaining a Python application using the official Dropbox API. To ask the users to let my application use their Dropbox account, I use a small script using the DropboxSession class, which is clearly the same as the one we can find on this blog post :

# Include the Dropbox SDK libraries
from dropbox import client, rest, session

# Get your app key and secret from the Dropbox developer website
APP_KEY = '******'
APP_SECRET = '******'

# ACCESS_TYPE should be 'dropbox' or 'app_folder' as configured for your app
ACCESS_TYPE = 'app_folder'

sess = session.DropboxSession(APP_KEY, APP_SECRET, ACCESS_TYPE)
request_token = sess.obtain_request_token()
url = sess.build_authorize_url(request_token)

# Make the user sign in and authorize this token
print "url:", url
print "Please visit this website and press the 'Allow' button, then hit 'Enter' here."
# Python 2/3 compatibility
try:
    raw_input()
except NameError:
    input()
# This will fail if the user didn't visit the above URL
access_token = sess.obtain_access_token(request_token)

#Print the token for future reference
print access_token

While it's perfectly working with Python 2.7.6, it seems to fail because of Dropbox code in Python 3.4 (the raw_input problem having been dealt with). I get this error :

Traceback (most recent call last):
  File "/home/scylardor/.virtualenvs/onitu3/lib/python3.4/site-packages/dropbox/session.py", line 285, in _parse_token
    key = params['oauth_token'][0]
KeyError: 'oauth_token'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "get_access_token.py", line 12, in <module>
    request_token = sess.obtain_request_token()
  File "/home/scylardor/.virtualenvs/onitu3/lib/python3.4/site-packages/dropbox/session.py", line 185, in obtain_request_token
    self.request_token = self._parse_token(response.read())
  File "/home/scylardor/.virtualenvs/onitu3/lib/python3.4/site-packages/dropbox/session.py", line 287, in _parse_token
    raise ValueError("'oauth_token' not found in OAuth request.")
ValueError: 'oauth_token' not found in OAuth request.

Long story short, after having studied the faulty code, it seems that the Dropbox code searches for a string dictionary key, despite the fact that in Python 3, those keys become bytestrings (ie it lookups 'oauth_token' , which isn't here, instead of b'oauth_token' , which is here).

However, even after having fixed the code to see if that's the only issue, no luck, I get another error further in the procedure:

Traceback (most recent call last):
  File "get_access_token.py", line 25, in <module>
    access_token = sess.obtain_access_token(request_token)
  File "/home/scylardor/.virtualenvs/onitu3/lib/python3.4/site-packages/dropbox/session.py", line 214, in obtain_access_token
    response = self.rest_client.POST(url, headers=headers, params=params, raw_response=True)
  File "/home/scylardor/.virtualenvs/onitu3/lib/python3.4/site-packages/dropbox/rest.py", line 316, in POST
    return cls.IMPL.POST(*n, **kw)
  File "/home/scylardor/.virtualenvs/onitu3/lib/python3.4/site-packages/dropbox/rest.py", line 254, in POST
    post_params=params, headers=headers, raw_response=raw_response)
  File "/home/scylardor/.virtualenvs/onitu3/lib/python3.4/site-packages/dropbox/rest.py", line 227, in request
    raise ErrorResponse(r, r.read())
dropbox.rest.ErrorResponse: [401] 'Unauthorized'

So the faulty functions are sess.obtain_request_token() and sess.obtain_access_token(request_token) . And the Python 2.7 version works fine, but I'd like to keep Python 3 compatibility.

So, does anyone know how one's supposed to make it work in Python 3 ? Could it be deliberately broken in order to make people move on to new procedures ? I could have sworn it was working with Python 3, some time ago.

Thank you for your time if you have an idea :)

edit: It seems the Dropbox SDK just isn't fully Python 3-compatible yet. So, I guess there's nothing else to do than to wait for them to update the SDK.

尝试使用1.6版

$ pip install dropbox==1.6

Better than waiting for the SDK to be compatible, you can use (or contribute to and use) the "community" fork, dropbox-py3 ( here on github ).

(Those quotes are big quotes. For now it's just me coding this, and just the part I need, but everyone's welcome to help. I think it's mainly identifying the few parts that are missing a ".encode" because it's mixing bytes and strings.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM