In [12]:
import sys
sys.path.append('../openbidder')

In [96]:
import base64
import realtime_bidding_pb2

In [14]:
b1 = realtime_bidding_pb2.BidRequest()

기본 서버를 생성하여 openbidder_pb 에서 보내는 데이터를 받아 화면에 출력한다.


In [17]:
from http.server import BaseHTTPRequestHandler, HTTPServer

In [79]:
class HTTPRequestHandler(BaseHTTPRequestHandler):
    def do_POST(self):
        length = self.headers['content-length']
        data = self.rfile.read(int(length))
        with open('sample_message.txt', 'wb') as f:
            f.write(data)
        print(data)
        self.send_response(200, 'OK')
        self.end_headers()

In [80]:
HTTPDeamon = HTTPServer(('', 15000), HTTPRequestHandler)
HTTPDeamon.serve_forever()


----------------------------------------
Exception happened during processing of request from ('127.0.0.1', 53156)
----------------------------------------
Traceback (most recent call last):
  File "/Users/rickypark/anaconda/envs/openbidder/lib/python3.5/socketserver.py", line 313, in _handle_request_noblock
    self.process_request(request, client_address)
  File "/Users/rickypark/anaconda/envs/openbidder/lib/python3.5/socketserver.py", line 341, in process_request
    self.finish_request(request, client_address)
  File "/Users/rickypark/anaconda/envs/openbidder/lib/python3.5/socketserver.py", line 354, in finish_request
    self.RequestHandlerClass(request, client_address, self)
  File "/Users/rickypark/anaconda/envs/openbidder/lib/python3.5/socketserver.py", line 681, in __init__
    self.handle()
  File "/Users/rickypark/anaconda/envs/openbidder/lib/python3.5/http/server.py", line 422, in handle
    self.handle_one_request()
  File "/Users/rickypark/anaconda/envs/openbidder/lib/python3.5/http/server.py", line 410, in handle_one_request
    method()
  File "<ipython-input-79-11ca19d1beab>", line 4, in do_POST
    data = self.read(int(length))
AttributeError: 'HTTPRequestHandler' object has no attribute 'read'
---------------------------------------------------------------------------
KeyboardInterrupt                         Traceback (most recent call last)
<ipython-input-80-b1b526af5bd6> in <module>()
      1 HTTPDeamon = HTTPServer(('', 15000), HTTPRequestHandler)
----> 2 HTTPDeamon.serve_forever()

/Users/rickypark/anaconda/envs/openbidder/lib/python3.5/socketserver.py in serve_forever(self, poll_interval)
    230 
    231                 while not self.__shutdown_request:
--> 232                     ready = selector.select(poll_interval)
    233                     if ready:
    234                         self._handle_request_noblock()

/Users/rickypark/anaconda/envs/openbidder/lib/python3.5/selectors.py in select(self, timeout)
    374             ready = []
    375             try:
--> 376                 fd_event_list = self._poll.poll(timeout)
    377             except InterruptedError:
    378                 return ready

KeyboardInterrupt: 

In [81]:
HTTPDeamon.server_close()

In [31]:
bid_request = realtime_bidding_pb2.BidRequest()
with open('sample_message.txt', 'rb') as f:
    data = f.read()
    bid_request.ParseFromString(data)

In [46]:
data = bid_request.SerializeToString()
type(data)


Out[46]:
bytes

In [130]:
data


Out[130]:
b'\x12\x10A\xef`\r\xbceU\xf6\x0b\x063Z\xba\xa0\xcb\x9d"\x03\xbcl\x0e29Mozilla/5.0 (Windows; U; MSIE 7.0; Windows NT 6.0; en-US)b\x02enj\x08\x08\xe1\x04\x15\xbb\x1a\xcb>j\x08\x08\xba\x04\x15{\xf6\xa9>j\x08\x08\xdf\x04\x15\xc1\xbe\\?j\x08\x08\x9c\x04\x15\xe72`>j\x08\x08\xb1\x03\x15\x9e\xf4\xe4>r*\x08\x02\x10n\x18 "\x02\x08\x012\n\x80\x01\xe9\x01\xec\x01\xe5\x01\xb9\x02J\t\x10\x89\xfd\xc5\x19(\xb0\xf2(yC\x1a\x8b\x05\x00\x00\x00\x00x\x01\x9a\x01\x1ahttp://5.google.anonymous/\xa0\x01\x01\xaa\x01\x1b2o9-Xxk2bjrRb8CzyXwgrTP5vK8\xf8\x01\xeb\x80+\x92\x02\x03E1B\xb8\x02\xcd\x94=\xd1\x02A\x1a\x8b\x05\x00\x00\x00\x00'
  • Unique request id generated by Google. This is 16 bytes long.
  • Required

In [84]:
bid_request.id


Out[84]:
b'A\xef`\r\xbceU\xf6\x0b\x063Z\xba\xa0\xcb\x9d'
  • The first 3 bytes of the IP address in network byte order for IPv4, or the first 6 bytes for IPv6.

In [92]:
print(len(bid_request.ip))
'.'.join([str(int(i)) for i in bid_request.ip])


3
Out[92]:
'188.108.14'
  • When set, the user's cookie/id data allows only restricted usage enum UserDataTreatment { // The current request should be treated as child-directed. TAG_FOR_CHILD_DIRECTED_TREATMENT = 0; }

In [93]:
bid_request.user_data_treatment


Out[93]:
[]
  • The Google ID for the user as described in the documentation for the cookie matching service.
  • unpadded web-safe base64.
  • This field is the same as the Google ID returned by the cookie matching service.
  • Not set if there is one or more user_data_treatment value

In [122]:
bid_request.google_user_id


Out[122]:
'2o9-Xxk2bjrRb8CzyXwgrTP5vK8'
  • Only set if there is one or more user_data_treatment value.
  • If constrained_usage_google_user_id is set, then google_user_id is not set.

In [123]:
bid_request.constrained_usage_google_user_id


Out[123]:
''
  • The version number of the google_user_id

In [124]:
bid_request.cookie_version


Out[124]:
1
  • The time in seconds since the google_user_id was created

In [125]:
bid_request.cookie_age_seconds


Out[125]:
704619
  • Match data stored for this google_user_id through the cookie matching service.
  • If a match exists, then this field holds the decoded data that was passed in the google_hm parameter.

In [126]:
bid_request.hosted_match_data


Out[126]:
b''
  • Only set if there is one or more user_data_treatment value.
  • If constrained_usage_hosted_match_data is set, then hosted_match_data is not set.

In [127]:
bid_request.constrained_usage_hosted_match_data


Out[127]:
b''
  • A string that identifies the browser and type of device

In [128]:
bid_request.user_agent


Out[128]:
'Mozilla/5.0 (Windows; U; MSIE 7.0; Windows NT 6.0; en-US)'
  • Geo information
  • the geo-table.csv table in the technical documentation

In [129]:
bid_request.geo_criteria_id


Out[129]:
1002061

Detected postal code of the appropriate type for the country


In [131]:
bid_request.postal_code


Out[131]:
''

postal_code_prefix field is set when accuracy is too low


In [132]:
bid_request.postal_code_prefix


Out[132]:
'E1B'

location on the Earth's surface a parallelogram with 4 corners

message Hyperlocal { message Point { optional float latitude = 1; optional float longitude = 2; } repeated Point corners = 1; } message HyperlocalSet { repeated Hyperlocal hyperlocal = 1; optional Hyperlocal.Point center_point = 2; }


In [136]:
bid_request.hyperlocal_set.hyperlocal


Out[136]:
[]

In [137]:
bid_request.encrypted_hyperlocal_set


Out[137]:
b''

GMT in minutes. GMT+10 is timezone_offset = 600


In [138]:
bid_request.timezone_offset


Out[138]:
0

Demographic data provided by the publisher

message UserDemographic { enum Gender { UNKNOWN = 0; MALE = 1; FEMALE = 2; } // Gender optional Gender gender = 1 [default = UNKNOWN]; // Age interval optional int32 age_low = 2 [default = 0]; optional int32 age_high = 3 [default = 999]; }


In [139]:
bid_request.user_demographic.gender, bid_request.user_demographic.age_low, bid_request.user_demographic.age_high


Out[139]:
(0, 0, 999)
  • Audience-targeting list(remarketing list)
  • Buyer UI Help topics on remarketing.
message UserList {
    // The user list id.
    optional int64 id = 1;
    // The time in seconds since the user was added to the list.
    optional int32 age_seconds = 2;
}

In [141]:
bid_request.user_list


Out[141]:
[]

seller network id(seller-network-ids.txt)


In [142]:
bid_request.seller_network_id


Out[142]:
0

In [170]:
# seller_network_id가 주어지고 그 이상의 정보가 필요할 때
bid_request.partner_id


Out[170]:
0

The URL of the page with parameters removed


In [143]:
bid_request.url


Out[143]:
''
  • An id for the domain of the page.
  • This is set when the inventory is anonymous.
  • Only one of url or anonymous_id is ever set in the same request

In [144]:
bid_request.anonymous_id


Out[144]:
'http://5.google.anonymous/'

In [145]:
bid_request.detected_language


Out[145]:
['en']

detected verticals for the page

message Vertical {
    // The vertical id(publisher-verticals.txt)
    required int32 id = 1;
    // Weight for this vertical, in the (0.0, 1.0] range.  More relevant
    // verticals have higher weights.
    required float weight = 2;
}

verticals.txt의 넘버링이 체계적으로 되어 있지 못함. depth 별로 역전시켜서 DB화 해야할 것 같음.


In [148]:
bid_request.detected_vertical


Out[148]:
[id: 609
weight: 0.396688312292099
, id: 570
weight: 0.3319586217403412
, id: 607
weight: 0.8622856736183167
, id: 540
weight: 0.21894417703151703
, id: 433
weight: 0.44717878103256226
]

In [183]:
# List of detected content labels(content-labels.txt). 컨텐츠 등급.
bid_request.detected_content_label


Out[183]:
[]

Device Message


In [172]:
# UNKNOWN_DEVICE = 0; // default
# HIGHEND_PHONE = 1;
# TABLET = 2;
# PERSONAL_COMPUTER = 3;  // Desktop or laptop devices.
# CONNECTED_TV = 4;  // Includes both TVs and set-top boxes.
# GAME_CONSOLE = 5;
bid_request.device.device_type


Out[172]:
0

In [173]:
# platform of device.  Examples: android, iphone, palm
bid_request.device.platform


Out[173]:
''

In [174]:
# brand of device, e.g. Nokia, Samsung
bid_request.device.brand


Out[174]:
''

In [175]:
# model of device, e.g. N70, Galaxy
bid_request.device.model


Out[175]:
''

In [179]:
# The OS version; e.g. 2 for Android 2.1, or 3.3 for iOS 3.3.1.
bid_request.device.os_version.major, bid_request.device.os_version.minor, \
bid_request.device.os_version.micro


Out[179]:
(0, 0, 0)

In [180]:
# mobile carrier.
# https://developers.google.com/adwords/api/docs/appendix/mobilecarriers
bid_request.device.carrier_id


Out[180]:
0

In [181]:
# width in pixels
bid_request.device.screen_width


Out[181]:
0

In [182]:
# height in pixels
bid_request.device.screen_height


Out[182]:
0

In [185]:
# screen_width=320, screen_height=640, and device_pixel_ratio_millis=2000
bid_request.device.screen_pixel_ratio_millis


Out[185]:
0

In [186]:
# UNKNOWN_ORIENTATION = 0; --> default
# PORTRAIT = 1;
# LANDSCAPE = 2;
bid_request.device.screen_orientation


Out[186]:
0

In [188]:
# Apple iOS device model, e.g., "iphone 5s", "iphone 6+", "ipad 4".
bid_request.device.hardware_version


Out[188]:
''

Mobile Message

  • Information for ad queries coming from mobile devices(web & app)
  • either a smartphone or a tablet

In [162]:
# if true, it is app and app_id is set or anonymous_id is set
bid_request.mobile.is_app


Out[162]:
False

In [163]:
# app-store id or for Android, qualified package name
bid_request.mobile.app_id


Out[163]:
''

In [164]:
# if true, full screen ad
bid_request.mobile.is_interstitial_request


Out[164]:
False

In [167]:
# mobile app category from iTunes Store and Play Store
# https://developers.google.com/adwords/api/docs/appendix/mobileappcategories
bid_request.mobile.app_category_ids


Out[167]:
[]

In [168]:
# whether the page is optimized for mobile browsers
bid_request.mobile.is_mobile_web_optimized


Out[168]:
False

In [194]:
# Apple's identifier(IDFA) or Android's advertising identifier
# when IDFA, plaintext after decrypting the ciphertext is the IDFA (16 byte UUID)
bid_request.mobile.encrypted_advertising_id


Out[194]:
b''

In [196]:
# Unencrypted version of encrypted_advertising_id, when SSL connection
# 16 byte UUID
bid_request.mobile.advertising_id


Out[196]:
b''

In [195]:
# the plaintext is the 16 byte MD5 hash of the IDFA.
# Later SDKs provide unhashed
bid_request.mobile.encrypted_hashed_idfa


Out[195]:
b''

In [197]:
# Unencrypted version of encrypted_hashed_idfa, when SSL connection
# 16 byte MD5
bid_request.mobile.hashed_idfa


Out[197]:
b''

In [198]:
# when user_data_treatment is set
bid_request.mobile.constrained_usage_encrypted_advertising_id,\
bid_request.mobile.constrained_usage_advertising_id


Out[198]:
(b'', b'')

In [199]:
bid_request.mobile.constrained_usage_encrypted_hashed_idfa,\
bid_request.mobile.constrained_usage_hashed_idfa


Out[199]:
(b'', b'')

In [200]:
# App name for Android apps in Google Play store
bid_request.mobile.app_name


Out[200]:
''

In [202]:
# Average user rating for the app in Google Play store, 1.0~5.0
bid_request.mobile.app_rating


Out[202]:
0

Video Message


In [203]:
# UNKNOWN_PLACEMENT = 0; --> default
# INSTREAM = 1;
# INTERSTITIAL = 2;
bid_request.video.placement


Out[203]:
0

In [204]:
# url of the page
bid_request.video.description_url


Out[204]:
''

In [205]:
# embedded on a page outside the publisher's domain.
# Vimeo video shared on Facebook, url is for Facebook and description_url is for Vimeo
bid_request.video.is_embedded_offsite


Out[205]:
False

In [207]:
# METHOD_UNKNOWN = 0; --> default
# AUTO_PLAY_SOUND_ON = 1;
# AUTO_PLAY_SOUND_OFF = 2;
# CLICK_TO_PLAY = 3;
bid_request.video.playback_method


Out[207]:
0

In [208]:
# Whether the inventory allows clicking on the video ad
bid_request.video.is_clickable


Out[208]:
False

In [209]:
# time in milliseconds from the start of the video
# 0 means pre-roll and -1 means post-roll
bid_request.video.videoad_start_delay


Out[209]:
0

In [210]:
# The maximum duration in milliseconds of the ad that you should return
# If this is not set or has value <= 0, any duration is allowed.
bid_request.video.max_ad_duration


Out[210]:
0

In [211]:
# The minimum duration in milliseconds of the ad that you should return.
# If this is not set or has value <= 0, there is no minimum duration.
bid_request.video.min_ad_duration


Out[211]:
0

In [212]:
# The maximum number of ads in an Adx video pod
bid_request.video.max_ads_in_pod


Out[212]:
0

In [213]:
# ALLOW_SKIPPABLE = 0; --> default
# REQUIRE_SKIPPABLE = 1;
# BLOCK_SKIPPABLE = 2;
bid_request.video.video_ad_skippable


Out[213]:
0

In [214]:
# The maximum duration in milliseconds for the ad you should return, if this ad is skippable
# If this is not set or has value <= 0, any duration is allowed.
bid_request.video.skippable_max_ad_duration


Out[214]:
0

In [215]:
# VIDEO_FLV = 0;    // Flash video files are accepted (FLV).
# VIDEO_MP4 = 1;
# YT_HOSTED = 2;    // Valid VAST ads with at least one media file hosted on youtube.com.
# VPAID_FLASH = 3;  // Flash VPAID (SWF).
# VPAID_JS = 4;     // JavaScript VPAID.
bid_request.video.allowed_video_formats


Out[215]:
[]

In [217]:
# companion ad slots
# message CompanionSlot {
#   // These fields represent the available heights and widths in this slot.
#   repeated int32 height = 1 [packed=true];
#   repeated int32 width  = 2 [packed=true];
#   enum CreativeFormat {
#     IMAGE_CREATIVE = 0;
#     FLASH_CREATIVE = 1;
#     HTML_CREATIVE  = 2;
#   }
#   repeated CreativeFormat creative_format = 3;
# }
bid_request.video.companion_slot


Out[217]:
[]

In [220]:
# the companion ad can be picked to be rendered as an end cap (info card)
# in the video slot after the video ad finishes playing.
# END_CAP_FORBIDDEN and END_CAP_REQUIRED are not supported.
# END_CAP_NOT_ENABLED = 0;  // Companion ad won't be rendered as end cap.
# END_CAP_OPTIONAL = 1;     // End cap will be rendered if response contains
#                           // eligible companion banner, but companion
#                           // banner is not required.
# END_CAP_FORBIDDEN = 2;    // Response with companion ad is filtered.
# END_CAP_REQUIRED = 3;     // Response without companion ad is filtered.
bid_request.video.end_cap_support


Out[220]:
0

In [221]:
bid_request.video.content_attributes.title, \
bid_request.video.content_attributes.duration_seconds, \
bid_request.video.content_attributes.keywords


Out[221]:
('', 0, [])

In [222]:
# The publisher settings list id
# https://developers.google.com/ad-exchange/rtb/pub-settings-guide
# 어떤건지 잘 모르겠음.
bid_request.publisher_settings_list_id


Out[222]:
93002305

In [224]:
# GOOGLE_REPRESENTED is adsense and admob inventory
# UNKNOWN_PUBLISHER_TYPE = 0; --> default
# ADX_PUBLISHER_OWNED_AND_OPERATED = 1;
# ADX_PUBLISHER_REPRESENTED = 2;
# GOOGLE_REPRESENTED = 3;
bid_request.publisher_type


Out[224]:
0

AdSlot Message


In [227]:
bid_request.adslot


Out[227]:
[id: 2
width: 110
height: 32
excluded_attribute: 8
excluded_attribute: 1
allowed_vendor_type: 128
allowed_vendor_type: 233
allowed_vendor_type: 236
allowed_vendor_type: 229
allowed_vendor_type: 313
matching_ad_data {
  billing_id: 53575305
  minimum_cpm_micros: 670000
}
publisher_settings_list_id: 93002307
]

In [228]:
# arbitrarily assigned slot id, usually starts counting from 1
# use this to identify which slot to bid on in the BidResponse
bid_request.adslot[0].id


Out[228]:
2

In [230]:
# A stable identifier for the combination of publisher, ad slot, and page.
bid_request.adslot[0].ad_block_key


Out[230]:
0

In [232]:
# A channel is a set of ad slots on a site.
# Channel names are provided by the publisher
bid_request.adslot[0].targetable_channel


Out[232]:
[]

In [235]:
# can be more than one.
# for video, player size
# for interstitial, first width/height pair is the screen size
bid_request.adslot[0].width, bid_request.adslot[0].height


Out[235]:
([110], [32])

In [236]:
# disallowed attribute ids
# publisher-excludable-creative-attributes.txt
bid_request.adslot[0].excluded_attribute


Out[236]:
[8, 1]

In [240]:
# allowed vendor types(vendors.txt)
# if seller_network is GDN, see gdn-vendors.txt
# not apply to deals with block overrides(see https://support.google.com/adxbuyer/answer/6114194)
bid_request.adslot[0].allowed_vendor_type


Out[240]:
[128, 233, 236, 229, 313]

In [244]:
# disallowed sensitive ad categories(ad-sensitive-categories.txt)
bid_request.adslot[0].excluded_sensitive_category


Out[244]:
[]

In [247]:
# The allowed restricted ad categories(ad-restricted-categories.txt)
bid_request.adslot[0].allowed_restricted_category


Out[247]:
[]

In [246]:
# for preferred deals or programmatic guarantees.
bid_request.adslot[0].allowed_restricted_category_for_deals


Out[246]:
[]

In [249]:
# List of creative languages allowed
# https://developers.google.com/adwords/api/docs/appendix/languagecodes
bid_request.adslot[0].allowed_languages


Out[249]:
[]

In [251]:
# disallowed ad product categories(ad-product-categories.txt)
bid_request.adslot[0].excluded_product_category


Out[251]:
[]

In [254]:
# The billing ids corresponding to the pretargeting configs that matched
bid_request.adslot[0].matching_ad_data[0].billing_id


Out[254]:
[53575305]

In [255]:
# The minimum CPM value that you can bid
# micros of your account currency
bid_request.adslot[0].matching_ad_data[0].minimum_cpm_micros


Out[255]:
670000

In [261]:
# repeated int64 included_advertisers = 1; (advertisers.txt)
# repeated int64 excluded_advertisers = 2;
# repeated int64 included_agencies = 3; (agencies.txt)
# repeated int64 excluded_agencies = 4;
# If set to true, indicates that the specified advertisers/agencies are blocked from bidding.
# optional bool blocked = 5;
# optional int64 minimum_cpm_micros = 6;
bid_request.adslot[0].matching_ad_data[0].pricing_rule


Out[261]:
[]

In [263]:
# optional int64 direct_deal_id = 1;
# optional int64 fixed_cpm_micros = 2;
# enum DealType {
#   UNKNOWN_DEAL_TYPE = 0;
#   PREFERRED_DEAL = 1;
#   PRIVATE_AUCTION = 2;
# }
# optional DealType deal_type = 3 [default = UNKNOWN_DEAL_TYPE];
# optional bool publisher_blocks_overridden = 4 [default = false];
bid_request.adslot[0].matching_ad_data[0].direct_deal


Out[263]:
[]

In [264]:
bid_request.adslot[0].publisher_settings_list_id


Out[264]:
[93002307]

In [267]:
# Parameters related to exchange bidding
bid_request.adslot[0].exchange_bidding.publisher_parameter


Out[267]:
[]

In [270]:
# NO_DETECTION = 0; --> default
# ABOVE_THE_FOLD = 1;
# BELOW_THE_FOLD = 2;
bid_request.adslot[0].slot_visibility


Out[270]:
0

In [271]:
# Viewability percentage for the ad slot.
# 0~100, -1 indicates that viewability could not be estimated.
bid_request.adslot[0].viewability


Out[271]:
-1

In [272]:
# Historical click-through rate for ads served in the ad slot.
# 0~1.0, -1 indicates that CTR data is not available.
bid_request.adslot[0].click_through_rate


Out[272]:
-1

In [273]:
# iFraming state of the ad slot on the webpage where it is present.
# UNKNOWN_IFRAME_STATE = 0; --> default
# NO_IFRAME = 1;
# SAME_DOMAIN_IFRAME = 2;
# CROSS_DOMAIN_IFRAME = 3;
bid_request.adslot[0].iframing_state


Out[273]:
0

In [274]:
# iFrame depth of the ad slot on the webpage where it is present.
# Currently only set for video ad requests.
# UNKNOWN_IFRAME_DEPTH = 0;
# NOT_IN_IFRAME = 1;
# ONE_IFRAME = 2;
# MULTIPLE_IFRAME = 3;
bid_request.adslot[0].iframing_depth


Out[274]:
0

In [278]:
# enum Fields {
#     HEADLINE = 0x1;
#     BODY = 0x2;
#     CALL_TO_ACTION = 0x4;
#     ADVERTISER = 0x8;
#     IMAGE = 0x10;
#     LOGO = 0x20;
#     APP_ICON = 0x40;
#     STAR_RATING = 0x80;
#     PRICE = 0x100;
#     STORE = 0x200;
# }
# optional int64 required_fields = 1;
# optional int64 recommended_fields = 2;
# optional int32 headline_max_safe_length = 3;
# optional int32 body_max_safe_length = 4;
# optional int32 call_to_action_max_safe_length = 5;
# optional int32 advertiser_max_safe_length = 6;
# optional int32 store_max_safe_length = 14;
# optional int32 price_max_safe_length = 15;
# optional int32 image_width = 7;
# optional int32 image_height = 8;
# optional int32 logo_width = 9;
# optional int32 logo_height = 10;
# optional int32 app_icon_width = 11;
# optional int32 app_icon_height = 12;
bid_request.adslot[0].native_ad_template


Out[278]:
[]

In [279]:
# directly from the publisher, or a passback
# UNKNOWN = 0;
# DIRECT_REQUEST = 1;
# MEDIATED = 2;
bid_request.adslot[0].mediation_status


Out[279]:
0

In [282]:
# message AutoRefreshSettings {
#     enum AutoRefreshType {
#       UNKNOWN_AUTO_REFRESH_TYPE = 0;
#       USER_ACTION = 1;  // Refresh triggered by user-initiated action such
#                         // as scrolling.
#       EVENT = 2;  // Event-driven content change. For example, ads refresh
#                   // when the football game score changes on the page.
#       TIME = 3;   // Time-based refresh. Ads refresh on a predefined time
#                   // interval even without user activity.
#     }
#     // The type of the declared auto refresh.
#     optional AutoRefreshType refresh_type = 1
#       [default = UNKNOWN_AUTO_REFRESH_TYPE];

#     // The minimum refresh interval. This applies to all refresh types.
#     optional int32 min_refresh_interval_seconds = 2;
# }
bid_request.adslot[0].auto_refresh.refresh_settings,\
bid_request.adslot[0].auto_refresh.refresh_count


Out[282]:
([], 0)

In [283]:
# ad slot that scrolls along with the content on the page.
# UNKNOWN_STICKINESS = 0;
# IS_STICKY = 1;
bid_request.adslot[0].stickiness


Out[283]:
0

In [284]:
# who controls the environment that made the ad request and will render the ad
# There is no technical difference in how these request are handled
# only set for VAST video ads
# UNKNOWN_RENDERER = 0;
# GOOGLE = 1;
# PUBLISHER = 2;
bid_request.adslot[0].renderer


Out[284]:
0

In [286]:
# Whether this request is for an Accelerated Mobile Page(AMP)
# https://github.com/ampproject/amphtml/blob/master/ads/README.md
# UNKNOWN_AMP = 0;
# NON_AMP_PAGE = 1; --> default
# // Late-loading request from an AMP HTML page. Ad will render with a
# // slight delay so it will not negatively impact page render performance.
# AMP_PAGE_LATE_REQUEST = 2;
bid_request.adslot[0].amp_ad_request_type


Out[286]:
1

In [287]:
# Feedback on bids submitted in previous responses.
# only set if real-time feedback is enabled
# message BidResponseFeedback {
#     // The unique id from BidRequest.id
#     optional bytes request_id = 1;

#     // The index of the BidResponse_Ad if there was more than one. The index
#     // starts at zero for the first creative.
#     optional int32 creative_index = 2;

#     // The status code for the ad. See creative-status-codes.txt in the
#     // technical documentation for a list of ids.
#     optional int32 creative_status_code = 3;

#     // The second price cpm in micros of your account currency if your bid won
#     // the auction, or the cpm that must be exceeded to win the auction if your
#     // bid was outbid. This is only set if your bid participated in the
#     // auction. It is not set if the bid was filtered prior to the auction. It
#     // is also withheld if the publisher or winning bidder has opted out of
#     // price feedback, or if your account has opted out of sharing winning
#     // prices with other bidders.
#     optional int64 cpm_micros = 4;
# }
bid_request.bid_response_feedback


Out[287]:
[]

In [301]:
res = realtime_bidding_pb2.BidResponse()

In [302]:
res.ad


Out[302]:
[]

In [303]:
res.ad.add()


Out[303]:


In [306]:
# A unique identifier chosen by you for the creative in this response
res.ad[0].buyer_creative_id = '10'

In [307]:
# The HTML snippet
res.ad[0].html_snippet = "<img src=''>"

In [308]:
# The URL to fetch a video ad
res.ad[0].video_url = 'http://domain.com/'

In [312]:
# Only one of the following should be set: html_snippet, video_url, or native_ad
# Only set if BidRequest.adslot.native is present
res.ad[0].native_ad.headline = 'title'
res.ad[0].native_ad.body = 'body'
res.ad[0].native_ad.call_to_action = 'button text'
res.ad[0].native_ad.advertiser = 'name of the advertiser'
res.ad[0].native_ad.image.url = 'url'
res.ad[0].native_ad.image.width = 100
res.ad[0].native_ad.image.height = 100
res.ad[0].native_ad.logo.url = 'url'
res.ad[0].native_ad.logo.width = 20
res.ad[0].native_ad.logo.height = 20
res.ad[0].native_ad.app_icon.url = 'url'
res.ad[0].native_ad.app_icon.width = 20
res.ad[0].native_ad.app_icon.height = 20
res.ad[0].native_ad.star_rating = 3.2 # app rating in the app store
res.ad[0].native_ad.click_tracking_url = 'url'
res.ad[0].native_ad.price = '$100' # the price of promoted app
res.ad[0].native_ad.store = 'url to the app store'

In [321]:
res.ad[0].click_through_url.append('url')

In [324]:
# vendors.txt, gdn-vendors.txt
res.ad[0].vendor_type.append(10)

In [329]:
# All attributes for the ads(buyer-declarable-creative-attributes.txt)
# excluded_attribute 에 있는 것이 포함되면 안됨.
res.ad[0].attribute.append(10)

In [328]:
# ad-sensitive-categories.txt
# excluded_sensitive_category 에 있는 것이 포함되면 안됨
res.ad[0].category.append(10)

In [330]:
# ad-restricted-categories.txt
res.ad[0].restricted_category.append(10)

In [331]:
res.ad[0].advertiser_name.append('nitmus')

In [332]:
res.ad[0].bidder_name = 'openbidder'

In [333]:
res.ad[0].width = 100
res.ad[0].height = 100

In [334]:
# agencies.txt
res.ad[0].agency_id = 10

In [337]:
res.ad[0].adslot.add()
res.ad[0].adslot[0].id = 10  # slot id from the BidRequest
res.ad[0].adslot[0].max_cpm_micros = 100
res.ad[0].adslot[0].min_cpm_micros = 90
res.ad[0].adslot[0].billing_id = 10 # BidRequest.AdSlot.matching_ad_data.billing_id
# Leave unset or set it to "1" if a deal is available but you want to
# ignore the deal and participate in the open auction.
res.ad[0].adslot[0].deal_id = 1

In [338]:
res.ad[0].impression_tracking_url.append('url')

In [339]:
# Link to ad preferences page. This is only supported for native ads.
res.ad[0].ad_choices_destination_url = 'url'

In [340]:
res.debug_string = 'is_test string of BidRequest'

In [342]:
# processing time in milliseconds
res.processing_time_ms = 100

In [ ]: