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.
Files changed (39) hide show
  1. direct_cli/__init__.py +14 -0
  2. direct_cli/api.py +94 -0
  3. direct_cli/auth.py +58 -0
  4. direct_cli/cli.py +85 -0
  5. direct_cli/commands/__init__.py +61 -0
  6. direct_cli/commands/adextensions.py +96 -0
  7. direct_cli/commands/adgroups.py +189 -0
  8. direct_cli/commands/adimages.py +63 -0
  9. direct_cli/commands/ads.py +306 -0
  10. direct_cli/commands/agencyclients.py +64 -0
  11. direct_cli/commands/audiencetargets.py +187 -0
  12. direct_cli/commands/bidmodifiers.py +110 -0
  13. direct_cli/commands/bids.py +108 -0
  14. direct_cli/commands/businesses.py +61 -0
  15. direct_cli/commands/campaigns.py +311 -0
  16. direct_cli/commands/changes.py +97 -0
  17. direct_cli/commands/clients.py +98 -0
  18. direct_cli/commands/creatives.py +68 -0
  19. direct_cli/commands/dictionaries.py +64 -0
  20. direct_cli/commands/dynamicads.py +104 -0
  21. direct_cli/commands/feeds.py +99 -0
  22. direct_cli/commands/keywordbids.py +111 -0
  23. direct_cli/commands/keywords.py +309 -0
  24. direct_cli/commands/keywordsresearch.py +71 -0
  25. direct_cli/commands/leads.py +65 -0
  26. direct_cli/commands/negativekeywordsharedsets.py +97 -0
  27. direct_cli/commands/reports.py +128 -0
  28. direct_cli/commands/retargeting.py +104 -0
  29. direct_cli/commands/sitelinks.py +92 -0
  30. direct_cli/commands/smartadtargets.py +104 -0
  31. direct_cli/commands/turbopages.py +97 -0
  32. direct_cli/commands/vcards.py +93 -0
  33. direct_cli/output.py +143 -0
  34. direct_cli/utils.py +120 -0
  35. direct_cli-0.0.0.dist-info/METADATA +393 -0
  36. direct_cli-0.0.0.dist-info/RECORD +39 -0
  37. direct_cli-0.0.0.dist-info/WHEEL +5 -0
  38. direct_cli-0.0.0.dist-info/entry_points.txt +2 -0
  39. direct_cli-0.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,108 @@
1
+ """
2
+ Bids 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 bids():
15
+ """Manage bids"""
16
+ pass
17
+
18
+
19
+ @bids.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("--keyword-ids", help="Comma-separated keyword 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(
29
+ ctx, campaign_ids, adgroup_ids, keyword_ids, limit, fetch_all, output_format, output
30
+ ):
31
+ """Get bids"""
32
+ try:
33
+ client = create_client(
34
+ token=ctx.obj.get("token"),
35
+ login=ctx.obj.get("login"),
36
+ sandbox=ctx.obj.get("sandbox"),
37
+ )
38
+
39
+ criteria = {}
40
+ if campaign_ids:
41
+ criteria["CampaignIds"] = parse_ids(campaign_ids)
42
+ if adgroup_ids:
43
+ criteria["AdGroupIds"] = parse_ids(adgroup_ids)
44
+ if keyword_ids:
45
+ criteria["KeywordIds"] = parse_ids(keyword_ids)
46
+
47
+ params = {
48
+ "SelectionCriteria": criteria,
49
+ "FieldNames": ["CampaignId", "AdGroupId", "KeywordId", "Bid"],
50
+ }
51
+
52
+ if limit:
53
+ params["Page"] = {"Limit": limit}
54
+
55
+ body = {"method": "get", "params": params}
56
+
57
+ result = client.bids().post(data=body)
58
+
59
+ if fetch_all:
60
+ items = []
61
+ for item in result().iter_items():
62
+ items.append(item)
63
+ format_output(items, output_format, output)
64
+ else:
65
+ data = result().extract()
66
+ format_output(data, output_format, output)
67
+
68
+ except Exception as e:
69
+ print_error(str(e))
70
+ raise click.Abort()
71
+
72
+
73
+ @bids.command()
74
+ @click.option("--campaign-id", required=True, type=int, help="Campaign ID")
75
+ @click.option("--bid", type=float, help="Bid amount")
76
+ @click.option("--json", "extra_json", help="Additional JSON parameters")
77
+ @click.option("--dry-run", is_flag=True, help="Show request without sending")
78
+ @click.pass_context
79
+ def set(ctx, campaign_id, bid, extra_json, dry_run):
80
+ """Set bids"""
81
+ try:
82
+ bid_data = {"CampaignId": campaign_id}
83
+
84
+ if bid:
85
+ bid_data["Bid"] = int(bid * 1000000)
86
+
87
+ if extra_json:
88
+ extra = json.loads(extra_json)
89
+ bid_data.update(extra)
90
+
91
+ body = {"method": "set", "params": {"Bids": [bid_data]}}
92
+
93
+ if dry_run:
94
+ format_output(body, "json", None)
95
+ return
96
+
97
+ client = create_client(
98
+ token=ctx.obj.get("token"),
99
+ login=ctx.obj.get("login"),
100
+ sandbox=ctx.obj.get("sandbox"),
101
+ )
102
+
103
+ result = client.bids().post(data=body)
104
+ format_output(result().extract(), "json", None)
105
+
106
+ except Exception as e:
107
+ print_error(str(e))
108
+ raise click.Abort()
@@ -0,0 +1,61 @@
1
+ """
2
+ Businesses 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
10
+
11
+
12
+ @click.group()
13
+ def businesses():
14
+ """Manage businesses"""
15
+ pass
16
+
17
+
18
+ @businesses.command()
19
+ @click.option("--ids", help="Comma-separated business 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 businesses"""
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 ["Id", "Name", "Url"]
36
+
37
+ criteria = {}
38
+ if ids:
39
+ criteria["Ids"] = parse_ids(ids)
40
+
41
+ params = {"SelectionCriteria": criteria, "FieldNames": field_names}
42
+
43
+ if limit:
44
+ params["Page"] = {"Limit": limit}
45
+
46
+ body = {"method": "get", "params": params}
47
+
48
+ result = client.businesses().post(data=body)
49
+
50
+ if fetch_all:
51
+ items = []
52
+ for item in result().iter_items():
53
+ items.append(item)
54
+ format_output(items, output_format, output)
55
+ else:
56
+ data = result().extract()
57
+ format_output(data, output_format, output)
58
+
59
+ except Exception as e:
60
+ print_error(str(e))
61
+ raise click.Abort()
@@ -0,0 +1,311 @@
1
+ """
2
+ Campaigns commands
3
+ """
4
+
5
+ import json
6
+ import click
7
+ from typing import Optional, List
8
+
9
+ from ..api import create_client
10
+ from ..output import format_output, print_error
11
+ from ..utils import (
12
+ parse_ids,
13
+ build_selection_criteria,
14
+ build_common_params,
15
+ get_default_fields,
16
+ )
17
+
18
+
19
+ @click.group()
20
+ def campaigns():
21
+ """Manage campaigns"""
22
+ pass
23
+
24
+
25
+ @campaigns.command()
26
+ @click.option("--ids", help="Comma-separated campaign IDs")
27
+ @click.option("--status", help="Filter by status (ACTIVE, SUSPENDED, etc.)")
28
+ @click.option("--types", help="Filter by types (TEXT_CAMPAIGN, etc.)")
29
+ @click.option("--limit", type=int, help="Limit number of results")
30
+ @click.option("--fetch-all", is_flag=True, help="Fetch all pages")
31
+ @click.option(
32
+ "--format",
33
+ "output_format",
34
+ default="json",
35
+ help="Output format (json/table/csv/tsv)",
36
+ )
37
+ @click.option("--output", help="Output file")
38
+ @click.option(
39
+ "--fields", help="Comma-separated field names (default: all common fields)"
40
+ )
41
+ @click.pass_context
42
+ def get(ctx, ids, status, types, limit, fetch_all, output_format, output, fields):
43
+ """Get campaigns"""
44
+ try:
45
+ client = create_client(
46
+ token=ctx.obj.get("token"),
47
+ login=ctx.obj.get("login"),
48
+ sandbox=ctx.obj.get("sandbox"),
49
+ )
50
+
51
+ # Parse field names
52
+ field_names = fields.split(",") if fields else get_default_fields("campaigns")
53
+
54
+ # Build selection criteria
55
+ criteria = build_selection_criteria(
56
+ ids=parse_ids(ids), status=status, types=types
57
+ )
58
+
59
+ # Build params
60
+ params = build_common_params(
61
+ criteria=criteria, field_names=field_names, limit=limit
62
+ )
63
+
64
+ body = {"method": "get", "params": params}
65
+
66
+ result = client.campaigns().post(data=body)
67
+
68
+ if fetch_all:
69
+ # Get all pages
70
+ items = []
71
+ for item in result().iter_items():
72
+ items.append(item)
73
+ format_output(items, output_format, output)
74
+ else:
75
+ data = result().extract()
76
+ format_output(data, output_format, output)
77
+
78
+ except Exception as e:
79
+ print_error(str(e))
80
+ raise click.Abort()
81
+
82
+
83
+ @campaigns.command()
84
+ @click.option("--name", required=True, help="Campaign name")
85
+ @click.option("--start-date", required=True, help="Start date (YYYY-MM-DD)")
86
+ @click.option("--type", "campaign_type", default="TEXT_CAMPAIGN", help="Campaign type")
87
+ @click.option("--budget", type=int, help="Daily budget in currency units")
88
+ @click.option("--end-date", help="End date (YYYY-MM-DD)")
89
+ @click.option("--json", "extra_json", help="Additional JSON parameters")
90
+ @click.option("--dry-run", is_flag=True, help="Show request without sending")
91
+ @click.pass_context
92
+ def add(ctx, name, start_date, campaign_type, budget, end_date, extra_json, dry_run):
93
+ """Add new campaign"""
94
+ try:
95
+ campaign_data = {
96
+ "Name": name,
97
+ "StartDate": start_date,
98
+ "TextCampaign": {
99
+ "BiddingStrategy": {
100
+ "Search": {"BiddingStrategyType": "HIGHEST_POSITION"},
101
+ "Network": {"BiddingStrategyType": "SERVING_OFF"},
102
+ },
103
+ "Settings": [],
104
+ },
105
+ }
106
+
107
+ if budget:
108
+ campaign_data["DailyBudget"] = {
109
+ "Amount": budget * 1000000,
110
+ "Mode": "STANDARD",
111
+ }
112
+
113
+ if end_date:
114
+ campaign_data["EndDate"] = end_date
115
+
116
+ if extra_json:
117
+ extra = json.loads(extra_json)
118
+ campaign_data.update(extra)
119
+
120
+ body = {"method": "add", "params": {"Campaigns": [campaign_data]}}
121
+
122
+ if dry_run:
123
+ format_output(body, "json", None)
124
+ return
125
+
126
+ client = create_client(
127
+ token=ctx.obj.get("token"),
128
+ login=ctx.obj.get("login"),
129
+ sandbox=ctx.obj.get("sandbox"),
130
+ )
131
+
132
+ result = client.campaigns().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
+ @campaigns.command()
141
+ @click.option("--id", "campaign_id", required=True, type=int, help="Campaign ID")
142
+ @click.option("--name", help="New campaign name")
143
+ @click.option("--status", help="New status")
144
+ @click.option("--budget", type=int, help="New daily budget")
145
+ @click.option("--json", "extra_json", help="Additional JSON parameters")
146
+ @click.option("--dry-run", is_flag=True, help="Show request without sending")
147
+ @click.pass_context
148
+ def update(ctx, campaign_id, name, status, budget, extra_json, dry_run):
149
+ """Update campaign"""
150
+ try:
151
+ campaign_data = {"Id": campaign_id}
152
+
153
+ if name:
154
+ campaign_data["Name"] = name
155
+
156
+ if status:
157
+ campaign_data["Status"] = status
158
+
159
+ if budget:
160
+ campaign_data["DailyBudget"] = {
161
+ "Amount": budget * 1000000,
162
+ "Mode": "STANDARD",
163
+ }
164
+
165
+ if extra_json:
166
+ extra = json.loads(extra_json)
167
+ campaign_data.update(extra)
168
+
169
+ body = {"method": "update", "params": {"Campaigns": [campaign_data]}}
170
+
171
+ if dry_run:
172
+ format_output(body, "json", None)
173
+ return
174
+
175
+ client = create_client(
176
+ token=ctx.obj.get("token"),
177
+ login=ctx.obj.get("login"),
178
+ sandbox=ctx.obj.get("sandbox"),
179
+ )
180
+
181
+ result = client.campaigns().post(data=body)
182
+ format_output(result().extract(), "json", None)
183
+
184
+ except Exception as e:
185
+ print_error(str(e))
186
+ raise click.Abort()
187
+
188
+
189
+ @campaigns.command()
190
+ @click.option("--id", "campaign_id", required=True, type=int, help="Campaign ID")
191
+ @click.pass_context
192
+ def delete(ctx, campaign_id):
193
+ """Delete campaign"""
194
+ try:
195
+ client = create_client(
196
+ token=ctx.obj.get("token"),
197
+ login=ctx.obj.get("login"),
198
+ sandbox=ctx.obj.get("sandbox"),
199
+ )
200
+
201
+ body = {
202
+ "method": "delete",
203
+ "params": {"SelectionCriteria": {"Ids": [campaign_id]}},
204
+ }
205
+
206
+ result = client.campaigns().post(data=body)
207
+ format_output(result().extract(), "json", None)
208
+
209
+ except Exception as e:
210
+ print_error(str(e))
211
+ raise click.Abort()
212
+
213
+
214
+ @campaigns.command()
215
+ @click.option("--id", "campaign_id", required=True, type=int, help="Campaign ID")
216
+ @click.pass_context
217
+ def archive(ctx, campaign_id):
218
+ """Archive campaign"""
219
+ try:
220
+ client = create_client(
221
+ token=ctx.obj.get("token"),
222
+ login=ctx.obj.get("login"),
223
+ sandbox=ctx.obj.get("sandbox"),
224
+ )
225
+
226
+ body = {
227
+ "method": "archive",
228
+ "params": {"SelectionCriteria": {"Ids": [campaign_id]}},
229
+ }
230
+
231
+ result = client.campaigns().post(data=body)
232
+ format_output(result().extract(), "json", None)
233
+
234
+ except Exception as e:
235
+ print_error(str(e))
236
+ raise click.Abort()
237
+
238
+
239
+ @campaigns.command()
240
+ @click.option("--id", "campaign_id", required=True, type=int, help="Campaign ID")
241
+ @click.pass_context
242
+ def unarchive(ctx, campaign_id):
243
+ """Unarchive campaign"""
244
+ try:
245
+ client = create_client(
246
+ token=ctx.obj.get("token"),
247
+ login=ctx.obj.get("login"),
248
+ sandbox=ctx.obj.get("sandbox"),
249
+ )
250
+
251
+ body = {
252
+ "method": "unarchive",
253
+ "params": {"SelectionCriteria": {"Ids": [campaign_id]}},
254
+ }
255
+
256
+ result = client.campaigns().post(data=body)
257
+ format_output(result().extract(), "json", None)
258
+
259
+ except Exception as e:
260
+ print_error(str(e))
261
+ raise click.Abort()
262
+
263
+
264
+ @campaigns.command()
265
+ @click.option("--id", "campaign_id", required=True, type=int, help="Campaign ID")
266
+ @click.pass_context
267
+ def suspend(ctx, campaign_id):
268
+ """Suspend campaign"""
269
+ try:
270
+ client = create_client(
271
+ token=ctx.obj.get("token"),
272
+ login=ctx.obj.get("login"),
273
+ sandbox=ctx.obj.get("sandbox"),
274
+ )
275
+
276
+ body = {
277
+ "method": "suspend",
278
+ "params": {"SelectionCriteria": {"Ids": [campaign_id]}},
279
+ }
280
+
281
+ result = client.campaigns().post(data=body)
282
+ format_output(result().extract(), "json", None)
283
+
284
+ except Exception as e:
285
+ print_error(str(e))
286
+ raise click.Abort()
287
+
288
+
289
+ @campaigns.command()
290
+ @click.option("--id", "campaign_id", required=True, type=int, help="Campaign ID")
291
+ @click.pass_context
292
+ def resume(ctx, campaign_id):
293
+ """Resume campaign"""
294
+ try:
295
+ client = create_client(
296
+ token=ctx.obj.get("token"),
297
+ login=ctx.obj.get("login"),
298
+ sandbox=ctx.obj.get("sandbox"),
299
+ )
300
+
301
+ body = {
302
+ "method": "resume",
303
+ "params": {"SelectionCriteria": {"Ids": [campaign_id]}},
304
+ }
305
+
306
+ result = client.campaigns().post(data=body)
307
+ format_output(result().extract(), "json", None)
308
+
309
+ except Exception as e:
310
+ print_error(str(e))
311
+ raise click.Abort()
@@ -0,0 +1,97 @@
1
+ """
2
+ Changes 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
10
+
11
+
12
+ @click.group()
13
+ def changes():
14
+ """Check for changes"""
15
+ pass
16
+
17
+
18
+ @changes.command()
19
+ @click.option("--campaign-ids", required=True, help="Comma-separated campaign IDs")
20
+ @click.option("--timestamp", help="Timestamp for changes check (ISO format)")
21
+ @click.option("--format", "output_format", default="json", help="Output format")
22
+ @click.option("--output", help="Output file")
23
+ @click.pass_context
24
+ def check(ctx, campaign_ids, timestamp, output_format, output):
25
+ """Check changes for campaigns"""
26
+ try:
27
+ client = create_client(
28
+ token=ctx.obj.get("token"),
29
+ login=ctx.obj.get("login"),
30
+ sandbox=ctx.obj.get("sandbox"),
31
+ )
32
+
33
+ params = {"CampaignIds": parse_ids(campaign_ids)}
34
+
35
+ if timestamp:
36
+ params["Timestamp"] = timestamp
37
+
38
+ body = {"method": "check", "params": params}
39
+
40
+ result = client.changes().post(data=body)
41
+ format_output(result.data, output_format, output)
42
+
43
+ except Exception as e:
44
+ print_error(str(e))
45
+ raise click.Abort()
46
+
47
+
48
+ @changes.command()
49
+ @click.option("--timestamp", help="Timestamp for changes check (ISO format)")
50
+ @click.option("--format", "output_format", default="json", help="Output format")
51
+ @click.option("--output", help="Output file")
52
+ @click.pass_context
53
+ def check_campaigns(ctx, timestamp, output_format, output):
54
+ """Check campaigns changes"""
55
+ try:
56
+ client = create_client(
57
+ token=ctx.obj.get("token"),
58
+ login=ctx.obj.get("login"),
59
+ sandbox=ctx.obj.get("sandbox"),
60
+ )
61
+
62
+ params = {}
63
+
64
+ if timestamp:
65
+ params["Timestamp"] = timestamp
66
+
67
+ body = {"method": "checkCampaigns", "params": params}
68
+
69
+ result = client.changes().post(data=body)
70
+ format_output(result.data, output_format, output)
71
+
72
+ except Exception as e:
73
+ print_error(str(e))
74
+ raise click.Abort()
75
+
76
+
77
+ @changes.command()
78
+ @click.option("--format", "output_format", default="json", help="Output format")
79
+ @click.option("--output", help="Output file")
80
+ @click.pass_context
81
+ def check_dictionaries(ctx, output_format, output):
82
+ """Check dictionaries changes"""
83
+ try:
84
+ client = create_client(
85
+ token=ctx.obj.get("token"),
86
+ login=ctx.obj.get("login"),
87
+ sandbox=ctx.obj.get("sandbox"),
88
+ )
89
+
90
+ body = {"method": "checkDictionaries", "params": {}}
91
+
92
+ result = client.changes().post(data=body)
93
+ format_output(result.data, output_format, output)
94
+
95
+ except Exception as e:
96
+ print_error(str(e))
97
+ raise click.Abort()
@@ -0,0 +1,98 @@
1
+ """
2
+ Clients 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, get_default_fields
11
+
12
+
13
+ @click.group()
14
+ def clients():
15
+ """Manage clients"""
16
+ pass
17
+
18
+
19
+ @clients.command()
20
+ @click.option("--ids", help="Comma-separated client IDs")
21
+ @click.option("--limit", type=int, help="Limit number of results")
22
+ @click.option("--fetch-all", is_flag=True, help="Fetch all pages")
23
+ @click.option("--format", "output_format", default="json", help="Output format")
24
+ @click.option("--output", help="Output file")
25
+ @click.option("--fields", help="Comma-separated field names")
26
+ @click.pass_context
27
+ def get(ctx, ids, limit, fetch_all, output_format, output, fields):
28
+ """Get clients"""
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
+ field_names = fields.split(",") if fields else get_default_fields("clients")
37
+
38
+ criteria = {}
39
+ if ids:
40
+ criteria["ClientIds"] = parse_ids(ids)
41
+
42
+ params = {"FieldNames": field_names}
43
+
44
+ if criteria:
45
+ params["SelectionCriteria"] = criteria
46
+
47
+ if limit:
48
+ params["Page"] = {"Limit": limit}
49
+
50
+ body = {"method": "get", "params": params}
51
+
52
+ result = client.clients().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
+ @clients.command()
69
+ @click.option("--client-id", required=True, type=int, help="Client ID")
70
+ @click.option("--json", "extra_json", required=True, help="JSON with updates")
71
+ @click.option("--dry-run", is_flag=True, help="Show request without sending")
72
+ @click.pass_context
73
+ def update(ctx, client_id, extra_json, dry_run):
74
+ """Update client settings"""
75
+ try:
76
+ client_data = {"ClientId": client_id}
77
+
78
+ extra = json.loads(extra_json)
79
+ client_data.update(extra)
80
+
81
+ body = {"method": "update", "params": {"Clients": [client_data]}}
82
+
83
+ if dry_run:
84
+ format_output(body, "json", None)
85
+ return
86
+
87
+ client = create_client(
88
+ token=ctx.obj.get("token"),
89
+ login=ctx.obj.get("login"),
90
+ sandbox=ctx.obj.get("sandbox"),
91
+ )
92
+
93
+ result = client.clients().post(data=body)
94
+ format_output(result().extract(), "json", None)
95
+
96
+ except Exception as e:
97
+ print_error(str(e))
98
+ raise click.Abort()