1515
1616from adwords_downloader import config
1717from googleads import adwords , oauth2 , errors
18- from oauth2client import client as oauth2_client
1918
19+ from google_auth_oauthlib .flow import InstalledAppFlow
20+ from oauthlib .oauth2 .rfc6749 .errors import InvalidGrantError
2021
2122
2223class PerformanceReportType (Enum ):
@@ -399,7 +400,7 @@ def _download_adwords_report(api_client: AdWordsApiClient,
399400
400401 logging .warning (('Error HTTP #{e.code} Failed attempt #{retry_count} for report with settings:\n '
401402 '{report_filter}\n '
402- 'Retrying...' ).format (e = e ,retry_count = retry_count ,
403+ 'Retrying...' ).format (e = e , retry_count = retry_count ,
403404 report_filter = report_filter ))
404405 time .sleep (retry_count * config .retry_backoff_factor ())
405406 else :
@@ -415,32 +416,63 @@ def _download_adwords_report(api_client: AdWordsApiClient,
415416 raise e
416417
417418
419+ class ClientConfigBuilder (object ):
420+ """Helper class used to build a client config dict used in the OAuth 2.0 flow."""
421+
422+ _DEFAULT_AUTH_URI = 'https://accounts.google.com/o/oauth2/auth'
423+ _DEFAULT_TOKEN_URI = 'https://accounts.google.com/o/oauth2/token'
424+ CLIENT_TYPE_WEB = 'web'
425+ CLIENT_TYPE_INSTALLED_APP = 'installed'
426+
427+ def __init__ (self , client_type = None , client_id = None , client_secret = None ,
428+ auth_uri = _DEFAULT_AUTH_URI , token_uri = _DEFAULT_TOKEN_URI ):
429+ self .client_type = client_type
430+ self .client_id = client_id
431+ self .client_secret = client_secret
432+ self .auth_uri = auth_uri
433+ self .token_uri = token_uri
434+
435+ def Build (self ):
436+ """Builds a client config dictionary used in the OAuth 2.0 flow."""
437+ if all ((self .client_type , self .client_id , self .client_secret ,
438+ self .auth_uri , self .token_uri )):
439+ client_config = {
440+ self .client_type : {
441+ 'client_id' : self .client_id ,
442+ 'client_secret' : self .client_secret ,
443+ 'auth_uri' : self .auth_uri ,
444+ 'token_uri' : self .token_uri
445+ }
446+ }
447+ else :
448+ raise ValueError ('Required field is missing.' )
449+
450+ return client_config
451+
452+
418453def refresh_oauth_token ():
419454 """Retrieve and display the access and refresh token."""
420455
421- flow = oauth2_client .OAuth2WebServerFlow (
422- client_id = config .oauth2_client_id (),
423- client_secret = config .oauth2_client_secret (),
424- scope = ['https://www.googleapis.com/auth/adwords' ],
425- user_agent = 'Ads Python Client Library' ,
426- redirect_uri = 'urn:ietf:wg:oauth:2.0:oob' )
456+ client_config = ClientConfigBuilder (
457+ client_type = ClientConfigBuilder .CLIENT_TYPE_WEB , client_id = config .oauth2_client_id (),
458+ client_secret = config .oauth2_client_secret ())
459+ flow = InstalledAppFlow .from_client_config (client_config .Build (),
460+ scopes = ['https://www.googleapis.com/auth/adwords' ])
461+ flow .redirect_uri = 'urn:ietf:wg:oauth:2.0:oob'
462+ authorize_url , _ = flow .authorization_url (prompt = 'consent' )
427463
428- authorize_url = flow .step1_get_authorize_url ()
429-
430- print (('Log into the Google Account you use to access your AdWords account '
431- 'and go to the following URL: \n {}\n ' .format (authorize_url )))
464+ print ('Log into the Google Account you use to access your AdWords account '
465+ 'and go to the following URL: \n %s\n ' % authorize_url )
432466 print ('After approving the token enter the verification code (if specified).' )
433467 code = input ('Code: ' ).strip ()
434-
435468 try :
436- credential = flow .step2_exchange ( code )
437- except oauth2_client . FlowExchangeError as e :
438- print ('Authentication has failed: {}' . format ( e ) )
469+ flow .fetch_token ( code = code )
470+ except InvalidGrantError as ex :
471+ print ('Authentication has failed: %s' % ex )
439472 sys .exit (1 )
440- else :
441- print ('OAuth2 authorization successful!\n \n '
442- 'Your access token is:\n {access_token}\n \n Your refresh token is:\n {refresh_token}'
443- .format (access_token = credential .access_token , refresh_token = credential .refresh_token ))
473+
474+ print ('Access token: %s' % flow .credentials .token )
475+ print ('Refresh token: %s' % flow .credentials .refresh_token )
444476
445477
446478def parse_labels (labels : str ) -> {str : str }:
0 commit comments