direct-cli 0.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- direct_cli/__init__.py +14 -0
- direct_cli/api.py +94 -0
- direct_cli/auth.py +58 -0
- direct_cli/cli.py +85 -0
- direct_cli/commands/__init__.py +61 -0
- direct_cli/commands/adextensions.py +96 -0
- direct_cli/commands/adgroups.py +189 -0
- direct_cli/commands/adimages.py +63 -0
- direct_cli/commands/ads.py +306 -0
- direct_cli/commands/agencyclients.py +64 -0
- direct_cli/commands/audiencetargets.py +187 -0
- direct_cli/commands/bidmodifiers.py +110 -0
- direct_cli/commands/bids.py +108 -0
- direct_cli/commands/businesses.py +61 -0
- direct_cli/commands/campaigns.py +311 -0
- direct_cli/commands/changes.py +97 -0
- direct_cli/commands/clients.py +98 -0
- direct_cli/commands/creatives.py +68 -0
- direct_cli/commands/dictionaries.py +64 -0
- direct_cli/commands/dynamicads.py +104 -0
- direct_cli/commands/feeds.py +99 -0
- direct_cli/commands/keywordbids.py +111 -0
- direct_cli/commands/keywords.py +309 -0
- direct_cli/commands/keywordsresearch.py +71 -0
- direct_cli/commands/leads.py +65 -0
- direct_cli/commands/negativekeywordsharedsets.py +97 -0
- direct_cli/commands/reports.py +128 -0
- direct_cli/commands/retargeting.py +104 -0
- direct_cli/commands/sitelinks.py +92 -0
- direct_cli/commands/smartadtargets.py +104 -0
- direct_cli/commands/turbopages.py +97 -0
- direct_cli/commands/vcards.py +93 -0
- direct_cli/output.py +143 -0
- direct_cli/utils.py +120 -0
- direct_cli-0.0.0.dist-info/METADATA +393 -0
- direct_cli-0.0.0.dist-info/RECORD +39 -0
- direct_cli-0.0.0.dist-info/WHEEL +5 -0
- direct_cli-0.0.0.dist-info/entry_points.txt +2 -0
- direct_cli-0.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Ads commands
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
import click
|
|
7
|
+
|
|
8
|
+
from ..api import create_client
|
|
9
|
+
from ..output import format_output, print_error
|
|
10
|
+
from ..utils import parse_ids
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@click.group()
|
|
14
|
+
def ads():
|
|
15
|
+
"""Manage ads"""
|
|
16
|
+
pass
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@ads.command()
|
|
20
|
+
@click.option("--ids", help="Comma-separated ad IDs")
|
|
21
|
+
@click.option("--campaign-ids", help="Comma-separated campaign IDs")
|
|
22
|
+
@click.option("--adgroup-ids", help="Comma-separated ad group IDs")
|
|
23
|
+
@click.option("--status", help="Filter by status")
|
|
24
|
+
@click.option("--limit", type=int, help="Limit number of results")
|
|
25
|
+
@click.option("--fetch-all", is_flag=True, help="Fetch all pages")
|
|
26
|
+
@click.option("--format", "output_format", default="json", help="Output format")
|
|
27
|
+
@click.option("--output", help="Output file")
|
|
28
|
+
@click.option("--fields", help="Comma-separated field names")
|
|
29
|
+
@click.pass_context
|
|
30
|
+
def get(
|
|
31
|
+
ctx,
|
|
32
|
+
ids,
|
|
33
|
+
campaign_ids,
|
|
34
|
+
adgroup_ids,
|
|
35
|
+
status,
|
|
36
|
+
limit,
|
|
37
|
+
fetch_all,
|
|
38
|
+
output_format,
|
|
39
|
+
output,
|
|
40
|
+
fields,
|
|
41
|
+
):
|
|
42
|
+
"""Get ads"""
|
|
43
|
+
try:
|
|
44
|
+
client = create_client(
|
|
45
|
+
token=ctx.obj.get("token"),
|
|
46
|
+
login=ctx.obj.get("login"),
|
|
47
|
+
sandbox=ctx.obj.get("sandbox"),
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
field_names = (
|
|
51
|
+
fields.split(",")
|
|
52
|
+
if fields
|
|
53
|
+
else ["Id", "CampaignId", "AdGroupId", "Status", "State", "Type"]
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
criteria = {}
|
|
57
|
+
if ids:
|
|
58
|
+
criteria["Ids"] = parse_ids(ids)
|
|
59
|
+
if campaign_ids:
|
|
60
|
+
criteria["CampaignIds"] = parse_ids(campaign_ids)
|
|
61
|
+
if adgroup_ids:
|
|
62
|
+
criteria["AdGroupIds"] = parse_ids(adgroup_ids)
|
|
63
|
+
if status:
|
|
64
|
+
criteria["Statuses"] = [status]
|
|
65
|
+
|
|
66
|
+
params = {"SelectionCriteria": criteria, "FieldNames": field_names}
|
|
67
|
+
|
|
68
|
+
if limit:
|
|
69
|
+
params["Page"] = {"Limit": limit}
|
|
70
|
+
|
|
71
|
+
body = {"method": "get", "params": params}
|
|
72
|
+
|
|
73
|
+
result = client.ads().post(data=body)
|
|
74
|
+
|
|
75
|
+
if fetch_all:
|
|
76
|
+
items = []
|
|
77
|
+
for item in result().iter_items():
|
|
78
|
+
items.append(item)
|
|
79
|
+
format_output(items, output_format, output)
|
|
80
|
+
else:
|
|
81
|
+
data = result().extract()
|
|
82
|
+
format_output(data, output_format, output)
|
|
83
|
+
|
|
84
|
+
except Exception as e:
|
|
85
|
+
print_error(str(e))
|
|
86
|
+
raise click.Abort()
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
@ads.command()
|
|
90
|
+
@click.option("--adgroup-id", required=True, type=int, help="Ad group ID")
|
|
91
|
+
@click.option("--type", "ad_type", default="TEXT_AD", help="Ad type")
|
|
92
|
+
@click.option("--title", help="Ad title")
|
|
93
|
+
@click.option("--text", help="Ad text")
|
|
94
|
+
@click.option("--href", help="Ad URL")
|
|
95
|
+
@click.option("--json", "extra_json", help="Additional JSON parameters")
|
|
96
|
+
@click.option("--dry-run", is_flag=True, help="Show request without sending")
|
|
97
|
+
@click.pass_context
|
|
98
|
+
def add(ctx, adgroup_id, ad_type, title, text, href, extra_json, dry_run):
|
|
99
|
+
"""Add new ad"""
|
|
100
|
+
try:
|
|
101
|
+
ad_data = {"AdGroupId": adgroup_id, "Type": ad_type}
|
|
102
|
+
|
|
103
|
+
if ad_type == "TEXT_AD":
|
|
104
|
+
ad_data["TextAd"] = {}
|
|
105
|
+
if title:
|
|
106
|
+
ad_data["TextAd"]["Title"] = title
|
|
107
|
+
if text:
|
|
108
|
+
ad_data["TextAd"]["Text"] = text
|
|
109
|
+
if href:
|
|
110
|
+
ad_data["TextAd"]["Href"] = href
|
|
111
|
+
|
|
112
|
+
if extra_json:
|
|
113
|
+
extra = json.loads(extra_json)
|
|
114
|
+
ad_data.update(extra)
|
|
115
|
+
|
|
116
|
+
body = {"method": "add", "params": {"Ads": [ad_data]}}
|
|
117
|
+
|
|
118
|
+
if dry_run:
|
|
119
|
+
format_output(body, "json", None)
|
|
120
|
+
return
|
|
121
|
+
|
|
122
|
+
client = create_client(
|
|
123
|
+
token=ctx.obj.get("token"),
|
|
124
|
+
login=ctx.obj.get("login"),
|
|
125
|
+
sandbox=ctx.obj.get("sandbox"),
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
result = client.ads().post(data=body)
|
|
129
|
+
format_output(result().extract(), "json", None)
|
|
130
|
+
|
|
131
|
+
except Exception as e:
|
|
132
|
+
print_error(str(e))
|
|
133
|
+
raise click.Abort()
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
@ads.command()
|
|
137
|
+
@click.option("--id", "ad_id", required=True, type=int, help="Ad ID")
|
|
138
|
+
@click.option("--status", help="New status")
|
|
139
|
+
@click.option("--json", "extra_json", help="Additional JSON parameters")
|
|
140
|
+
@click.option("--dry-run", is_flag=True, help="Show request without sending")
|
|
141
|
+
@click.pass_context
|
|
142
|
+
def update(ctx, ad_id, status, extra_json, dry_run):
|
|
143
|
+
"""Update ad"""
|
|
144
|
+
try:
|
|
145
|
+
ad_data = {"Id": ad_id}
|
|
146
|
+
|
|
147
|
+
if status:
|
|
148
|
+
ad_data["Status"] = status
|
|
149
|
+
|
|
150
|
+
if extra_json:
|
|
151
|
+
extra = json.loads(extra_json)
|
|
152
|
+
ad_data.update(extra)
|
|
153
|
+
|
|
154
|
+
body = {"method": "update", "params": {"Ads": [ad_data]}}
|
|
155
|
+
|
|
156
|
+
if dry_run:
|
|
157
|
+
format_output(body, "json", None)
|
|
158
|
+
return
|
|
159
|
+
|
|
160
|
+
client = create_client(
|
|
161
|
+
token=ctx.obj.get("token"),
|
|
162
|
+
login=ctx.obj.get("login"),
|
|
163
|
+
sandbox=ctx.obj.get("sandbox"),
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
result = client.ads().post(data=body)
|
|
167
|
+
format_output(result().extract(), "json", None)
|
|
168
|
+
|
|
169
|
+
except Exception as e:
|
|
170
|
+
print_error(str(e))
|
|
171
|
+
raise click.Abort()
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
@ads.command()
|
|
175
|
+
@click.option("--id", "ad_id", required=True, type=int, help="Ad ID")
|
|
176
|
+
@click.pass_context
|
|
177
|
+
def delete(ctx, ad_id):
|
|
178
|
+
"""Delete ad"""
|
|
179
|
+
try:
|
|
180
|
+
client = create_client(
|
|
181
|
+
token=ctx.obj.get("token"),
|
|
182
|
+
login=ctx.obj.get("login"),
|
|
183
|
+
sandbox=ctx.obj.get("sandbox"),
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
body = {"method": "delete", "params": {"SelectionCriteria": {"Ids": [ad_id]}}}
|
|
187
|
+
|
|
188
|
+
result = client.ads().post(data=body)
|
|
189
|
+
format_output(result().extract(), "json", None)
|
|
190
|
+
|
|
191
|
+
except Exception as e:
|
|
192
|
+
print_error(str(e))
|
|
193
|
+
raise click.Abort()
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
@ads.command()
|
|
197
|
+
@click.option("--id", "ad_id", required=True, type=int, help="Ad ID")
|
|
198
|
+
@click.pass_context
|
|
199
|
+
def archive(ctx, ad_id):
|
|
200
|
+
"""Archive ad"""
|
|
201
|
+
try:
|
|
202
|
+
client = create_client(
|
|
203
|
+
token=ctx.obj.get("token"),
|
|
204
|
+
login=ctx.obj.get("login"),
|
|
205
|
+
sandbox=ctx.obj.get("sandbox"),
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
body = {"method": "archive", "params": {"SelectionCriteria": {"Ids": [ad_id]}}}
|
|
209
|
+
|
|
210
|
+
result = client.ads().post(data=body)
|
|
211
|
+
format_output(result().extract(), "json", None)
|
|
212
|
+
|
|
213
|
+
except Exception as e:
|
|
214
|
+
print_error(str(e))
|
|
215
|
+
raise click.Abort()
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
@ads.command()
|
|
219
|
+
@click.option("--id", "ad_id", required=True, type=int, help="Ad ID")
|
|
220
|
+
@click.pass_context
|
|
221
|
+
def unarchive(ctx, ad_id):
|
|
222
|
+
"""Unarchive ad"""
|
|
223
|
+
try:
|
|
224
|
+
client = create_client(
|
|
225
|
+
token=ctx.obj.get("token"),
|
|
226
|
+
login=ctx.obj.get("login"),
|
|
227
|
+
sandbox=ctx.obj.get("sandbox"),
|
|
228
|
+
)
|
|
229
|
+
|
|
230
|
+
body = {
|
|
231
|
+
"method": "unarchive",
|
|
232
|
+
"params": {"SelectionCriteria": {"Ids": [ad_id]}},
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
result = client.ads().post(data=body)
|
|
236
|
+
format_output(result().extract(), "json", None)
|
|
237
|
+
|
|
238
|
+
except Exception as e:
|
|
239
|
+
print_error(str(e))
|
|
240
|
+
raise click.Abort()
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
@ads.command()
|
|
244
|
+
@click.option("--id", "ad_id", required=True, type=int, help="Ad ID")
|
|
245
|
+
@click.pass_context
|
|
246
|
+
def suspend(ctx, ad_id):
|
|
247
|
+
"""Suspend ad"""
|
|
248
|
+
try:
|
|
249
|
+
client = create_client(
|
|
250
|
+
token=ctx.obj.get("token"),
|
|
251
|
+
login=ctx.obj.get("login"),
|
|
252
|
+
sandbox=ctx.obj.get("sandbox"),
|
|
253
|
+
)
|
|
254
|
+
|
|
255
|
+
body = {"method": "suspend", "params": {"SelectionCriteria": {"Ids": [ad_id]}}}
|
|
256
|
+
|
|
257
|
+
result = client.ads().post(data=body)
|
|
258
|
+
format_output(result().extract(), "json", None)
|
|
259
|
+
|
|
260
|
+
except Exception as e:
|
|
261
|
+
print_error(str(e))
|
|
262
|
+
raise click.Abort()
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
@ads.command()
|
|
266
|
+
@click.option("--id", "ad_id", required=True, type=int, help="Ad ID")
|
|
267
|
+
@click.pass_context
|
|
268
|
+
def resume(ctx, ad_id):
|
|
269
|
+
"""Resume ad"""
|
|
270
|
+
try:
|
|
271
|
+
client = create_client(
|
|
272
|
+
token=ctx.obj.get("token"),
|
|
273
|
+
login=ctx.obj.get("login"),
|
|
274
|
+
sandbox=ctx.obj.get("sandbox"),
|
|
275
|
+
)
|
|
276
|
+
|
|
277
|
+
body = {"method": "resume", "params": {"SelectionCriteria": {"Ids": [ad_id]}}}
|
|
278
|
+
|
|
279
|
+
result = client.ads().post(data=body)
|
|
280
|
+
format_output(result().extract(), "json", None)
|
|
281
|
+
|
|
282
|
+
except Exception as e:
|
|
283
|
+
print_error(str(e))
|
|
284
|
+
raise click.Abort()
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
@ads.command()
|
|
288
|
+
@click.option("--id", "ad_id", required=True, type=int, help="Ad ID")
|
|
289
|
+
@click.pass_context
|
|
290
|
+
def moderate(ctx, ad_id):
|
|
291
|
+
"""Moderate ad"""
|
|
292
|
+
try:
|
|
293
|
+
client = create_client(
|
|
294
|
+
token=ctx.obj.get("token"),
|
|
295
|
+
login=ctx.obj.get("login"),
|
|
296
|
+
sandbox=ctx.obj.get("sandbox"),
|
|
297
|
+
)
|
|
298
|
+
|
|
299
|
+
body = {"method": "moderate", "params": {"SelectionCriteria": {"Ids": [ad_id]}}}
|
|
300
|
+
|
|
301
|
+
result = client.ads().post(data=body)
|
|
302
|
+
format_output(result().extract(), "json", None)
|
|
303
|
+
|
|
304
|
+
except Exception as e:
|
|
305
|
+
print_error(str(e))
|
|
306
|
+
raise click.Abort()
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"""
|
|
2
|
+
AgencyClients commands
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import click
|
|
6
|
+
|
|
7
|
+
from ..api import create_client
|
|
8
|
+
from ..output import format_output, print_error
|
|
9
|
+
from ..utils import parse_ids, get_default_fields
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@click.group()
|
|
13
|
+
def agencyclients():
|
|
14
|
+
"""Manage agency clients"""
|
|
15
|
+
pass
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@agencyclients.command()
|
|
19
|
+
@click.option("--ids", help="Comma-separated client IDs")
|
|
20
|
+
@click.option("--limit", type=int, help="Limit number of results")
|
|
21
|
+
@click.option("--fetch-all", is_flag=True, help="Fetch all pages")
|
|
22
|
+
@click.option("--format", "output_format", default="json", help="Output format")
|
|
23
|
+
@click.option("--output", help="Output file")
|
|
24
|
+
@click.option("--fields", help="Comma-separated field names")
|
|
25
|
+
@click.pass_context
|
|
26
|
+
def get(ctx, ids, limit, fetch_all, output_format, output, fields):
|
|
27
|
+
"""Get agency clients"""
|
|
28
|
+
try:
|
|
29
|
+
client = create_client(
|
|
30
|
+
token=ctx.obj.get("token"),
|
|
31
|
+
login=ctx.obj.get("login"),
|
|
32
|
+
sandbox=ctx.obj.get("sandbox"),
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
field_names = fields.split(",") if fields else get_default_fields("clients")
|
|
36
|
+
|
|
37
|
+
criteria = {}
|
|
38
|
+
if ids:
|
|
39
|
+
criteria["ClientIds"] = parse_ids(ids)
|
|
40
|
+
|
|
41
|
+
params = {"FieldNames": field_names}
|
|
42
|
+
|
|
43
|
+
if criteria:
|
|
44
|
+
params["SelectionCriteria"] = criteria
|
|
45
|
+
|
|
46
|
+
if limit:
|
|
47
|
+
params["Page"] = {"Limit": limit}
|
|
48
|
+
|
|
49
|
+
body = {"method": "get", "params": params}
|
|
50
|
+
|
|
51
|
+
result = client.agencyclients().post(data=body)
|
|
52
|
+
|
|
53
|
+
if fetch_all:
|
|
54
|
+
items = []
|
|
55
|
+
for item in result().iter_items():
|
|
56
|
+
items.append(item)
|
|
57
|
+
format_output(items, output_format, output)
|
|
58
|
+
else:
|
|
59
|
+
data = result().extract()
|
|
60
|
+
format_output(data, output_format, output)
|
|
61
|
+
|
|
62
|
+
except Exception as e:
|
|
63
|
+
print_error(str(e))
|
|
64
|
+
raise click.Abort()
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
"""
|
|
2
|
+
AudienceTargets commands
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
import click
|
|
7
|
+
|
|
8
|
+
from ..api import create_client
|
|
9
|
+
from ..output import format_output, print_error
|
|
10
|
+
from ..utils import parse_ids
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@click.group()
|
|
14
|
+
def audiencetargets():
|
|
15
|
+
"""Manage audience targets"""
|
|
16
|
+
pass
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@audiencetargets.command()
|
|
20
|
+
@click.option("--ids", help="Comma-separated target IDs")
|
|
21
|
+
@click.option("--adgroup-ids", help="Comma-separated ad group IDs")
|
|
22
|
+
@click.option("--campaign-ids", help="Comma-separated campaign IDs")
|
|
23
|
+
@click.option("--limit", type=int, help="Limit number of results")
|
|
24
|
+
@click.option("--fetch-all", is_flag=True, help="Fetch all pages")
|
|
25
|
+
@click.option("--format", "output_format", default="json", help="Output format")
|
|
26
|
+
@click.option("--output", help="Output file")
|
|
27
|
+
@click.pass_context
|
|
28
|
+
def get(ctx, ids, adgroup_ids, campaign_ids, limit, fetch_all, output_format, output):
|
|
29
|
+
"""Get audience targets"""
|
|
30
|
+
try:
|
|
31
|
+
client = create_client(
|
|
32
|
+
token=ctx.obj.get("token"),
|
|
33
|
+
login=ctx.obj.get("login"),
|
|
34
|
+
sandbox=ctx.obj.get("sandbox"),
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
criteria = {}
|
|
38
|
+
if ids:
|
|
39
|
+
criteria["Ids"] = parse_ids(ids)
|
|
40
|
+
if adgroup_ids:
|
|
41
|
+
criteria["AdGroupIds"] = parse_ids(adgroup_ids)
|
|
42
|
+
if campaign_ids:
|
|
43
|
+
criteria["CampaignIds"] = parse_ids(campaign_ids)
|
|
44
|
+
|
|
45
|
+
params = {
|
|
46
|
+
"SelectionCriteria": criteria,
|
|
47
|
+
"FieldNames": ["Id", "AdGroupId", "RetargetingListId", "State", "Bid"],
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if limit:
|
|
51
|
+
params["Page"] = {"Limit": limit}
|
|
52
|
+
|
|
53
|
+
body = {"method": "get", "params": params}
|
|
54
|
+
|
|
55
|
+
result = client.audiencetargets().post(data=body)
|
|
56
|
+
|
|
57
|
+
if fetch_all:
|
|
58
|
+
items = []
|
|
59
|
+
for item in result().iter_items():
|
|
60
|
+
items.append(item)
|
|
61
|
+
format_output(items, output_format, output)
|
|
62
|
+
else:
|
|
63
|
+
data = result().extract()
|
|
64
|
+
format_output(data, output_format, output)
|
|
65
|
+
|
|
66
|
+
except Exception as e:
|
|
67
|
+
print_error(str(e))
|
|
68
|
+
raise click.Abort()
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
@audiencetargets.command()
|
|
72
|
+
@click.option("--adgroup-id", required=True, type=int, help="Ad group ID")
|
|
73
|
+
@click.option(
|
|
74
|
+
"--retargeting-list-id", required=True, type=int, help="Retargeting list ID"
|
|
75
|
+
)
|
|
76
|
+
@click.option("--bid", type=float, help="Bid")
|
|
77
|
+
@click.option("--json", "extra_json", help="Additional JSON parameters")
|
|
78
|
+
@click.option("--dry-run", is_flag=True, help="Show request without sending")
|
|
79
|
+
@click.pass_context
|
|
80
|
+
def add(ctx, adgroup_id, retargeting_list_id, bid, extra_json, dry_run):
|
|
81
|
+
"""Add audience target"""
|
|
82
|
+
try:
|
|
83
|
+
target_data = {
|
|
84
|
+
"AdGroupId": adgroup_id,
|
|
85
|
+
"RetargetingListId": retargeting_list_id,
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if bid:
|
|
89
|
+
target_data["Bid"] = int(bid * 1000000)
|
|
90
|
+
|
|
91
|
+
if extra_json:
|
|
92
|
+
extra = json.loads(extra_json)
|
|
93
|
+
target_data.update(extra)
|
|
94
|
+
|
|
95
|
+
body = {"method": "add", "params": {"AudienceTargets": [target_data]}}
|
|
96
|
+
|
|
97
|
+
if dry_run:
|
|
98
|
+
format_output(body, "json", None)
|
|
99
|
+
return
|
|
100
|
+
|
|
101
|
+
client = create_client(
|
|
102
|
+
token=ctx.obj.get("token"),
|
|
103
|
+
login=ctx.obj.get("login"),
|
|
104
|
+
sandbox=ctx.obj.get("sandbox"),
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
result = client.audiencetargets().post(data=body)
|
|
108
|
+
format_output(result().extract(), "json", None)
|
|
109
|
+
|
|
110
|
+
except Exception as e:
|
|
111
|
+
print_error(str(e))
|
|
112
|
+
raise click.Abort()
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
@audiencetargets.command()
|
|
116
|
+
@click.option("--id", "target_id", required=True, type=int, help="Target ID")
|
|
117
|
+
@click.pass_context
|
|
118
|
+
def delete(ctx, target_id):
|
|
119
|
+
"""Delete audience target"""
|
|
120
|
+
try:
|
|
121
|
+
client = create_client(
|
|
122
|
+
token=ctx.obj.get("token"),
|
|
123
|
+
login=ctx.obj.get("login"),
|
|
124
|
+
sandbox=ctx.obj.get("sandbox"),
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
body = {
|
|
128
|
+
"method": "delete",
|
|
129
|
+
"params": {"SelectionCriteria": {"Ids": [target_id]}},
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
result = client.audiencetargets().post(data=body)
|
|
133
|
+
format_output(result().extract(), "json", None)
|
|
134
|
+
|
|
135
|
+
except Exception as e:
|
|
136
|
+
print_error(str(e))
|
|
137
|
+
raise click.Abort()
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
@audiencetargets.command()
|
|
141
|
+
@click.option("--id", "target_id", required=True, type=int, help="Target ID")
|
|
142
|
+
@click.pass_context
|
|
143
|
+
def suspend(ctx, target_id):
|
|
144
|
+
"""Suspend audience target"""
|
|
145
|
+
try:
|
|
146
|
+
client = create_client(
|
|
147
|
+
token=ctx.obj.get("token"),
|
|
148
|
+
login=ctx.obj.get("login"),
|
|
149
|
+
sandbox=ctx.obj.get("sandbox"),
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
body = {
|
|
153
|
+
"method": "suspend",
|
|
154
|
+
"params": {"SelectionCriteria": {"Ids": [target_id]}},
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
result = client.audiencetargets().post(data=body)
|
|
158
|
+
format_output(result().extract(), "json", None)
|
|
159
|
+
|
|
160
|
+
except Exception as e:
|
|
161
|
+
print_error(str(e))
|
|
162
|
+
raise click.Abort()
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
@audiencetargets.command()
|
|
166
|
+
@click.option("--id", "target_id", required=True, type=int, help="Target ID")
|
|
167
|
+
@click.pass_context
|
|
168
|
+
def resume(ctx, target_id):
|
|
169
|
+
"""Resume audience target"""
|
|
170
|
+
try:
|
|
171
|
+
client = create_client(
|
|
172
|
+
token=ctx.obj.get("token"),
|
|
173
|
+
login=ctx.obj.get("login"),
|
|
174
|
+
sandbox=ctx.obj.get("sandbox"),
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
body = {
|
|
178
|
+
"method": "resume",
|
|
179
|
+
"params": {"SelectionCriteria": {"Ids": [target_id]}},
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
result = client.audiencetargets().post(data=body)
|
|
183
|
+
format_output(result().extract(), "json", None)
|
|
184
|
+
|
|
185
|
+
except Exception as e:
|
|
186
|
+
print_error(str(e))
|
|
187
|
+
raise click.Abort()
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"""
|
|
2
|
+
BidModifiers commands
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
import click
|
|
7
|
+
|
|
8
|
+
from ..api import create_client
|
|
9
|
+
from ..output import format_output, print_error
|
|
10
|
+
from ..utils import parse_ids
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@click.group()
|
|
14
|
+
def bidmodifiers():
|
|
15
|
+
"""Manage bid modifiers"""
|
|
16
|
+
pass
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@bidmodifiers.command()
|
|
20
|
+
@click.option("--campaign-ids", help="Comma-separated campaign IDs")
|
|
21
|
+
@click.option("--adgroup-ids", help="Comma-separated ad group IDs")
|
|
22
|
+
@click.option("--limit", type=int, help="Limit number of results")
|
|
23
|
+
@click.option("--fetch-all", is_flag=True, help="Fetch all pages")
|
|
24
|
+
@click.option("--format", "output_format", default="json", help="Output format")
|
|
25
|
+
@click.option("--output", help="Output file")
|
|
26
|
+
@click.pass_context
|
|
27
|
+
def get(ctx, campaign_ids, adgroup_ids, limit, fetch_all, output_format, output):
|
|
28
|
+
"""Get bid modifiers"""
|
|
29
|
+
try:
|
|
30
|
+
client = create_client(
|
|
31
|
+
token=ctx.obj.get("token"),
|
|
32
|
+
login=ctx.obj.get("login"),
|
|
33
|
+
sandbox=ctx.obj.get("sandbox"),
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
criteria = {}
|
|
37
|
+
if campaign_ids:
|
|
38
|
+
criteria["CampaignIds"] = parse_ids(campaign_ids)
|
|
39
|
+
if adgroup_ids:
|
|
40
|
+
criteria["AdGroupIds"] = parse_ids(adgroup_ids)
|
|
41
|
+
|
|
42
|
+
params = {
|
|
43
|
+
"SelectionCriteria": criteria,
|
|
44
|
+
"FieldNames": ["Id", "CampaignId", "AdGroupId", "Type", "ModifierValue"],
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if limit:
|
|
48
|
+
params["Page"] = {"Limit": limit}
|
|
49
|
+
|
|
50
|
+
body = {"method": "get", "params": params}
|
|
51
|
+
|
|
52
|
+
result = client.bidmodifiers().post(data=body)
|
|
53
|
+
|
|
54
|
+
if fetch_all:
|
|
55
|
+
items = []
|
|
56
|
+
for item in result().iter_items():
|
|
57
|
+
items.append(item)
|
|
58
|
+
format_output(items, output_format, output)
|
|
59
|
+
else:
|
|
60
|
+
data = result().extract()
|
|
61
|
+
format_output(data, output_format, output)
|
|
62
|
+
|
|
63
|
+
except Exception as e:
|
|
64
|
+
print_error(str(e))
|
|
65
|
+
raise click.Abort()
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
@bidmodifiers.command()
|
|
69
|
+
@click.option("--campaign-id", required=True, type=int, help="Campaign ID")
|
|
70
|
+
@click.option(
|
|
71
|
+
"--type",
|
|
72
|
+
"modifier_type",
|
|
73
|
+
required=True,
|
|
74
|
+
help="Modifier type (DEMOGRAPHICS, MOBILE, etc.)",
|
|
75
|
+
)
|
|
76
|
+
@click.option("--value", type=float, required=True, help="Modifier value")
|
|
77
|
+
@click.option("--json", "extra_json", help="Additional JSON parameters")
|
|
78
|
+
@click.option("--dry-run", is_flag=True, help="Show request without sending")
|
|
79
|
+
@click.pass_context
|
|
80
|
+
def set(ctx, campaign_id, modifier_type, value, extra_json, dry_run):
|
|
81
|
+
"""Set bid modifier"""
|
|
82
|
+
try:
|
|
83
|
+
modifier_data = {
|
|
84
|
+
"CampaignId": campaign_id,
|
|
85
|
+
"Type": modifier_type,
|
|
86
|
+
"BidModifier": value,
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if extra_json:
|
|
90
|
+
extra = json.loads(extra_json)
|
|
91
|
+
modifier_data.update(extra)
|
|
92
|
+
|
|
93
|
+
body = {"method": "set", "params": {"BidModifiers": [modifier_data]}}
|
|
94
|
+
|
|
95
|
+
if dry_run:
|
|
96
|
+
format_output(body, "json", None)
|
|
97
|
+
return
|
|
98
|
+
|
|
99
|
+
client = create_client(
|
|
100
|
+
token=ctx.obj.get("token"),
|
|
101
|
+
login=ctx.obj.get("login"),
|
|
102
|
+
sandbox=ctx.obj.get("sandbox"),
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
result = client.bidmodifiers().post(data=body)
|
|
106
|
+
format_output(result().extract(), "json", None)
|
|
107
|
+
|
|
108
|
+
except Exception as e:
|
|
109
|
+
print_error(str(e))
|
|
110
|
+
raise click.Abort()
|