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()
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]:
In [130]:
data
Out[130]:
In [84]:
bid_request.id
Out[84]:
In [92]:
print(len(bid_request.ip))
'.'.join([str(int(i)) for i in bid_request.ip])
Out[92]:
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]:
In [122]:
bid_request.google_user_id
Out[122]:
In [123]:
bid_request.constrained_usage_google_user_id
Out[123]:
In [124]:
bid_request.cookie_version
Out[124]:
In [125]:
bid_request.cookie_age_seconds
Out[125]:
In [126]:
bid_request.hosted_match_data
Out[126]:
In [127]:
bid_request.constrained_usage_hosted_match_data
Out[127]:
In [128]:
bid_request.user_agent
Out[128]:
In [129]:
bid_request.geo_criteria_id
Out[129]:
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]:
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]:
Hyperlocal targeting signal: https://developers.google.com/ad-exchange/rtb/response-guide/decrypt-hyperlocal
In [137]:
bid_request.encrypted_hyperlocal_set
Out[137]:
GMT in minutes. GMT+10 is timezone_offset = 600
In [138]:
bid_request.timezone_offset
Out[138]:
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]:
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]:
In [170]:
# seller_network_id가 주어지고 그 이상의 정보가 필요할 때
bid_request.partner_id
Out[170]:
The URL of the page with parameters removed
In [143]:
bid_request.url
Out[143]:
In [144]:
bid_request.anonymous_id
Out[144]:
In [145]:
bid_request.detected_language
Out[145]:
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]:
In [183]:
# List of detected content labels(content-labels.txt). 컨텐츠 등급.
bid_request.detected_content_label
Out[183]:
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]:
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]:
In [180]:
# mobile carrier.
# https://developers.google.com/adwords/api/docs/appendix/mobilecarriers
bid_request.device.carrier_id
Out[180]:
In [181]:
# width in pixels
bid_request.device.screen_width
Out[181]:
In [182]:
# height in pixels
bid_request.device.screen_height
Out[182]:
In [185]:
# screen_width=320, screen_height=640, and device_pixel_ratio_millis=2000
bid_request.device.screen_pixel_ratio_millis
Out[185]:
In [186]:
# UNKNOWN_ORIENTATION = 0; --> default
# PORTRAIT = 1;
# LANDSCAPE = 2;
bid_request.device.screen_orientation
Out[186]:
In [188]:
# Apple iOS device model, e.g., "iphone 5s", "iphone 6+", "ipad 4".
bid_request.device.hardware_version
Out[188]:
In [162]:
# if true, it is app and app_id is set or anonymous_id is set
bid_request.mobile.is_app
Out[162]:
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]:
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]:
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]:
In [196]:
# Unencrypted version of encrypted_advertising_id, when SSL connection
# 16 byte UUID
bid_request.mobile.advertising_id
Out[196]:
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]:
In [197]:
# Unencrypted version of encrypted_hashed_idfa, when SSL connection
# 16 byte MD5
bid_request.mobile.hashed_idfa
Out[197]:
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]:
In [199]:
bid_request.mobile.constrained_usage_encrypted_hashed_idfa,\
bid_request.mobile.constrained_usage_hashed_idfa
Out[199]:
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]:
In [203]:
# UNKNOWN_PLACEMENT = 0; --> default
# INSTREAM = 1;
# INTERSTITIAL = 2;
bid_request.video.placement
Out[203]:
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]:
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]:
In [208]:
# Whether the inventory allows clicking on the video ad
bid_request.video.is_clickable
Out[208]:
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]:
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]:
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]:
In [212]:
# The maximum number of ads in an Adx video pod
bid_request.video.max_ads_in_pod
Out[212]:
In [213]:
# ALLOW_SKIPPABLE = 0; --> default
# REQUIRE_SKIPPABLE = 1;
# BLOCK_SKIPPABLE = 2;
bid_request.video.video_ad_skippable
Out[213]:
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]:
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]:
In [221]:
bid_request.video.content_attributes.title, \
bid_request.video.content_attributes.duration_seconds, \
bid_request.video.content_attributes.keywords
Out[221]:
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]:
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]:
In [227]:
bid_request.adslot
Out[227]:
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]:
In [230]:
# A stable identifier for the combination of publisher, ad slot, and page.
bid_request.adslot[0].ad_block_key
Out[230]:
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]:
In [236]:
# disallowed attribute ids
# publisher-excludable-creative-attributes.txt
bid_request.adslot[0].excluded_attribute
Out[236]:
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]:
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]:
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]:
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]:
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]:
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]:
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]:
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]:
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]:
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]:
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]:
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]:
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]:
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]:
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 [ ]: