def check_price_buckets_validity(price_buckets): """ Validate that the price_buckets object contains all required keys and the values are the expected types. Args: price_buckets (object) Returns: None """ try: pb_precision = price_buckets['precision'] pb_min = price_buckets['min'] pb_max = price_buckets['max'] pb_increment = price_buckets['increment'] except KeyError: raise BadSettingException('The setting "PREBID_PRICE_BUCKETS" ' 'must contain keys "precision", "min", "max", and "increment".') if not (isinstance(pb_precision, int) or isinstance(pb_precision, float)): raise BadSettingException('The "precision" key in "PREBID_PRICE_BUCKETS" ' 'must be a number.') if not (isinstance(pb_min, int) or isinstance(pb_min, float)): raise BadSettingException('The "min" key in "PREBID_PRICE_BUCKETS" ' 'must be a number.') if not (isinstance(pb_max, int) or isinstance(pb_max, float)): raise BadSettingException('The "max" key in "PREBID_PRICE_BUCKETS" ' 'must be a number.') if not (isinstance(pb_increment, int) or isinstance(pb_increment, float)): raise BadSettingException('The "increment" key in "PREBID_PRICE_BUCKETS" ' 'must be a number.')
def get_advertiser_id_by_name(name): """ Returns a DFP company ID from company name. Args: name (str): the name of the DFP advertiser Returns: an integer: the advertiser's DFP ID """ dfp_client = get_client() company_service = dfp_client.GetService('CompanyService', version='v201802') # Filter by name. query = 'WHERE name = :name' values = [ { 'key': 'name', 'value': { 'xsi_type': 'TextValue', 'value': name } }, ] statement = dfp.FilterStatement(query, values) response = company_service.getCompaniesByStatement(statement.ToStatement()) # A company is required. no_company_found = False try: no_company_found = True if len(response['results']) < 1 else False except (AttributeError, KeyError): no_company_found = True if no_company_found: if getattr(settings, 'DFP_CREATE_ADVERTISER_IF_DOES_NOT_EXIST', False): advertiser = create_advertiser(name) else: raise DFPObjectNotFound( 'No advertiser found with name {0}'.format(name)) elif len(response['results']) > 1: raise BadSettingException( 'Multiple advertisers found with name {0}'.format(name)) else: advertiser = response['results'][0] logger.info( u'Using existing advertiser with ID "{id}", name "{name}", and ' 'type "{type}".'.format(id=advertiser['id'], name=advertiser['name'], type=advertiser['type'])) return advertiser['id']
def create_order(order_name, advertiser_id, trafficker_id): """ Creates an order in DFP. Args: order_name (str): the name of the order advertiser_id (int): the ID of the advertiser in DFP trafficker_id (int): the ID of the DFP user owning the order Returns: an integer: the ID of the created order """ dfp_client = get_client() company_service = dfp_client.GetService('CompanyService', version='v201702') # Check to make sure an order does not exist with this name. # Otherwise, DFP will throw an exception. existing_order = dfp.get_orders.get_order_by_name(order_name) if existing_order is not None: # If the settings allow modifying an existing order, do so. Otherwise, # throw an exception. can_use_existing_order = getattr(settings, 'DFP_USE_EXISTING_ORDER_IF_EXISTS', None) if can_use_existing_order: order = existing_order logger.info( 'Using existing order with id "{id}" and name "{name}".'. format(id=order['id'], name=order['name'])) else: raise BadSettingException( ('An order already exists with name {0}. ' 'Please choose a new order name.').format(order_name)) # No order with the name exists, so create it. else: orders = [ create_order_config(name=order_name, advertiser_id=advertiser_id, trafficker_id=trafficker_id) ] order_service = dfp_client.GetService('OrderService', version='v201702') orders = order_service.createOrders(orders) order = orders[0] logger.info( u'Created an order with id "{id}" and name "{name}".'.format( id=order['id'], name=order['name'])) return order['id']
def validateCSVValues(start_range, end_range, granularity, rate_id): if start_range < 0 or end_range < 0: raise BadSettingException( 'Start range and end range can not be negative. Please correct the csv and try again.' ) if start_range > end_range: raise BadSettingException( 'Start range can not be more than end range. Please correct the csv and try again.' ) if rate_id not in (1, 2): raise BadSettingException( 'Rate id can only be 1 or 2. Please correct the csv and try again') if start_range < 0.01 and granularity == 0.01: raise BadSettingException( 'Start range can not be less than 0.01 for granularity 0.01, either increase granularity or start range in csv.' ) if end_range > 999: raise BadSettingException( 'End range can not be more then 999. Please correct the csv and try again.' ) if granularity == 0: raise BadSettingException( 'Zero is not accepted as granularity. Please correct the csv and try again' )
def main(): """ Loads placements from settings and fetches them from DFP. Returns: None """ placements = getattr(settings, 'DFP_TARGETED_PLACEMENT_NAMES', None) if placements is None: raise MissingSettingException('DFP_TARGETED_PLACEMENT_NAMES') elif len(placements) < 1: raise BadSettingException('The setting "DFP_TARGETED_PLACEMENT_NAMES" ' 'must contain at least one placement ID.') get_placement_ids_by_name(placements)
def main(): """ Loads ad units from settings and fetches them from DFP. Returns: None """ ad_units = getattr(settings, 'DFP_TARGETED_AD_UNIT_NAMES', None) if ad_units is None: raise MissingSettingException('DFP_TARGETED_AD_UNIT_NAMES') elif len(ad_units) < 1: raise BadSettingException('The setting "DFP_TARGETED_AD_UNIT_NAMES" ' 'must contain at least one ad unit ID.') get_ad_unit_ids_by_name(ad_units)
def main(): """ Validate the settings and ask for confirmation from the user. Then, start all necessary DFP tasks. """ user_email = getattr(settings, 'DFP_USER_EMAIL_ADDRESS', None) if user_email is None: raise MissingSettingException('DFP_USER_EMAIL_ADDRESS') advertiser_name = getattr(settings, 'DFP_ADVERTISER_NAME', None) if advertiser_name is None: raise MissingSettingException('DFP_ADVERTISER_NAME') order_name = getattr(settings, 'DFP_ORDER_NAME', None) if order_name is None: raise MissingSettingException('DFP_ORDER_NAME') placements = getattr(settings, 'DFP_TARGETED_PLACEMENT_NAMES', None) ad_units = getattr(settings, 'DFP_TARGETED_AD_UNIT_NAMES', None) video_ad_type = getattr(settings, 'DFP_VIDEO_AD_TYPE', False) vast_redirect_url = getattr(settings, 'DFP_VAST_REDIRECT_URL', '') if video_ad_type is True and len(vast_redirect_url) < 1: raise BadSettingException( 'When setting "DFP_VIDEO_AD_TYPE" to "True", please also set "DFP_VAST_REDIRECT_URL".' ) if ad_units is None and placements is None: raise MissingSettingException( 'DFP_TARGETED_PLACEMENT_NAMES or DFP_TARGETED_AD_UNIT_NAMES') elif (placements is None or len(placements) < 1) and (ad_units is None or len(ad_units) < 1): raise BadSettingException( 'The setting "DFP_TARGETED_PLACEMENT_NAMES" or "DFP_TARGETED_AD_UNIT_NAMES" ' 'must contain at least one DFP placement or ad unit.') sizes = getattr(settings, 'DFP_PLACEMENT_SIZES', None) if sizes is None: raise MissingSettingException('DFP_PLACEMENT_SIZES') elif len(sizes) < 1: raise BadSettingException('The setting "DFP_PLACEMENT_SIZES" ' 'must contain at least one size object.') currency_code = getattr(settings, 'DFP_CURRENCY_CODE', 'USD') line_item_format = getattr(settings, 'DFP_LINE_ITEM_FORMAT', u'{bidder_code}: HB ${price}') # How many creatives to attach to each line item. We need at least one # creative per ad unit on a page. See: # https://github.com/kmjennison/dfp-prebid-setup/issues/13 num_creatives = (getattr(settings, 'DFP_NUM_CREATIVES_PER_LINE_ITEM', None) or len(placements) + len(ad_units)) bidder_code = getattr(settings, 'PREBID_BIDDER_CODE', None) if bidder_code is None: raise MissingSettingException('PREBID_BIDDER_CODE') price_buckets = getattr(settings, 'PREBID_PRICE_BUCKETS', None) if price_buckets is None: raise MissingSettingException('PREBID_PRICE_BUCKETS') check_price_buckets_validity(price_buckets) prices = get_prices_array(price_buckets) prices_summary = get_prices_summary_string(prices) logger.info(u""" Going to create {name_start_format}{num_line_items}{format_end} new line items. {name_start_format}Order{format_end}: {value_start_format}{order_name}{format_end} {name_start_format}Advertiser{format_end}: {value_start_format}{advertiser}{format_end} Line items will have targeting: {name_start_format}hb_pb{format_end} = {value_start_format}{prices_summary}{format_end} {name_start_format}hb_bidder{format_end} = {value_start_format}{bidder_code}{format_end} {name_start_format}placements{format_end} = {value_start_format}{placements}{format_end} {name_start_format}ad units{format_end} = {value_start_format}{ad_units}{format_end} """.format( num_line_items=len(prices), order_name=order_name, advertiser=advertiser_name, user_email=user_email, prices_summary=prices_summary, bidder_code=bidder_code, placements=placements, ad_units=ad_units, sizes=sizes, name_start_format=color.BOLD, format_end=color.END, value_start_format=color.BLUE, )) if video_ad_type: logger.info( u""" Line items will have VAST redirect creatives with redirect URL: {value_start_format}{redirect_url}{format_end} """.format( redirect_url=vast_redirect_url, value_start_format=color.BLUE, format_end=color.END, )) else: logger.info( u""" Line items will have third party creatives based on snippet.html content. """) ok = input('Is this correct? (y/n)\n') if ok != 'y': logger.info('Exiting.') return setup_partner(user_email, advertiser_name, order_name, placements, ad_units, sizes, bidder_code, prices, num_creatives, currency_code, line_item_format, video_ad_type, vast_redirect_url)
def main(): """ Validate the settings and ask for confirmation from the user. Then, start all necessary DFP tasks. """ user_email = getattr(settings, 'DFP_USER_EMAIL_ADDRESS', None) if user_email is None: raise MissingSettingException('DFP_USER_EMAIL_ADDRESS') advertiser_name = getattr(settings, 'DFP_ADVERTISER_NAME', None) if advertiser_name is None: raise MissingSettingException('DFP_ADVERTISER_NAME') advertiser_type = getattr(settings, 'DFP_ADVERTISER_TYPE', "ADVERTISER") if advertiser_type != "ADVERTISER" and advertiser_type != "AD_NETWORK": raise BadSettingException('DFP_ADVERTISER_TYPE') order_name = getattr(settings, 'DFP_ORDER_NAME', None) if order_name is None: raise MissingSettingException('DFP_ORDER_NAME') lineitem_type = getattr(settings, 'DFP_LINEITEM_TYPE', None) if lineitem_type is None: raise MissingSettingException('DFP_LINEITEM_TYPE') num_placements = 0 placements = getattr(settings, 'DFP_TARGETED_PLACEMENT_NAMES', None) placements_print = str(placements) if placements is None: placements = [] placements_print = "RON" # if no placements are specified, we wil do run of network which is # effectively one placement num_placements = len(placements) if num_placements == 0: num_placements = 1 placements_print = "RON" creative_type = getattr(settings, 'OPENWRAP_CREATIVE_TYPE', None) if creative_type is None: creative_type = constant.WEB elif creative_type not in [ constant.WEB, constant.WEB_SAFEFRAME, constant.AMP, constant.IN_APP, constant.NATIVE, constant.VIDEO, constant.JW_PLAYER ]: raise BadSettingException( 'Unknown OPENWRAP_CREATIVE_TYPE: {0}'.format(creative_type)) sizes = getattr(settings, 'DFP_PLACEMENT_SIZES', None) if creative_type != constant.NATIVE: if sizes is None: raise MissingSettingException('DFP_PLACEMENT_SIZES') elif len(sizes) < 1: raise BadSettingException('The setting "DFP_PLACEMENT_SIZES" ' 'must contain at least one size object.') currency_code = getattr(settings, 'DFP_CURRENCY_CODE', 'USD') # How many creatives to attach to each line item. We need at least one # creative per ad unit on a page. See: # https://github.com/kmjennison/dfp-prebid-setup/issues/13 num_creatives = (getattr(settings, 'DFP_NUM_CREATIVES_PER_LINE_ITEM', None) or num_placements) # read creative template for native Line-items creative_template = None if creative_type == constant.NATIVE: creative_template = getattr(settings, 'OPENWRAP_CREATIVE_TEMPLATE', None) if creative_template is None: raise MissingSettingException('OPENWRAP_CREATIVE_TEMPLATE') elif not isinstance(creative_template, (list, str)): raise BadSettingException('OPENWRAP_CREATIVE_TEMPLATE') if isinstance(creative_template, str): creative_template = [creative_template] bidder_code = getattr(settings, 'PREBID_BIDDER_CODE', None) if bidder_code is not None and not isinstance(bidder_code, (list, tuple, str)): raise BadSettingException('PREBID_BIDDER_CODE') same_adv_exception = getattr(settings, 'DFP_SAME_ADV_EXCEPTION', False) if not isinstance(same_adv_exception, bool): raise BadSettingException('DFP_SAME_ADV_EXCEPTION') device_categories = getattr(settings, 'DFP_DEVICE_CATEGORIES', None) if device_categories is not None and not isinstance( device_categories, (list, tuple, str)): raise BadSettingException('DFP_DEVICE_CATEGORIES') device_capabilities = None # We do not want to restrict line item based on device capabilties # Disabling after a discussion with Lloyd # if creative_type is constant.IN_APP: # device_capabilities = ('Mobile Apps', 'MRAID v1', 'MRAID v2') roadblock_type = getattr(settings, 'DFP_ROADBLOCK_TYPE', 'ONE_OR_MORE') if roadblock_type not in ('ONE_OR_MORE', 'AS_MANY_AS_POSSIBLE'): raise BadSettingException('DFP_ROADBLOCK_TYPE') lineitem_prefix = getattr(settings, 'LINE_ITEM_PREFIX', None) if lineitem_prefix != None: if not isinstance(lineitem_prefix, (str)): raise BadSettingException('LINE_ITEM_PREFIX') use_1x1 = getattr(settings, 'OPENWRAP_USE_1x1_CREATIVE', False) if not isinstance(use_1x1, bool): raise BadSettingException('OPENWRAP_USE_1x1_CREATIVE') custom_targeting = getattr(settings, 'OPENWRAP_CUSTOM_TARGETING', None) if custom_targeting != None: if not isinstance(custom_targeting, (list, tuple)): raise BadSettingException('OPENWRAP_CUSTOM_TARGETING') for ct in custom_targeting: if len(ct) != 3: raise BadSettingException('OPENWRAP_CUSTOM_TARGETING') if ct[1] != "IS" and ct[1] != "IS_NOT": raise BadSettingException('OPENWRAP_CUSTOM_TARGETING') if not isinstance(ct[2], (list, tuple, str, bool)): raise BadSettingException( 'OPENWRAP_CUSTOM_TARGETING - {0}'.format(type(ct[2]))) price_buckets_csv = getattr(settings, 'OPENWRAP_BUCKET_CSV', None) if price_buckets_csv is None: raise MissingSettingException('OPENWRAP_BUCKET_CSV') prices = load_price_csv(price_buckets_csv, creative_type) prices_summary = [] for p in prices: prices_summary.append(p['rate']) if len(prices) > constant.LINE_ITEMS_LIMIT: print( '\n Error: {} Lineitems will be created. This is exceeding Line items count per order of {}!\n' .format(len(prices), constant.LINE_ITEMS_LIMIT)) return # set bidder_code, custom_targetting, device categories to None when creative_type is IN-APP, JW_PLAYER # default roadblock_type to ONE_OR_MORE when creative_type is VIDEO, JW_PLAYER # default roadblock type to 'AS_MANY_AS_POSSIBLE' when creative_type is in-app if creative_type == constant.IN_APP: roadblock_type = 'AS_MANY_AS_POSSIBLE' #bidder_code = None custom_targeting = None device_categories = None elif creative_type == constant.JW_PLAYER: roadblock_type = 'ONE_OR_MORE' bidder_code = ['pubmatic'] custom_targeting = None device_categories = None elif creative_type == constant.VIDEO: roadblock_type = 'ONE_OR_MORE' logger.info(u""" Going to create {name_start_format}{num_line_items}{format_end} new line items. {name_start_format}Order{format_end}: {value_start_format}{order_name}{format_end} {name_start_format}Advertiser{format_end}: {value_start_format}{advertiser}{format_end} {name_start_format}Advertiser Type{format_end}: {value_start_format}{advertiser_type}{format_end} {name_start_format}LineItem Type{format_end}: {value_start_format}{lineitem_type}{format_end} {name_start_format}LineItem Prefix{format_end}: {value_start_format}{lineitem_prefix}{format_end} {name_start_format}Creative Type{format_end} = {value_start_format}{creative_type}{format_end} {name_start_format}Use 1x1 Creative{format_end} = {value_start_format}{use_1x1}{format_end} Line items will have targeting: {name_start_format}rates{format_end} = {value_start_format}{prices_summary}{format_end} {name_start_format}bidders{format_end} = {value_start_format}{bidder_code}{format_end} {name_start_format}placements{format_end} = {value_start_format}{placements}{format_end} {name_start_format}custom targeting{format_end} = {value_start_format}{custom_targeting}{format_end} {name_start_format}same advertiser exception{format_end} = {value_start_format}{same_adv_exception}{format_end} {name_start_format}device categories{format_end} = {value_start_format}{device_categories}{format_end} {name_start_format}device capabilities{format_end} = {value_start_format}{device_capabilities}{format_end} {name_start_format}roadblock type{format_end} = {value_start_format}{roadblock_type}{format_end} """.format( num_line_items=len(prices), order_name=order_name, advertiser=advertiser_name, advertiser_type=advertiser_type, lineitem_type=lineitem_type, lineitem_prefix=lineitem_prefix, creative_type=creative_type, user_email=user_email, prices_summary=prices_summary, bidder_code=bidder_code, placements=placements_print, sizes=sizes, custom_targeting=custom_targeting, same_adv_exception=same_adv_exception, device_categories=device_categories, device_capabilities=device_capabilities, roadblock_type=roadblock_type, use_1x1=use_1x1, name_start_format=color.BOLD, format_end=color.END, value_start_format=color.BLUE, )) ok = input('Is this correct? (y/n)\n') if ok != 'y': logger.info('Exiting.') return try: setup_partner(user_email, advertiser_name, advertiser_type, order_name, placements, sizes, lineitem_type, lineitem_prefix, bidder_code, prices, creative_type, creative_template, num_creatives, use_1x1, currency_code, custom_targeting, same_adv_exception, device_categories, device_capabilities, roadblock_type) except ConnectionError as e: logger.error( '\nConnection Error. Please try again after some time! Err: \n{}'. format(e)) except GoogleAdsServerFault as e: if "ServerError.SERVER_ERROR" in str(e): logger.error( '\n\nDFP Server Error. Please try again after some time! Err: \n{}' .format(e)) else: raise DFPException( "\n\nError occured while creating Lineitems in DFP: \n {}". format(e))
def load_price_csv(filename, creative_type): buckets = [] exchange_rate = 1 #read currency conversion flag currency_exchange = True # Currency module/CURRENCY_EXCHANGE is applicable for web and native platform if creative_type in (constant.WEB, constant.WEB_SAFEFRAME, constant.NATIVE): currency_exchange = getattr(settings, 'CURRENCY_EXCHANGE', True) if currency_exchange: network = get_dfp_network() logger.info("Network currency : %s", network.currencyCode) exchange_rate = get_exchange_rate(network.currencyCode) logger.info("Currency exchange rate: {}".format(exchange_rate)) #currency rate handling till here with open(filename, 'r') as csvfile: preader = csv.reader(csvfile) next(preader) # skip header row for row in preader: # ignore extra lines or spaces if row == [] or row[0].strip() == "": continue print(row) try: start_range = float(row[2]) end_range = float(row[3]) granularity = float(row[4]) rate_id = int(row[5]) except ValueError: raise BadSettingException( 'Start range, end range, granularity and rate id should be number. Please correct the csv and try again.' ) validateCSVValues(start_range, end_range, granularity, rate_id) if granularity != -1: i = start_range while i < end_range: a = round(i + granularity, 2) if a > end_range: a = end_range if round(i, 2) != (a, 2): buckets.append({ 'start': i, 'end': a, 'granularity': granularity, 'rate': get_calculated_rate(i, a, rate_id, exchange_rate) }) i = a else: buckets.append({ 'start': start_range, 'end': end_range, 'granularity': 1.0, 'rate': get_calculated_rate(start_range, end_range, rate_id, exchange_rate) }) return buckets
def setup_partner(user_email, advertiser_name, advertiser_type, order_name, placements, sizes, lineitem_type, lineitem_prefix, bidder_code, prices, creative_type, creative_template, num_creatives, use_1x1, currency_code, custom_targeting, same_adv_exception, device_categories, device_capabilities, roadblock_type): """ Call all necessary DFP tasks for a new Prebid partner setup. """ # Get the user. user_id = dfp.get_users.get_user_id_by_email(user_email) # Get the placement IDs. placement_ids = None ad_unit_ids = None if len(placements) > 0: placement_ids = dfp.get_placements.get_placement_ids_by_name( placements) else: # Run of network root_id = dfp.get_root_ad_unit_id.get_root_ad_unit_id() ad_unit_ids = [root_id] # Get the device category IDs # Dont get device categories for in-app and jwplayer platform device_category_ids = None if device_categories != None and creative_type not in (constant.IN_APP, constant.JW_PLAYER): device_category_ids = [] if isinstance(device_categories, str): device_categories = (device_categories) dc_map = dfp.get_device_categories.get_device_categories() for dc in device_categories: if dc in dc_map: device_category_ids.append(dc_map[dc]) else: raise BadSettingException( "Invalid Device Cagetory: {} ".format(dc)) #get device capabilty ids for in-APP platform device_capability_ids = None if device_capabilities != None and creative_type is constant.IN_APP: device_capability_ids = [] if isinstance(device_capabilities, str): device_capabilities = (device_capabilities) dc_map = dfp.get_device_capabilities.get_device_capabilities() for dc in device_capabilities: if dc in dc_map: device_capability_ids.append(dc_map[dc]) else: raise BadSettingException( "Invalid Device Capability: {} ".format(dc)) # Get (or potentially create) the advertiser. advertiser_id = dfp.get_advertisers.get_advertiser_id_by_name( advertiser_name, advertiser_type) # Create the order. order_id = dfp.create_orders.create_order(order_name, advertiser_id, user_id) # Create creatives. #Get creative template for native platform creative_template_ids = None if creative_type == constant.NATIVE: creative_template_ids = dfp.get_creative_template.get_creative_template_ids_by_name( creative_template) #if bidder is None, then bidder will be 'All' bidder_str = bidder_code if bidder_str == None: bidder_str = "All" elif isinstance(bidder_str, (list, tuple)): bidder_str = "_".join(bidder_str) #generate unique id that will be used for creative and line item naming unique_id = get_unique_id(creative_type) #create creatives logger.info("creating creatives...") size_arg = sizes if use_1x1: size_arg = None creative_configs = get_creative_config(creative_type, bidder_str, order_name, advertiser_id, size_arg, num_creatives, creative_template_ids, prefix=unique_id) creative_ids = dfp.create_creatives.create_creatives(creative_configs) # if platform is video, create creative sets if creative_type in (constant.VIDEO, constant.JW_PLAYER): creative_set_configs = dfp.create_creative_sets.create_creative_set_config( creative_ids, sizes, unique_id) creative_ids = dfp.create_creative_sets.create_creative_sets( creative_set_configs) # Create line items. # if line item prefix is not passed, set unique id as lineitem prefix if lineitem_prefix is None: lineitem_prefix = unique_id logger.info("creating line_items_config...") line_items_config = create_line_item_configs( prices, order_id, placement_ids, bidder_code, sizes, OpenWrapTargetingKeyGen(), lineitem_type, lineitem_prefix, currency_code, custom_targeting, creative_type, creative_template_ids, same_adv_exception=same_adv_exception, ad_unit_ids=ad_unit_ids, device_category_ids=device_category_ids, device_capability_ids=device_capability_ids, roadblock_type=roadblock_type) logger.info("Creating line items...") line_item_ids = dfp.create_line_items.create_line_items(line_items_config) # Associate creatives with line items. size_overrides = [] if use_1x1 and creative_type is not constant.NATIVE: size_overrides = sizes logger.info("Creating lineitem creative associations...") dfp.associate_line_items_and_creatives.make_licas( line_item_ids, creative_ids, size_overrides=size_overrides, creative_type=creative_type) logger.info(""" Done! Please review your order, line items, and creatives to make sure they are correct. Then, approve the order in DFP. Happy bidding! """)
def main(): """ Validate the settings and ask for confirmation from the user. Then, start all necessary DFP tasks. """ user_email = getattr(settings, 'DFP_USER_EMAIL_ADDRESS', None) if user_email is None: raise MissingSettingException('DFP_USER_EMAIL_ADDRESS') advertiser_name = getattr(settings, 'DFP_ADVERTISER_NAME', None) if advertiser_name is None: raise MissingSettingException('DFP_ADVERTISER_NAME') order_name = getattr(settings, 'DFP_ORDER_NAME', None) if order_name is None: raise MissingSettingException('DFP_ORDER_NAME') placements = getattr(settings, 'DFP_TARGETED_PLACEMENT_NAMES', None) if placements is None: raise MissingSettingException('DFP_TARGETED_PLACEMENT_NAMES') elif len(placements) < 1: raise BadSettingException( 'The setting "DFP_TARGETED_PLACEMENT_NAMES" ' 'must contain at least one DFP placement ID.') sizes = getattr(settings, 'DFP_PLACEMENT_SIZES', None) if sizes is None: raise MissingSettingException('DFP_PLACEMENT_SIZES') elif len(sizes) < 1: raise BadSettingException('The setting "DFP_PLACEMENT_SIZES" ' 'must contain at least one size object.') currency_code = getattr(settings, 'DFP_CURRENCY_CODE', 'USD') # How many creatives to attach to each line item. We need at least one # creative per ad unit on a page. See: # https://github.com/kmjennison/dfp-prebid-setup/issues/13 num_creatives = (getattr(settings, 'DFP_NUM_CREATIVES_PER_LINE_ITEM', None) or len(placements)) bidder_code = getattr(settings, 'PREBID_BIDDER_CODE', None) if bidder_code is None: raise MissingSettingException('PREBID_BIDDER_CODE') price_buckets = getattr(settings, 'PREBID_PRICE_BUCKETS', None) if price_buckets is None: raise MissingSettingException('PREBID_PRICE_BUCKETS') check_price_buckets_validity(price_buckets) prices = get_prices_array(price_buckets) prices_summary = get_prices_summary_string(prices, price_buckets['precision']) logger.info(u""" Going to create {name_start_format}{num_line_items}{format_end} new line items. {name_start_format}Order{format_end}: {value_start_format}{order_name}{format_end} {name_start_format}Advertiser{format_end}: {value_start_format}{advertiser}{format_end} Line items will have targeting: {name_start_format}hb_pb{format_end} = {value_start_format}{prices_summary}{format_end} {name_start_format}hb_bidder{format_end} = {value_start_format}{bidder_code}{format_end} {name_start_format}placements{format_end} = {value_start_format}{placements}{format_end} """.format( num_line_items=len(prices), order_name=order_name, advertiser=advertiser_name, user_email=user_email, prices_summary=prices_summary, bidder_code=bidder_code, placements=placements, sizes=sizes, name_start_format=color.BOLD, format_end=color.END, value_start_format=color.BLUE, )) ok = input('Is this correct? (y/n)\n') if ok != 'y': logger.info('Exiting.') return setup_partner( user_email, advertiser_name, order_name, placements, sizes, bidder_code, prices, num_creatives, currency_code, )
def main(): """ Validate the settings and ask for confirmation from the user. Then, start all necessary DFP tasks. """ user_email = getattr(settings, 'DFP_USER_EMAIL_ADDRESS', None) if user_email is None: raise MissingSettingException('DFP_USER_EMAIL_ADDRESS') advertiser_name = getattr(settings, 'DFP_ADVERTISER_NAME', None) if advertiser_name is None: raise MissingSettingException('DFP_ADVERTISER_NAME') order_name = getattr(settings, 'DFP_ORDER_NAME', None) if order_name is None: raise MissingSettingException('DFP_ORDER_NAME') placements = getattr(settings, 'DFP_TARGETED_PLACEMENT_NAMES', None) no_inventory = getattr(settings, 'DFP_ALLOW_NO_INVENTORY_TARGETING', None) if placements is None: raise MissingSettingException('DFP_TARGETED_PLACEMENT_NAMES') elif len(placements) < 1 and no_inventory is not True: raise BadSettingException( 'The setting "DFP_TARGETED_PLACEMENT_NAMES" ' 'must contain at least one DFP placement ID.') sizes = getattr(settings, 'DFP_PLACEMENT_SIZES', None) if sizes is None: raise MissingSettingException('DFP_PLACEMENT_SIZES') elif len(sizes) < 1: raise BadSettingException('The setting "DFP_PLACEMENT_SIZES" ' 'must contain at least one size object.') currency_code = getattr(settings, 'DFP_CURRENCY_CODE', 'USD') # How many creatives to attach to each line item. We need at least one # creative per ad unit on a page. See: # https://github.com/kmjennison/dfp-prebid-setup/issues/13 num_creatives = (getattr(settings, 'DFP_NUM_CREATIVES_PER_LINE_ITEM', None) or len(placements)) # In the case where no inventory is being used, make sure at least one # creative is created if not num_creatives > 0: num_creatives = 1 bidder_code = getattr(settings, 'PREBID_BIDDER_CODE', None) if bidder_code is None: raise MissingSettingException('PREBID_BIDDER_CODE') bidder_params = getattr(settings, 'PREBID_BIDDER_PARAMS', None) hb_pb_key = 'hb_pb' additional_keys = '' if bidder_params is True: hb_pb_key += '_' + bidder_code hb_adid_key = 'hb_adid_' + bidder_code hb_size_key = 'hb_size_' + bidder_code if len(hb_pb_key) > 20: hb_pb_key = hb_pb_key[:20] if len(hb_adid_key) > 20: hb_adid_key = hb_adid_key[:20] if len(hb_size_key) > 20: hb_size_key = hb_size_key[:20] additional_keys = u""" Additionally, keys {name_start_format}{hb_adid_key}{format_end} and {name_start_format}{hb_size_key}{format_end} will be created.""".format( hb_adid_key=hb_adid_key, hb_size_key=hb_size_key, name_start_format=color.BOLD, format_end=color.END, ) price_buckets = getattr(settings, 'PREBID_PRICE_BUCKETS', None) if price_buckets is None: raise MissingSettingException('PREBID_PRICE_BUCKETS') check_price_buckets_validity(price_buckets) prices = get_prices_array(price_buckets) prices_summary = get_prices_summary_string(prices, price_buckets['precision']) logger.info(u""" Going to create {name_start_format}{num_line_items}{format_end} new line items. {name_start_format}Order{format_end}: {value_start_format}{order_name}{format_end} {name_start_format}Advertiser{format_end}: {value_start_format}{advertiser}{format_end} {name_start_format}Owner{format_end}: {value_start_format}{user_email}{format_end} Line items will have targeting: {name_start_format}{hb_pb_key}{format_end} = {value_start_format}{prices_summary}{format_end} {name_start_format}hb_bidder{format_end} = {value_start_format}{bidder_code}{format_end} {name_start_format}placements{format_end} = {value_start_format}{placements}{format_end}{additional_keys} """.format(num_line_items=len(prices), order_name=order_name, advertiser=advertiser_name, user_email=user_email, hb_pb_key=hb_pb_key, prices_summary=prices_summary, bidder_code=bidder_code, placements=placements, sizes=sizes, name_start_format=color.BOLD, format_end=color.END, value_start_format=color.BLUE, additional_keys=additional_keys)) ok = input('Is this correct? (y/n)\n') if ok != 'y': logger.info('Exiting.') return setup_partner( user_email, advertiser_name, order_name, placements, sizes, bidder_code, prices, num_creatives, currency_code, )
def main(): """ Validate the settings and ask for confirmation from the user. Then, start all necessary DFP tasks. """ user_email = getattr(settings, 'DFP_USER_EMAIL_ADDRESS', None) if user_email is None: raise MissingSettingException('DFP_USER_EMAIL_ADDRESS') advertiser_name = getattr(settings, 'DFP_ADVERTISER_NAME', None) if advertiser_name is None: raise MissingSettingException('DFP_ADVERTISER_NAME') order_name = getattr(settings, 'DFP_ORDER_NAME', None) if order_name is None: raise MissingSettingException('DFP_ORDER_NAME') placements = getattr(settings, 'DFP_TARGETED_PLACEMENT_NAMES', []) ad_units = getattr(settings, 'DFP_TARGETED_AD_UNIT_NAMES', []) if not ad_units and not placements: raise MissingSettingException( 'DFP_TARGETED_PLACEMENT_NAMES or DFP_TARGETED_AD_UNIT_NAMES') elif (not placements or len(placements) < 1) and (not ad_units or len(ad_units) < 1): raise BadSettingException( 'The setting "DFP_TARGETED_PLACEMENT_NAMES" or "DFP_TARGETED_AD_UNIT_NAMES" ' 'must contain at least one DFP placement or ad unit.') sizes = getattr(settings, 'DFP_PLACEMENT_SIZES', None) if sizes is None: raise MissingSettingException('DFP_PLACEMENT_SIZES') elif len(sizes) < 1: raise BadSettingException('The setting "DFP_PLACEMENT_SIZES" ' 'must contain at least one size object.') currency_code = getattr(settings, 'DFP_CURRENCY_CODE', 'USD') # How many creatives to attach to each line item. We need at least one # creative per ad unit on a page. See: # https://github.com/kmjennison/dfp-prebid-setup/issues/13 num_creatives = (getattr(settings, 'DFP_NUM_CREATIVES_PER_LINE_ITEM', None) or len(placements)) bidder_code = getattr(settings, 'PREBID_BIDDER_CODE', None) if bidder_code is None: logger.warning( 'PREBID_BIDDER_CODE is not specified. Create one set of line items for all bidders.' ) price_bucket_list = getattr(settings, 'PREBID_PRICE_BUCKETS', None) if price_bucket_list is None: raise MissingSettingException('PREBID_PRICE_BUCKETS') price_multipliers = getattr(settings, 'PRICE_MULTIPLIERS', {}) price_multiplier = price_multipliers.get(currency_code, 1) # Validate price buckets and adjust by price_multiplier adjusted_price_buckets = [] for price_bucket in price_bucket_list: check_price_buckets_validity(price_bucket) adjusted_price_buckets.append( adjust_price_bucket_by_price_multiplier(price_bucket, price_multiplier)) prices = get_prices_array_from_price_bucket_list(adjusted_price_buckets) prices_summary = get_prices_summary_string( prices, price_bucket_list[0]['precision']) logger.info(u""" Going to create {name_start_format}{num_line_items}{format_end} new line items. {name_start_format}Order{format_end}: {value_start_format}{order_name}{format_end} {name_start_format}Advertiser{format_end}: {value_start_format}{advertiser}{format_end} Line items will have targeting: {name_start_format}hb_pb{format_end} = {value_start_format}{prices_summary}{format_end} {name_start_format}hb_bidder{format_end} = {value_start_format}{bidder_code}{format_end} {name_start_format}placements{format_end} = {value_start_format}{placements}{format_end} {name_start_format}ad units{format_end} = {value_start_format}{ad_units}{format_end} """.format( num_line_items=len(prices), order_name=order_name, advertiser=advertiser_name, user_email=user_email, prices_summary=prices_summary, bidder_code=bidder_code or '(Targeting all bidders)', placements=placements, ad_units=ad_units, sizes=sizes, name_start_format=color.BOLD, format_end=color.END, value_start_format=color.BLUE, )) ok = input('Is thisy correct? (y/n)\n') if ok != 'y': logger.info('Exiting.') return setup_partner(user_email, advertiser_name, order_name, placements, ad_units, sizes, bidder_code, prices, num_creatives, currency_code)