badsuns / google-api-python-client

Automatically exported from code.google.com/p/google-api-python-client
Other
0 stars 0 forks source link

oauth2client on GCE throws AttributeError no attribute redirect_uri #342

Open GoogleCodeExporter opened 8 years ago

GoogleCodeExporter commented 8 years ago
[Use this form for both apiclient and oauth2client issues]

What steps will reproduce the problem?
1. I am porting an Python 2.7 script to a new GCE
2. The script runs on local laptop and connects to BigQuery perfectly
3. The script throws error when run on GCE instance

What is the expected output? What do you see instead?
When run on local laptop all is good. But, when run on a new GCE which I build 
2 hours ago with the latest client API, the script throws the following error 
after the client creates the flow:

_HAVE_FLOW: True
TEST _HAVE_FLOW: True
have storage, next use it to retrieve credential from file: 
bigquery_credentials.dat
ERROR - credentials is None
Run oauth2 flow with default arguments
 - Write_CVS_Records_to_BigQuery() Unexpected error: <type 'exceptions.AttributeError'>
Write_CVS_Records_to_BigQuery() AttributeError: 'NoneType' object has no 
attribute 'redirect_uri'
CLOUDSDK_CONFIG: /home/.../.config/gcloud
GOOGLE_APPLICATION_CREDENTIALS: 
client_secret_Xkjduoiyewryq3.apps.googleusercontent.com.json
GCLOUD_DATASET_ID: applied-algebra-93003
------------------------------------------------------------
Traceback (most recent call last):
  File "/dump/CI_SA_load_bq.py", line 221, in Write_CVS_Records_to_BigQuery
    credentials = tools.run_flow(_FLOW, storage, tools.argparser.parse_args([]))
  File "/usr/lib/python2.7/site-packages/oauth2client/util.py", line 137, in positional_wrapper
    return wrapped(*args, **kwargs)
  File "/usr/lib/python2.7/site-packages/oauth2client/tools.py", line 190, in run_flow
    flow.redirect_uri = oauth_callback
AttributeError: 'NoneType' object has no attribute 'redirect_uri'
------------------------------------------------------------
Traceback (most recent call last):
  File "/dump/CI_SA_load_bq.py", line 266, in <module>
    Write_CVS_Records_to_BigQuery()
  File "/dump/CI_SA_load_bq.py", line 221, in Write_CVS_Records_to_BigQuery
    credentials = tools.run_flow(_FLOW, storage, tools.argparser.parse_args([]))
  File "/usr/lib/python2.7/site-packages/oauth2client/util.py", line 137, in positional_wrapper
    return wrapped(*args, **kwargs)
  File "/usr/lib/python2.7/site-packages/oauth2client/tools.py", line 190, in run_flow
    flow.redirect_uri = oauth_callback
AttributeError: 'NoneType' object has no attribute 'redirect_uri'
 ~]$ 

What version of the product are you using? On what operating system?
The latest verion installed by pip. The most recent Centos version of GCE

Please provide any additional information below.

More than likely this is a configuration problem on the GCE; I've likely missed 
adding some setting required on a GCE instance. Here's the 2 suspect methods 
related to the AttributeError:

_SECRET_FILE_NAME='client_secret_devgce2.apps.googleusercontent.com.json'
_REDIRECT_URI='urn:ietf:wg:oauth:2.0:oob'

# Set up flow object to be used for authenticating the client
def Get_Client_Flow():
    try:
        if os.path.exists(_SECRET_FOLDER_NAME):
            print "_SECRET_FOLDER_NAME: %s exists"%(str(_SECRET_FOLDER_NAME))
            _SECRET_FILE = os.path.join(_SECRET_FOLDER_NAME,_SECRET_FILE_NAME)
            if os.path.isfile(_SECRET_FILE):               
                print "_SECRET_FILE: %s exists"%(_SECRET_FILE)                
                _HAVE_SECRET_FILE=True
                _FLOW = flow_from_clientsecrets(_SECRET_FILE,
                                       scope='https://www.googleapis.com/auth/bigquery',
                                       redirect_uri=_REDIRECT_URI)
                if not _FLOW==None:
                    _HAVE_FLOW.append(True)
                    print ("_HAVE_FLOW: %s")%(_HAVE_FLOW[0])
                else:
                    _HAVE_FLOW.append(False)
                    print ("_HAVE_FLOW: %s")%(_HAVE_FLOW[0])
            else:
                print "_SECRET_FILE: %s does not exist"%(str(_SECRET_FILE)) 
        else:
            print "_SECRET_FOLDER_NAME: %s does not exist"%(str(_SECRET_FOLDER_NAME))

    except Exception, inst:
        print "\n - Get_Client_Flow() Unexpected error: %s"%(str(sys.exc_info()[0]))
        if isinstance(inst,ValueError):
            print "Get_Client_Flow() - ValueError: %s\n"%(inst.message)
        if isinstance(inst,AttributeError):
            print "Get_Client_Flow() - AttributeError: %s\n"%(inst.message)
        if isinstance(inst,TypeError):
            print "Get_Client_Flow() - TypeError: %s\n"%(inst.message)      
        #print "\nPYTHONPATH: %s" % (os.environ['PYTHONPATH'])
        print "CLOUDSDK_CONFIG: %s" %  (os.environ['CLOUDSDK_CONFIG'])
        print "GOOGLE_APPLICATION_CREDENTIALS: %s"%(os.environ['GOOGLE_APPLICATION_CREDENTIALS'])
        print "GCLOUD_DATASET_ID: %s"%(os.environ['GCLOUD_DATASET_ID'])    
        print '-'*60
        traceback.print_exc(file=sys.stdout)
        print '-'*60                            
        raise  

def Write_CVS_Records_to_BigQuery():
    try:
        print "\n Write_CVS_Records_to_BigQuery()"
        '''
        Connect to BigQuery Service API
        '''
        Get_Client_Flow()

        if _HAVE_FLOW[0]:
            print ("TEST _HAVE_FLOW: %s")%(_HAVE_FLOW[0])
            #_FLOW.redirect_uri = _REDIRECT_URI

            # GET oauth2client STORAGE
            storage = Storage('bigquery_credentials.dat')
            if storage is None:
                print "storage is None, error creating means for retrieving credential from file: %s"%('bigquery_credentials.dat')
            else:
                print "have storage, next use it to retrieve credential from file: %s"%('bigquery_credentials.dat')
                credentials = storage.get()
                if credentials is None:
                    print "ERROR - credentials is None"

            if credentials is None or credentials.invalid:
                print "Run oauth2 flow with default arguments"
                # Run oauth2 flow with default arguments.
                credentials = tools.run_flow(_FLOW, storage, tools.argparser.parse_args([]))

            # create the HTTP object to handle your requests, and authorize with your credentials
            http = httplib2.Http()
            http = credentials.authorize(http)

            # create the service object for interacting with BigQuery
            _BIGQUERY_SERVICE = build('bigquery', 'v2', http=http)

            print ("BEGIN call to loadTable()")
            try:
                #print "did not call loadTable()"
                loadTable(_BIGQUERY_SERVICE, _PROJECT_NUMBER, _BIGQUERY_DATASET_ID, _TARGET_TABLE_ID, _SOURCE_CSV)

            except HttpError as err:
                print 'Write_CVS_Records_to_BigQuery() HttpError:', pprint.pprint(err.resp)
                print 'Write_CVS_Records_to_BigQuery()- HttpError content: %s: '%(err.content)
                print 'Write_CVS_Records_to_BigQuery() HttpError uri - loadTable(): ', pprint.pprint(err.uri)

            except AccessTokenRefreshError:
                print ("Write_CVS_Records_to_BigQuery() - Credentials have been revoked or expired, please re-run"
                       "the application to re-authorize")
        else:
            print ("TEST _HAVE_FLOW: %s")%(_HAVE_FLOW[0])

    except Exception, inst:
        print "\n - Write_CVS_Records_to_BigQuery() Unexpected error: %s"%(str(sys.exc_info()[0]))
        if isinstance(inst,ValueError):
            print "Write_CVS_Records_to_BigQuery() ValueError: %s\n"%(inst.message)
        if isinstance(inst,AttributeError):
            print "Write_CVS_Records_to_BigQuery() AttributeError: %s\n"%(inst.message)
        if isinstance(inst,TypeError):
            print "Write_CVS_Records_to_BigQuery()TypeError: %s\n"%(inst.message)      
        #print "\nPYTHONPATH: %s" % (os.environ['PYTHONPATH'])
        print "CLOUDSDK_CONFIG: %s" %  (os.environ['CLOUDSDK_CONFIG'])
        print "GOOGLE_APPLICATION_CREDENTIALS: %s"%(os.environ['GOOGLE_APPLICATION_CREDENTIALS'])
        print "GCLOUD_DATASET_ID: %s"%(os.environ['GCLOUD_DATASET_ID'])    
        print '-'*60
        traceback.print_exc(file=sys.stdout)
        print '-'*60                            
        raise

 This is not likely, in my view, a bug with the API, but a matter of an omitted setting in the code or in the .bashrc file. The only difference in the code that runs on the laptop and the code that fails to run on the GCE is the new addition of _REDIRECT_URI (when creating the flow object)

Any suggestions to fix this mis-configuration are appreciated.

Original issue reported on code.google.com by ccliff...@archipelagois.com on 12 May 2015 at 9:57

GoogleCodeExporter commented 8 years ago
I edited the client secret file to contain "redirect_uris":["http://localhost", 
"urn:ietf:wg:oauth:2.0:oob"], and I assigned these to the _REDIRECT_URI array 
as well, but the same error is thrown.

Original comment by ccliff...@archipelagois.com on 12 May 2015 at 11:31