@@ -41,43 +41,24 @@ def __init__(
4141 self .bid_request_distribution_rate = bid_request_distribution_rate
4242
4343
44- # Parse command line to get company file
45- parser = argparse .ArgumentParser (description = "Compute emissions for an ad tech company" )
46- parser .add_argument (
47- "-d" ,
48- "--defaultsFile" ,
49- default = "defaults.yaml" ,
50- help = "Set the defaults file to use (overrides defaults.yaml)" ,
51- )
52- parser .add_argument ("-v" , "--verbose" , action = "store_true" , help = "Show derivation of output" )
53- parser .add_argument (
54- "-p" ,
55- "--partners" ,
56- const = 1 ,
57- default = 0 ,
58- type = int ,
59- nargs = "?" ,
60- help = "Simulate distribution partners" ,
61- )
62- parser .add_argument ("companyFile" , nargs = 1 , help = "The company file to parse in YAML format" )
63- args = parser .parse_args ()
64- if args .verbose :
65- logging .basicConfig (level = logging .INFO )
66-
67- # Load defaults
68- defaultsStream = open (args .defaultsFile , "r" )
69- defaultsDocument = yaml .load (defaultsStream , Loader = SafeLoader )
70-
71- # Load facts about the company
72- stream = open (args .companyFile [0 ], "r" )
73- document = yaml .load (stream , Loader = SafeLoader )
74- if "company" not in document :
75- raise Exception ("No 'company' field found in company file" )
76- if "products" not in document ["company" ]:
77- raise Exception ("No 'products' field found in company file" )
78- if "sources" not in document ["company" ]:
79- raise Exception ("No 'sources' field found in company file" )
80- facts = get_facts_from_sources (document ["company" ]["sources" ])
44+ def get_ad_tech_model_keys () -> set [str ]:
45+ return {
46+ "bid requests processed billion per month" ,
47+ "cookie syncs processed billion per month" ,
48+ "cookie syncs processed per bid request" ,
49+ "cookie sync distribution ratio" ,
50+ "creative serving processed billion per month" ,
51+ "pct of bid requests processed from ad tech platforms" ,
52+ "bid request size in bytes" ,
53+ "bid request rejection pct" ,
54+ "server to server emissions g per gb" ,
55+ "server emissions mt per month" ,
56+ "server emissions g per kwh" ,
57+ "servers processing bid requests pct" ,
58+ "servers processing cookie syncs pct" ,
59+ "servers processing creative serving pct" ,
60+ "datacenter water intensity h2o m^3 per mwh" ,
61+ }
8162
8263
8364def getProductInfo (key : str , default : float | None , product : dict [str , float ], depth : int ):
@@ -228,8 +209,7 @@ def getPrimaryEmissionsPerBidRequest(
228209
229210
230211def getSecondaryEmissionsPerBidRequest (
231- model : AdTechPlatform ,
232- distributionPartners : list [DistributionPartner ],
212+ model : AdTechPlatform , distributionPartners : list [DistributionPartner ], depth : int
233213) -> float :
234214 secondaryEmissionsPerBidRequest = 0.0
235215 for edge in distributionPartners :
@@ -298,7 +278,7 @@ def getPrimaryEmissionsPerCookieSync(
298278
299279
300280def getSecondaryEmissionsPerCookieSync (
301- model : AdTechPlatform , distributionPartners : list [DistributionPartner ]
281+ model : AdTechPlatform , distributionPartners : list [DistributionPartner ], depth : int
302282) -> float :
303283 secondary_emissions_per_cookie_sync = 0.0
304284 for edge in distributionPartners :
@@ -312,49 +292,93 @@ def getSecondaryEmissionsPerCookieSync(
312292 return secondary_emissions_per_cookie_sync
313293
314294
315- depth = 4 if args .verbose else 0
316- productModels = []
317- for product in document ["company" ]["products" ]:
318- if "name" not in product :
319- raise Exception ("No 'name' field found in a product" )
320-
321- logging .info (f"#### { product ['name' ]} " )
322- template = getProductInfo ("template" , None , product , 0 )
323- identifier = getProductInfo ("identifier" , None , product , 0 )
324- serverAllocation = getProductInfo ("server allocation pct" , 100 , product , 0 ) / 100
325- corporateAllocation = getProductInfo ("corporate allocation pct" , 100 , product , 0 ) / 100
326- if template not in defaultsDocument ["defaults" ]:
327- raise Exception (f"Template { template } not found in defaults" )
328- defaults = defaultsDocument ["defaults" ][template ]
329- primaryEmissionsPerBidRequest = getPrimaryEmissionsPerBidRequest (
330- serverAllocation , corporateAllocation , facts , defaults , depth
331- )
332- primaryEmissionsPerCookieSync = getPrimaryEmissionsPerCookieSync (
333- serverAllocation , facts , defaults , depth
334- )
335- cookieSyncDistributionRatio = get_fact_or_default (
336- "cookie sync distribution ratio" , facts , defaults , depth - 1
337- )
338- bidRequestRejectionRate = (
339- get_fact_or_default ("bid request rejection pct" , facts , defaults , depth - 1 ) / 100.0
295+ def main ():
296+
297+ # Parse command line to get company file
298+ parser = argparse .ArgumentParser (description = "Compute emissions for an ad tech company" )
299+ parser .add_argument (
300+ "-d" ,
301+ "--defaultsFile" ,
302+ default = "defaults.yaml" ,
303+ help = "Set the defaults file to use (overrides defaults.yaml)" ,
340304 )
341- model = AdTechPlatform (
342- product ["name" ],
343- identifier ,
344- primaryEmissionsPerBidRequest ,
345- primaryEmissionsPerCookieSync ,
346- cookieSyncDistributionRatio ,
347- bidRequestRejectionRate ,
305+ parser .add_argument ("-v" , "--verbose" , action = "store_true" , help = "Show derivation of output" )
306+ parser .add_argument (
307+ "-p" ,
308+ "--partners" ,
309+ const = 1 ,
310+ default = 0 ,
311+ type = int ,
312+ nargs = "?" ,
313+ help = "Simulate distribution partners" ,
348314 )
349- productModels .append (model )
315+ parser .add_argument ("companyFile" , nargs = 1 , help = "The company file to parse in YAML format" )
316+ args = parser .parse_args ()
317+ if args .verbose :
318+ logging .basicConfig (level = logging .INFO )
319+
320+ # Load defaults
321+ defaultsStream = open (args .defaultsFile , "r" )
322+ defaultsDocument = yaml .load (defaultsStream , Loader = SafeLoader )
323+
324+ # Load facts about the company
325+ stream = open (args .companyFile [0 ], "r" )
326+ document = yaml .load (stream , Loader = SafeLoader )
327+ if "company" not in document :
328+ raise Exception ("No 'company' field found in company file" )
329+ if "products" not in document ["company" ]:
330+ raise Exception ("No 'products' field found in company file" )
331+ if "sources" not in document ["company" ]:
332+ raise Exception ("No 'sources' field found in company file" )
333+ facts = get_facts_from_sources (document ["company" ]["sources" ])
334+
335+ depth = 4 if args .verbose else 0
336+ productModels = []
337+ for product in document ["company" ]["products" ]:
338+ if "name" not in product :
339+ raise Exception ("No 'name' field found in a product" )
340+
341+ logging .info (f"#### { product ['name' ]} " )
342+ template = getProductInfo ("template" , None , product , 0 )
343+ identifier = getProductInfo ("identifier" , None , product , 0 )
344+ serverAllocation = getProductInfo ("server allocation pct" , 100 , product , 0 ) / 100
345+ corporateAllocation = getProductInfo ("corporate allocation pct" , 100 , product , 0 ) / 100
346+ if template not in defaultsDocument ["defaults" ]:
347+ raise Exception (f"Template { template } not found in defaults" )
348+ defaults = defaultsDocument ["defaults" ][template ]
349+ primaryEmissionsPerBidRequest = getPrimaryEmissionsPerBidRequest (
350+ serverAllocation , corporateAllocation , facts , defaults , depth
351+ )
352+ primaryEmissionsPerCookieSync = getPrimaryEmissionsPerCookieSync (
353+ serverAllocation , facts , defaults , depth
354+ )
355+ cookieSyncDistributionRatio = get_fact_or_default (
356+ "cookie sync distribution ratio" , facts , defaults , depth - 1
357+ )
358+ bidRequestRejectionRate = (
359+ get_fact_or_default ("bid request rejection pct" , facts , defaults , depth - 1 ) / 100.0
360+ )
361+ model = AdTechPlatform (
362+ product ["name" ],
363+ identifier ,
364+ primaryEmissionsPerBidRequest ,
365+ primaryEmissionsPerCookieSync ,
366+ cookieSyncDistributionRatio ,
367+ bidRequestRejectionRate ,
368+ )
369+ productModels .append (model )
370+
371+ print (yaml .dump ({"products" : productModels }, Dumper = yaml .Dumper ))
372+
373+ if args .partners and args .verbose :
374+ distributionPartners : list [DistributionPartner ] = []
375+ for i in range (args .partners ):
376+ partner = AdTechPlatform (f"dummy { i } " , f"dummy{ i } .com" , 0.001 , 0.0001 , 1.0 , 0.3 )
377+ distributionPartners .append (DistributionPartner (partner , 1.0 ))
350378
351- print (yaml .dump ({"products" : productModels }, Dumper = yaml .Dumper ))
379+ getSecondaryEmissionsPerBidRequest (productModels [0 ], distributionPartners , depth - 1 )
380+ getSecondaryEmissionsPerCookieSync (productModels [0 ], distributionPartners , depth - 1 )
352381
353- if args .partners and args .verbose :
354- distributionPartners : list [DistributionPartner ] = []
355- for i in range (args .partners ):
356- partner = AdTechPlatform (f"dummy { i } " , f"dummy{ i } .com" , 0.001 , 0.0001 , 1.0 , 0.3 )
357- distributionPartners .append (DistributionPartner (partner , 1.0 ))
358382
359- getSecondaryEmissionsPerBidRequest ( productModels [ 0 ], distributionPartners )
360- getSecondaryEmissionsPerCookieSync ( productModels [ 0 ], distributionPartners )
383+ if __name__ == "__main__" :
384+ main ( )
0 commit comments