def get_line_item_available_inventory(self, line_item, use_start=False, preserve_id=False): """ Get number of impressions available for line item @param line_item: LineItem @param use_start: bool, if False, checks availability from right now @param preserve_id: bool, communicate the id of the line item being forecasted to DFP. This is used in the case where we want to get a forecast on a line item in flight. This way, a domain doesn't need to have enough spare inventory to accommodate the two line items simultaneously. NOTE: If this is true then use_start is necessarily true. @return: int|None, number of available impressions """ dfp_line_item = transform_forecast_line_item_to_dfp( line_item, use_start, preserve_id) logging.info("Obtaining forecast data for line item %s", line_item.id or line_item) try: dfp_forecast = self.dfp_client.forecast_line_item(dfp_line_item) except Exception as e: raise ParselmouthException(e) forecast = recursive_asdict(dfp_forecast) if forecast and forecast.get('availableUnits'): available_units = int(forecast['availableUnits']) else: available_units = None logging.info("%s available impressions", str(available_units)) return available_units
def get_line_item_available_inventory(self, line_item, use_start=False, preserve_id=False): """ Get number of impressions available for line item @param line_item: LineItem @param use_start: bool, if False, checks availability from right now @param preserve_id: bool, communicate the id of the line item being forecasted to DFP. This is used in the case where we want to get a forecast on a line item in flight. This way, a domain doesn't need to have enough spare inventory to accommodate the two line items simultaneously. NOTE: If this is true then use_start is necessarily true. @return: int|None, number of available impressions """ dfp_line_item = transform_forecast_line_item_to_dfp( line_item, use_start, preserve_id ) logging.info( "Obtaining forecast data for line item %s", line_item.id or line_item ) try: dfp_forecast = self.dfp_client.forecast_line_item(dfp_line_item) except Exception as e: raise ParselmouthException(e) forecast = recursive_asdict(dfp_forecast) if forecast and forecast.get('availableUnits'): available_units = int(forecast['availableUnits']) else: available_units = None logging.info( "%s available impressions", str(available_units) ) return available_units
def test_line_item_forecast_utils(self): dfp_no_start_no_id = { "costType": "CPM", "creativePlaceholders": [ { "creativeSizeType": "PIXEL", "expectedCreativeCount": "1", "size": {"height": "768", "isAspectRatio": False, "width": "1024"}, } ], "endDateTime": { "date": {"day": 31, "month": 5, "year": 2014}, "hour": 23, "minute": 59, "second": 0, "timeZoneID": "America/New_York", }, "lineItemType": "STANDARD", "primaryGoal": {"goalType": "LIFETIME", "unitType": "IMPRESSIONS", "units": 1000000}, "startDateTimeType": "IMMEDIATELY", "targetPlatform": "ANY", "targeting": { "inventoryTargeting": {"targetedAdUnits": [{"adUnitId": "adunit", "includeDescendants": True}]} }, } # Check transform_forecast_line_item_to_dfp self.assertDictEqual( dfp_no_start_no_id, transform_forecast_line_item_to_dfp(TEST_LINE_ITEM, use_start=False, preserve_id=False) ) dfp_start_no_id = { "costType": "CPM", "creativePlaceholders": [ { "creativeSizeType": "PIXEL", "expectedCreativeCount": "1", "size": {"height": "768", "isAspectRatio": False, "width": "1024"}, } ], "endDateTime": { "date": {"day": 31, "month": 5, "year": 2014}, "hour": 23, "minute": 59, "second": 0, "timeZoneID": "America/New_York", }, "lineItemType": "STANDARD", "primaryGoal": {"goalType": "LIFETIME", "unitType": "IMPRESSIONS", "units": 1000000}, "startDateTimeType": "USE_START_DATE_TIME", "startDateTime": { "date": {"day": 23, "month": 4, "year": 2014}, "hour": 15, "minute": 50, "second": 0, "timeZoneID": "America/New_York", }, "targetPlatform": "ANY", "targeting": { "inventoryTargeting": {"targetedAdUnits": [{"adUnitId": "adunit", "includeDescendants": True}]} }, } # Check transform_forecast_line_item_to_dfp self.assertDictEqual( dfp_start_no_id, transform_forecast_line_item_to_dfp(TEST_LINE_ITEM, use_start=True, preserve_id=False) ) dfp_start_id = { "costType": "CPM", "creativePlaceholders": [ { "creativeSizeType": "PIXEL", "expectedCreativeCount": "1", "size": {"height": "768", "isAspectRatio": False, "width": "1024"}, } ], "endDateTime": { "date": {"day": 31, "month": 5, "year": 2014}, "hour": 23, "minute": 59, "second": 0, "timeZoneID": "America/New_York", }, "lineItemType": "STANDARD", "primaryGoal": {"goalType": "LIFETIME", "unitType": "IMPRESSIONS", "units": 1000000}, "startDateTimeType": "USE_START_DATE_TIME", "startDateTime": { "date": {"day": 23, "month": 4, "year": 2014}, "hour": 15, "minute": 50, "second": 0, "timeZoneID": "America/New_York", }, "targetPlatform": "ANY", "targeting": { "inventoryTargeting": {"targetedAdUnits": [{"adUnitId": "adunit", "includeDescendants": True}]} }, "id": "line_item_id", "orderId": "campaign_id", } # Check transform_forecast_line_item_to_dfp self.assertDictEqual( dfp_start_id, transform_forecast_line_item_to_dfp(TEST_LINE_ITEM, use_start=True, preserve_id=True) )
def test_line_item_forecast_utils(self): dfp_no_start_no_id = { 'costType': 'CPM', 'creativePlaceholders': [{ 'creativeSizeType': 'PIXEL', 'expectedCreativeCount': '1', 'size': { 'height': '768', 'isAspectRatio': False, 'width': '1024', }, }], 'endDateTime': { 'date': { 'day': 31, 'month': 5, 'year': 2014, }, 'hour': 23, 'minute': 59, 'second': 0, 'timeZoneID': 'America/New_York', }, 'lineItemType': 'STANDARD', 'primaryGoal': { 'goalType': 'LIFETIME', 'unitType': 'IMPRESSIONS', 'units': 1000000, }, 'startDateTimeType': 'IMMEDIATELY', 'targetPlatform': 'ANY', 'targeting': { 'inventoryTargeting': { 'targetedAdUnits': [{ 'adUnitId': 'adunit', 'includeDescendants': True, }], }, }, } # Check transform_forecast_line_item_to_dfp self.assertDictEqual( dfp_no_start_no_id, transform_forecast_line_item_to_dfp(TEST_LINE_ITEM, use_start=False, preserve_id=False), ) dfp_start_no_id = { 'costType': 'CPM', 'creativePlaceholders': [{ 'creativeSizeType': 'PIXEL', 'expectedCreativeCount': '1', 'size': { 'height': '768', 'isAspectRatio': False, 'width': '1024', }, }], 'endDateTime': { 'date': { 'day': 31, 'month': 5, 'year': 2014, }, 'hour': 23, 'minute': 59, 'second': 0, 'timeZoneID': 'America/New_York', }, 'lineItemType': 'STANDARD', 'primaryGoal': { 'goalType': 'LIFETIME', 'unitType': 'IMPRESSIONS', 'units': 1000000, }, 'startDateTimeType': 'USE_START_DATE_TIME', 'startDateTime': { 'date': { 'day': 23, 'month': 4, 'year': 2014, }, 'hour': 15, 'minute': 50, 'second': 0, 'timeZoneID': 'America/New_York', }, 'targetPlatform': 'ANY', 'targeting': { 'inventoryTargeting': { 'targetedAdUnits': [{ 'adUnitId': 'adunit', 'includeDescendants': True, }], }, }, } # Check transform_forecast_line_item_to_dfp self.assertDictEqual( dfp_start_no_id, transform_forecast_line_item_to_dfp(TEST_LINE_ITEM, use_start=True, preserve_id=False), ) dfp_start_id = { 'costType': 'CPM', 'creativePlaceholders': [{ 'creativeSizeType': 'PIXEL', 'expectedCreativeCount': '1', 'size': { 'height': '768', 'isAspectRatio': False, 'width': '1024', }, }], 'endDateTime': { 'date': { 'day': 31, 'month': 5, 'year': 2014, }, 'hour': 23, 'minute': 59, 'second': 0, 'timeZoneID': 'America/New_York', }, 'lineItemType': 'STANDARD', 'primaryGoal': { 'goalType': 'LIFETIME', 'unitType': 'IMPRESSIONS', 'units': 1000000, }, 'startDateTimeType': 'USE_START_DATE_TIME', 'startDateTime': { 'date': { 'day': 23, 'month': 4, 'year': 2014, }, 'hour': 15, 'minute': 50, 'second': 0, 'timeZoneID': 'America/New_York', }, 'targetPlatform': 'ANY', 'targeting': { 'inventoryTargeting': { 'targetedAdUnits': [{ 'adUnitId': 'adunit', 'includeDescendants': True, }], }, }, 'id': 'line_item_id', 'orderId': 'campaign_id', } # Check transform_forecast_line_item_to_dfp self.assertDictEqual( dfp_start_id, transform_forecast_line_item_to_dfp(TEST_LINE_ITEM, use_start=True, preserve_id=True), )