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,68 @@
1
+ """
2
+ Creatives 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 creatives():
14
+ """Manage creatives"""
15
+ pass
16
+
17
+
18
+ @creatives.command()
19
+ @click.option("--ids", help="Comma-separated creative IDs")
20
+ @click.option("--campaign-ids", help="Comma-separated campaign 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, campaign_ids, limit, fetch_all, output_format, output, fields):
28
+ """Get creatives"""
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 = (
37
+ fields.split(",")
38
+ if fields
39
+ else ["Id", "Name", "Type", "Status", "CampaignId"]
40
+ )
41
+
42
+ criteria = {}
43
+ if ids:
44
+ criteria["Ids"] = parse_ids(ids)
45
+ if campaign_ids:
46
+ criteria["CampaignIds"] = parse_ids(campaign_ids)
47
+
48
+ params = {"SelectionCriteria": criteria, "FieldNames": field_names}
49
+
50
+ if limit:
51
+ params["Page"] = {"Limit": limit}
52
+
53
+ body = {"method": "get", "params": params}
54
+
55
+ result = client.creatives().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()
@@ -0,0 +1,64 @@
1
+ """
2
+ Dictionaries commands
3
+ """
4
+
5
+ import click
6
+
7
+ from ..api import create_client
8
+ from ..output import format_output, print_error
9
+
10
+
11
+ DICTIONARY_NAMES = [
12
+ "Currencies",
13
+ "MetroStations",
14
+ "GeoRegions",
15
+ "TimeZones",
16
+ "Constants",
17
+ "AdCategories",
18
+ "OperationSystemVersions",
19
+ "ProductivityAssertions",
20
+ "SupplySidePlatforms",
21
+ "Interests",
22
+ ]
23
+
24
+
25
+ @click.group()
26
+ def dictionaries():
27
+ """Get reference dictionaries"""
28
+ pass
29
+
30
+
31
+ @dictionaries.command()
32
+ @click.option(
33
+ "--names",
34
+ required=True,
35
+ help="Comma-separated dictionary names (Currencies,GeoRegions,...)",
36
+ )
37
+ @click.option("--format", "output_format", default="json", help="Output format")
38
+ @click.option("--output", help="Output file")
39
+ @click.pass_context
40
+ def get(ctx, names, output_format, output):
41
+ """Get dictionaries"""
42
+ try:
43
+ client = create_client(
44
+ token=ctx.obj.get("token"),
45
+ login=ctx.obj.get("login"),
46
+ sandbox=ctx.obj.get("sandbox"),
47
+ )
48
+
49
+ dictionary_names = [n.strip() for n in names.split(",")]
50
+
51
+ body = {"method": "get", "params": {"DictionaryNames": dictionary_names}}
52
+
53
+ result = client.dictionaries().post(data=body)
54
+ format_output(result.data, output_format, output)
55
+
56
+ except Exception as e:
57
+ print_error(str(e))
58
+ raise click.Abort()
59
+
60
+
61
+ @dictionaries.command()
62
+ def list_names():
63
+ """List available dictionary names"""
64
+ format_output(DICTIONARY_NAMES, "json", None)
@@ -0,0 +1,104 @@
1
+ """
2
+ DynamicAds (Webpages) 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 dynamicads():
15
+ """Manage dynamic ad targets"""
16
+ pass
17
+
18
+
19
+ @dynamicads.command()
20
+ @click.option("--ids", help="Comma-separated target 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.option("--fields", help="Comma-separated field names")
27
+ @click.pass_context
28
+ def get(ctx, ids, adgroup_ids, limit, fetch_all, output_format, output, fields):
29
+ """Get dynamic ad 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
+ field_names = (
38
+ fields.split(",") if fields else ["Id", "AdGroupId", "Condition", "Bid"]
39
+ )
40
+
41
+ criteria = {}
42
+ if ids:
43
+ criteria["Ids"] = parse_ids(ids)
44
+ if adgroup_ids:
45
+ criteria["AdGroupIds"] = parse_ids(adgroup_ids)
46
+
47
+ params = {"SelectionCriteria": criteria, "FieldNames": field_names}
48
+
49
+ if limit:
50
+ params["Page"] = {"Limit": limit}
51
+
52
+ body = {"method": "get", "params": params}
53
+
54
+ result = client.dynamicads().post(data=body)
55
+
56
+ if fetch_all:
57
+ items = []
58
+ for item in result().iter_items():
59
+ items.append(item)
60
+ format_output(items, output_format, output)
61
+ else:
62
+ data = result().extract()
63
+ format_output(data, output_format, output)
64
+
65
+ except Exception as e:
66
+ print_error(str(e))
67
+ raise click.Abort()
68
+
69
+
70
+ @dynamicads.command()
71
+ @click.option("--adgroup-id", required=True, type=int, help="Ad group ID")
72
+ @click.option(
73
+ "--condition", required=True, help='Target condition (e.g., "contains:product")'
74
+ )
75
+ @click.option("--json", "extra_json", help="Additional JSON parameters")
76
+ @click.option("--dry-run", is_flag=True, help="Show request without sending")
77
+ @click.pass_context
78
+ def add(ctx, adgroup_id, condition, extra_json, dry_run):
79
+ """Add dynamic ad target"""
80
+ try:
81
+ target_data = {"AdGroupId": adgroup_id, "Condition": condition}
82
+
83
+ if extra_json:
84
+ extra = json.loads(extra_json)
85
+ target_data.update(extra)
86
+
87
+ body = {"method": "add", "params": {"Webpages": [target_data]}}
88
+
89
+ if dry_run:
90
+ format_output(body, "json", None)
91
+ return
92
+
93
+ client = create_client(
94
+ token=ctx.obj.get("token"),
95
+ login=ctx.obj.get("login"),
96
+ sandbox=ctx.obj.get("sandbox"),
97
+ )
98
+
99
+ result = client.dynamicads().post(data=body)
100
+ format_output(result().extract(), "json", None)
101
+
102
+ except Exception as e:
103
+ print_error(str(e))
104
+ raise click.Abort()
@@ -0,0 +1,99 @@
1
+ """
2
+ Feeds 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 feeds():
15
+ """Manage feeds"""
16
+ pass
17
+
18
+
19
+ @feeds.command()
20
+ @click.option("--ids", help="Comma-separated feed 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 feeds"""
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 = (
37
+ fields.split(",") if fields else ["Id", "Name", "Source", "Status"]
38
+ )
39
+
40
+ criteria = {}
41
+ if ids:
42
+ criteria["Ids"] = parse_ids(ids)
43
+
44
+ params = {"SelectionCriteria": criteria, "FieldNames": field_names}
45
+
46
+ if limit:
47
+ params["Page"] = {"Limit": limit}
48
+
49
+ body = {"method": "get", "params": params}
50
+
51
+ result = client.feeds().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()
65
+
66
+
67
+ @feeds.command()
68
+ @click.option("--name", required=True, help="Feed name")
69
+ @click.option("--url", required=True, help="Feed URL")
70
+ @click.option("--json", "extra_json", help="Additional JSON parameters")
71
+ @click.option("--dry-run", is_flag=True, help="Show request without sending")
72
+ @click.pass_context
73
+ def add(ctx, name, url, extra_json, dry_run):
74
+ """Add feed"""
75
+ try:
76
+ feed_data = {"Name": name, "Source": url}
77
+
78
+ if extra_json:
79
+ extra = json.loads(extra_json)
80
+ feed_data.update(extra)
81
+
82
+ body = {"method": "add", "params": {"Feeds": [feed_data]}}
83
+
84
+ if dry_run:
85
+ format_output(body, "json", None)
86
+ return
87
+
88
+ client = create_client(
89
+ token=ctx.obj.get("token"),
90
+ login=ctx.obj.get("login"),
91
+ sandbox=ctx.obj.get("sandbox"),
92
+ )
93
+
94
+ result = client.feeds().post(data=body)
95
+ format_output(result().extract(), "json", None)
96
+
97
+ except Exception as e:
98
+ print_error(str(e))
99
+ raise click.Abort()
@@ -0,0 +1,111 @@
1
+ """
2
+ KeywordBids 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 keywordbids():
15
+ """Manage keyword bids"""
16
+ pass
17
+
18
+
19
+ @keywordbids.command()
20
+ @click.option("--keyword-ids", help="Comma-separated keyword 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(
29
+ ctx, keyword_ids, adgroup_ids, campaign_ids, limit, fetch_all, output_format, output
30
+ ):
31
+ """Get keyword 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 keyword_ids:
41
+ criteria["KeywordIds"] = parse_ids(keyword_ids)
42
+ if adgroup_ids:
43
+ criteria["AdGroupIds"] = parse_ids(adgroup_ids)
44
+ if campaign_ids:
45
+ criteria["CampaignIds"] = parse_ids(campaign_ids)
46
+
47
+ params = {
48
+ "SelectionCriteria": criteria,
49
+ "FieldNames": ["KeywordId", "AdGroupId", "CampaignId", "Bid", "ContextBid"],
50
+ }
51
+
52
+ if limit:
53
+ params["Page"] = {"Limit": limit}
54
+
55
+ body = {"method": "get", "params": params}
56
+
57
+ result = client.keywordbids().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
+ @keywordbids.command()
74
+ @click.option("--keyword-id", required=True, type=int, help="Keyword ID")
75
+ @click.option("--search-bid", type=float, help="Search bid")
76
+ @click.option("--network-bid", type=float, help="Network 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 set(ctx, keyword_id, search_bid, network_bid, extra_json, dry_run):
81
+ """Set keyword bids"""
82
+ try:
83
+ bid_data = {"KeywordId": keyword_id}
84
+
85
+ if search_bid:
86
+ bid_data["SearchBid"] = int(search_bid * 1000000)
87
+ if network_bid:
88
+ bid_data["NetworkBid"] = int(network_bid * 1000000)
89
+
90
+ if extra_json:
91
+ extra = json.loads(extra_json)
92
+ bid_data.update(extra)
93
+
94
+ body = {"method": "set", "params": {"KeywordBids": [bid_data]}}
95
+
96
+ if dry_run:
97
+ format_output(body, "json", None)
98
+ return
99
+
100
+ client = create_client(
101
+ token=ctx.obj.get("token"),
102
+ login=ctx.obj.get("login"),
103
+ sandbox=ctx.obj.get("sandbox"),
104
+ )
105
+
106
+ result = client.keywordbids().post(data=body)
107
+ format_output(result().extract(), "json", None)
108
+
109
+ except Exception as e:
110
+ print_error(str(e))
111
+ raise click.Abort()