def reset_cid(client): setup.download_file_from_gcs('googleads.yaml', str(CONFIG_PATH) + 'googleads.yaml') with open(CONFIG_PATH / 'googleads.yaml', 'r') as f: config = yaml.load(f, Loader=yaml.FullLoader) cid = config['adwords']['client_customer_id'] client.SetClientCustomerId(cid)
def _get_config_file_contents(): """Gets the contents of the config file""" try: setup.download_file_from_gcs(CONFIG_FILE_PATH_GS, CONFIG_FILE_PATH) with open(CONFIG_FILE_PATH, 'r') as f: config = yaml.load(f, Loader=yaml.FullLoader) return config except Exception as e: logging.error(str(e))
def _update_asset_struct(asset): """Update the asset_to_ag file with the new assets and their adgroups""" try: setup.download_file_from_gcs('asset_to_ag.json', asset_to_ag_json_path) except Exception as e: print(e) with open(asset_to_ag_json_path, 'r') as f: struct = json.load(f) struct.append(asset) with open(asset_to_ag_json_path, 'w') as f: json.dump(struct, f, indent=2) setup.upload_file_to_gcs(asset_to_ag_json_path, 'asset_to_ag.json')
def get_yt_configs(): """return all config parameters""" try: setup.download_file_from_gcs(YT_CONFIG_FILE_PATH_GS, YT_CONFIG_FILE_PATH) with open(YT_CONFIG_FILE_PATH, 'r') as fi: config = json.load(fi) except Exception as e: config = { 'channel_id': '', 'api_key': '', } return _build_response(json.dumps(config),status=200)
def get_asset_to_ag(): try: setup.download_file_from_gcs('asset_to_ag.json', asset_to_ag_json_path) with open(asset_to_ag_json_path, 'r') as f: asset_struct = json.load(f) if asset_struct: return _build_response(json.dumps(asset_struct)) else: return _build_response(msg='asset structure is not available', status=501) except Exception as e: return _build_response( msg='error while reading asset_to_ag.json: ' + str(e), status=400)
def get_configs(): """return all config parameters""" try: setup.download_file_from_gcs(CONFIG_FILE_PATH_GS, CONFIG_FILE_PATH) with open(CONFIG_FILE_PATH, 'r') as fi: config = yaml.load(fi, Loader=yaml.FullLoader) except FileNotFoundError: config = { 'client_customer_id': '', 'client_id': '', 'client_secret': '', 'developer_token': '', 'refresh_token': '', 'config_valid': 0, } return _build_response(json.dumps(config))
def get_structure(): cid = int(request.args.get('cid')) try: setup.download_file_from_gcs('account_struct.json', account_struct_json_path) with open(account_struct_json_path, 'r') as f: accounts_struct = json.load(f) if cid: for account in accounts_struct: if account['id'] == cid: return _build_response(msg=json.dumps(account, indent=2)) return _build_response(msg='cid not found', status=500) else: return _build_response(msg=json.dumps(accounts_struct, indent=2)) except: return _build_response(msg='could not get data', status=500)
def init_flow(from_client_config=False, client_id=None, client_secret=None): global flow try: if from_client_config: # Copy Google Storage file to tmp file if cloud version setup.download_file_from_gcs(CONFIG_FILE_PATH_GS, CONFIG_FILE_PATH) # Get credentials from config file with open(CONFIG_FILE_PATH, 'r') as f: config = yaml.load(f, Loader=yaml.FullLoader) client_id = config['client_id'] client_secret = config['client_secret'] client_config = { 'web': { 'client_id': client_id, 'client_secret': client_secret, 'auth_uri': 'https://accounts.google.com/o/oauth2/auth', 'token_uri': 'https://accounts.google.com/o/oauth2/token', } } flow = Flow.from_client_config( client_config=client_config, scopes=[ 'openid', 'https://www.googleapis.com/auth/adwords', 'https://www.googleapis.com/auth/userinfo.profile', 'https://www.googleapis.com/auth/userinfo.email', 'https://www.googleapis.com/auth/youtube.readonly' ] ) flow.redirect_uri = BASE_URL auth_url, _ = flow.authorization_url() status=200 except Exception as e: logging.error(str(e)) status=500 auth_url = ''
def get_all_yt_videos(): setup.download_file_from_gcs(YT_CONFIG_GS, YT_CONFIG) with open(YT_CONFIG, 'r') as f: yt_config = json.load(f) with open(CONFIG_FILE_PATH, 'r') as f: config = yaml.load(f, Loader=yaml.FullLoader) client_id = config['client_id'] client_secret = config['client_secret'] refresh_token = config['refresh_token'] channel_id = yt_config['channel_id'] videos = [] info = { "client_id": client_id, "client_secret": client_secret, "refresh_token": refresh_token } credentials = Credentials.from_authorized_user_info(info) youtube = build('youtube', 'v3', credentials=credentials, cache_discovery=False) channels = youtube.channels().list(id=channel_id, part='contentDetails').execute() #Check if channel was found. Return empty list if not if not channels.get('items'): return videos uploads_pl_id = channels['items'][0]['contentDetails']['relatedPlaylists'][ 'uploads'] next_page_token = None while 1: vids = youtube.playlistItems().list( playlistId=uploads_pl_id, part='snippet, status', maxResults=50, pageToken=next_page_token).execute() for item in vids['items']: if item['status']['privacyStatus'] in ALLOWED_STATUS: video_id = item['snippet']['resourceId']['videoId'] videos.append({ 'id': video_id, 'name': item['snippet']['title'], 'thumbnail': item['snippet']['thumbnails']['default']['url'], 'url': YT_URL_PREFIX + video_id }) next_page_token = vids.get('nextPageToken') if next_page_token is None: break return videos
def mutate(): """Assign or remove an asset from adgroups. gets a dict with two entries: 1. refresh token to create clients 2. list of asset, account, adgourp and action. preforms all of the actions one by one. returns a list with the new asset objects with the changed adgroups list. if its a text asset, returns a list with both 'headlines' and 'descriptions' entries. also changes the asset_to_ag.json file. """ data = request.get_json(force=True) logging.info('Recived mutate request: %s', str(data['data'])) refresh_token = data['refresh_token'] data_load = data['data'] asset_id = data_load[0]['asset']['id'] asset_type = data_load[0]['asset']['type'] aw_client = init_user_adwords_client(refresh_token) ga_client = init_user_googleads_client(refresh_token) setup.download_file_from_gcs('asset_to_ag.json', asset_to_ag_json_path) with open(asset_to_ag_json_path, 'r') as f: asset_struct = json.load(f) # special func for text assets, as they have 2 entries in asset_to_ag.json if asset_type == 'TEXT': return _text_asset_mutate(data_load, aw_client, ga_client, asset_id, asset_struct) asset_handler = {} index = 0 # to re-write back to location for entry in asset_struct: if entry['id'] == asset_id: asset_handler = entry break index += 1 if not asset_handler: asset_handler = data_load[0]['asset'] asset_handler['adgroups'] = [] index = None failed_assign = [] successeful_assign = [] for item in data_load: account = item['account'] adgroup = item['adgroup'] action = item['action'] asset = item['asset'] try: mutation = mutate_ad(aw_client, account, adgroup, asset, action) except Exception as e: failed_assign.append( { 'adgroup': populate_adgroup_details(ga_client, account, adgroup), 'error_message': error_mapping(str(e)), 'err': str(e) } ) mutation = 'failed' logging.error('could not execute mutation on adgroup: %s',str(adgroup)) if mutation is None: successeful_assign.append(adgroup) asset_handler = _asset_ag_update(asset_handler,adgroup,action) Service_Class.reset_cid(aw_client) if index: asset_struct[index] = asset_handler else: asset_struct.append(asset_handler) with open(asset_to_ag_json_path, 'w') as f: json.dump(asset_struct, f,indent=2) setup.upload_file_to_gcs(asset_to_ag_json_path, 'asset_to_ag.json') if failed_assign and successeful_assign: status = 206 elif successeful_assign: status = 200 else: status = 500 logging.info( 'mutate response: msg={} , status={}'.format(asset_handler,index)) return _build_response(msg=json.dumps( [{'asset':asset_handler,'index':index, 'failures':failed_assign}]) , status=status)
return ADWORDS_CLIENT def get_global_googleads_client(): global GOOGLEADS_CLIENT if GOOGLEADS_CLIENT: return GOOGLEADS_CLIENT else: setup.set_api_configs() GOOGLEADS_CLIENT = GoogleAdsClient.load_from_storage( CONFIG_PATH / 'google-ads.yaml') return GOOGLEADS_CLIENT # check if config is valid. if yes, init clients and create struct try: # Copy Google Storage file to tmp file setup.download_file_from_gcs(CONFIG_FILE_PATH_GS, CONFIG_FILE_PATH) with open(CONFIG_FILE_PATH, 'r') as f: config_file = yaml.load(f, Loader=yaml.FullLoader) except FileNotFoundError: config_file = {'config_valid': 0} if config_file['config_valid']: try: setup.download_file_from_gcs('account_struct.json', account_struct_json_path) setup.download_file_from_gcs('asset_to_ag.json', asset_to_ag_json_path) if CLOUD_VERSION and Path(account_struct_json_path).exists(): get_global_googleads_client() # to initialize googleads.yaml file logging.info('Skipping structure creation on startup, since this is the cloud version') else: structure.create_mcc_struct(get_global_googleads_client(), account_struct_json_path, asset_to_ag_json_path)