-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathfb_ads_library_api_cli.py
More file actions
116 lines (98 loc) · 3.68 KB
/
fb_ads_library_api_cli.py
File metadata and controls
116 lines (98 loc) · 3.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#!/usr/bin/env python3
# Copyright (c) Facebook, Inc. and its affiliates.
# All rights reserved.
#
# This source code is licensed under the license found in the
# LICENSE file in the root directory of this source tree.
import argparse
import sys
from fb_ads_library_api import FbAdsLibraryTraversal
from fb_ads_library_api_operators import get_operators, save_to_csv
def get_parser():
parser = argparse.ArgumentParser(
description="The Facebook Ads Library API CLI Utility"
)
parser.add_argument(
"-t",
"--access-token",
help="The Facebook developer access token",
required=True,
)
parser.add_argument(
"-f",
"--fields",
help="Fields to retrieve from the Ad Library API",
default="id,ad_creation_time,ad_creative_bodies,ad_creative_link_captions,ad_creative_link_titles,ad_creative_link_descriptions,ad_delivery_start_time,ad_delivery_stop_time,ad_snapshot_url,bylines,currency,delivery_by_region,demographic_distribution,estimated_audience_size,impressions,page_id,page_name,publisher_platforms,spend",
type=validate_fields_param,
)
parser.add_argument(
"-p",
"--parameters",
help="search parameters to filter the results from the Ad Library API",
required=True,
type=validate_parameters_param,
)
parser.add_argument("--batch-size", type=int, help="Batch size")
parser.add_argument(
"--retry-limit",
type=int,
help="When an error occurs, the script will abort if it fails to get the same batch this amount of times",
)
parser.add_argument(
"--rate-limit",
type=int,
help="How many requests per hour can be made on this token",
)
parser.add_argument("-v", "--verbose", action="store_true")
actions = ",".join(get_operators().keys())
parser.add_argument(
"action", help="Action to take on the ads, possible values: %s" % actions
)
parser.add_argument(
"args", nargs=argparse.REMAINDER, help="The parameter for the specific action"
)
return parser
def validate_country_param(country_input):
if not country_input:
return ""
country_codes = list(filter(lambda x: x.strip(), country_input.split(",")))
return ",".join(country_codes)
def validate_fields_param(fields_input):
if not fields_input:
return False
fields_list = list(
filter(lambda x: x, map(lambda x: x.strip(), fields_input.split(",")))
)
if not fields_list:
raise argparse.ArgumentTypeError("Fields cannot be empty")
return ",".join(fields_list)
def validate_parameters_param(fields_input):
if not fields_input:
return False
fields_dict = {p[0]:p[1] for p in [p_pair.split("=") for p_pair in fields_input.split("&")]}
if not fields_dict:
raise argparse.ArgumentTypeError("parameters cannot be empty")
return fields_dict
def main():
parser = get_parser()
opts = parser.parse_args()
api = FbAdsLibraryTraversal(opts.access_token, opts.fields, opts.parameters)
if opts.retry_limit:
api.retry_limit = opts.retry_limit
if opts.rate_limit:
api.rate_limit = opts.rate_limit
generator_ad_archives = api.generate_ad_archives()
if opts.action in get_operators():
if opts.action == "save_to_csv":
save_to_csv(
generator_ad_archives, opts.args, opts.fields, is_verbose=opts.verbose
)
else:
get_operators()[opts.action](
generator_ad_archives, opts.args, is_verbose=opts.verbose
)
else:
print("Invalid 'action' value: %s" % opts.action)
sys.exit(1)
if __name__ == "__main__":
main()