I am trying to create a class in python which reads the access key/secret for dropbox and then downloads a file. The key/secret part is working alright, but I seem to be having a problem recognizing the client object, probably due to an issue with global vs local variables. I can't find my answer anywhere else.
Here's part of my code:
from dropbox import client, rest, session
class GetFile(object):
def __init__(self, file1):
self.auth_user()
def auth_user(self):
APP_KEY = 'xxxxxxxxxxxxxx'
APP_SECRET = 'xxxxxxxxxxxxxx'
ACCESS_TYPE = 'dropbox'
TOKENS = 'dropbox_token.txt'
token_file = open(TOKENS)
token_key,token_secret = token_file.read().split('|')
token_file.close()
sess = session.DropboxSession(APP_KEY,APP_SECRET, ACCESS_TYPE)
sess.set_token(token_key,token_secret)
client = client.DropboxClient(sess)
base, ext = file1.split('.')
f, metadata = client.get_file_and_metadata(file1)
out = open('/%s_COPY.%s' %(base, ext), 'w')
out.write(f.read())
And here's the error:
Traceback (most recent call last):
File "access_db.py", line 30, in <module>
start = GetFile(file_name)
File "access_db.py", line 6, in __init__
self.auth_user()
File "access_db.py", line 20, in auth_user
client = client.DropboxClient(sess)
UnboundLocalError: local variable 'client' referenced before assignment
I'm new-ish to python so let me know if there are other obvious things I may be doing wrong.
You imported the dropbox.client
module into a your module scope as client
, but you also have a local variable client
in your .auth_user()
method.
When python sees an assignment (such as client =
) in a function when compiling, it marks that name as a local variable. At this point your import of the client
module is doomed, it is no longer visible in your function under that name.
Next, in python's eyes you are trying to access that local variable client
in the function; you are trying to get the attribute DropboxClient
from it, but you haven't yet assigned anything to the variable client
at that moment. So the UnboundLocal
exception is thrown.
The workaround is to either not use client
as a local variable, to import the top-level dropbox
module instead of it's submodules, then refer to it's submodules with the full dropbox.client
, etc. paths, or thirdly, by giving the client
module a new name:
Don't use client
as a local:
dbclient = client.DropboxClient(sess)
# ...
f, metadata = dbclient.get_file_and_metadata(file1)
Import the dropbox
module directly:
import dropbox
# ...
sess = dropbox.session.DropboxSession(APP_KEY,APP_SECRET, ACCESS_TYPE)
# ...
client = dropbox.client.DropboxClient(sess)
Provide an alias for the client
module:
from dropbox import session, rest
from dropbox import client as dbclient
# ...
client = dbclient.DropboxClient(sess)