mcm-cli 1.4.1__py3-none-any.whl → 1.5.0__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: mcm-cli
3
- Version: 1.4.1
3
+ Version: 1.5.0
4
4
  Summary: A command-line interface for Moloco Commerde Media
5
5
  Home-page: https://github.com/moloco-mcm/mcm-cli
6
6
  Author: Moloco MCM Team
@@ -1,18 +1,18 @@
1
1
  mcmcli/__init__.py,sha256=-U6lMZ9_99IXAKwnqnYXYr6NcO6TSmG-kxewgvJjU4k,575
2
- mcmcli/__main__.py,sha256=wbiwdsy9Sq1Ebv93G6LlnH7wTb2SUT5gRxxFF9w5Hgc,1844
2
+ mcmcli/__main__.py,sha256=yiI9lBAaJYM57lXTHPKr3teWqU_xF39ZHt52_E1hCN8,1844
3
3
  mcmcli/logging.py,sha256=xjRS5ey1ONx_d34qB1Fetb_SwPysoh2hzNDuNAaYYWQ,1739
4
4
  mcmcli/requests.py,sha256=IuySBQ8P_GoGF3f_TRysfgQNOhi2n9M84WK_eRXnoEU,2945
5
5
  mcmcli/command/account.py,sha256=FWXmzOLj4rVLVLEv-w0eDVlQVrkONvR1UewZbcTDgE4,24994
6
- mcmcli/command/admin.py,sha256=05Ti5nMnuL_Ppo8hy2_bMGwfNZGdN6s528Gpi-EnpDg,16036
6
+ mcmcli/command/admin.py,sha256=2GC0B3oqQsT5N5mHUyezgZvzPkB4-oGtddguOWfdLJs,15980
7
7
  mcmcli/command/auth.py,sha256=Ak7ZNEskWPpMoeTJcbYlEpDBgzxn8N33Q2dNf67SsCs,2926
8
- mcmcli/command/campaign.py,sha256=SU6TrDy6YhqM0JWPzbYWLpXZrz7Ymw31pd168dK2LZk,10638
8
+ mcmcli/command/campaign.py,sha256=wh6WU19dCw0NBTp521g5wK6_0GraviWZxxahIcSlD44,12364
9
9
  mcmcli/command/config.py,sha256=08C5ftAvdvpQ26Z329LqhP8AxTI629LS7Ou6glzrRgw,4396
10
10
  mcmcli/command/decision.py,sha256=iLvEDEa2k0LAgoXrOvcdn-HcFRo90E8Dxht_Ls9EGCY,8690
11
11
  mcmcli/command/report.py,sha256=N8IMyDZ5QpY11-KkZG-n5_ZzEeh-ME5s2s3wrAKEGjY,5387
12
12
  mcmcli/command/wallet.py,sha256=vG2rg7tPwGsV9YB7cpvkiocbqtB1reqXn7dmolFmzD4,11536
13
13
  mcmcli/data/account.py,sha256=pe7tPapP6vlUD5D5L5Nh5k2bkWdYOK01Mpt5fBYFnJs,1782
14
14
  mcmcli/data/account_user.py,sha256=27nQp52nMma5a3QszSJGqgq5Z0ivIb-nMZcZuhEgbEg,1328
15
- mcmcli/data/campaign.py,sha256=vUukEsZ9Lzvcqm4Pa8z7vzyt_qOpT_t6_YEXuLubVSQ,1731
15
+ mcmcli/data/campaign.py,sha256=rbBbLt_5qrNXr8TM4nq5NtPqB0lJmtmINEAyepS7KJ4,2284
16
16
  mcmcli/data/decision.py,sha256=bQ5j_PbPRSFa0sY5g9UVqdNzl_2epchcz1lHoDVuV90,2880
17
17
  mcmcli/data/error.py,sha256=d6xa_jTXumlA0EzXy2PJQ86ajBb0Pm90fss9R3LuHUc,1094
18
18
  mcmcli/data/item.py,sha256=Z2xTRhU8T4vyJADO0l6-XPyQXvb9DX_OAjExhSXpW2A,1091
@@ -23,10 +23,10 @@ mcmcli/data/seller.py,sha256=40SA7QekM3a3svDrDYLo_QYJ68VUxDO0KeGejJMp4k4,1004
23
23
  mcmcli/data/token.py,sha256=11wtyLHCAZHu0LVbNDPa-yipcL6lenxoYIKEI58VzFs,1744
24
24
  mcmcli/data/user_join_request.py,sha256=lXMO2hE_VpRg0JofVrYAVM82S-RLFkPrZk8-drvhoDI,1251
25
25
  mcmcli/data/wallet.py,sha256=eMUi8N0vJdg_E10TPhSPoZkZtmIG7gHyqgabQ8C5Lg8,3217
26
- mcm_cli-1.4.1.dist-info/LICENSE,sha256=RFhQPdSOiMTguUX7JSoIuTxA7HVzCbj_p8WU36HjUQQ,10947
27
- mcm_cli-1.4.1.dist-info/METADATA,sha256=lwdpWx33PEgWxiCl4FBfbqM_CIflw5eLDOLtzCpjK1Y,3056
28
- mcm_cli-1.4.1.dist-info/NOTICE,sha256=Ldnl2MjRaXPxcldUdbI2NTybq60XAa2LowRhFrRTuiI,76
29
- mcm_cli-1.4.1.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
30
- mcm_cli-1.4.1.dist-info/entry_points.txt,sha256=qTHAWZ-ejSiU4t11RYwtAU8ScqhQPDeMVTG9y4wMVLg,60
31
- mcm_cli-1.4.1.dist-info/top_level.txt,sha256=sh7oqIaqLQlMtKHlxHHgpV2xGMrBMPFWpSp0C6nvJ_Y,7
32
- mcm_cli-1.4.1.dist-info/RECORD,,
26
+ mcm_cli-1.5.0.dist-info/LICENSE,sha256=RFhQPdSOiMTguUX7JSoIuTxA7HVzCbj_p8WU36HjUQQ,10947
27
+ mcm_cli-1.5.0.dist-info/METADATA,sha256=M_x0K3WbDKcyEmyXUI7dqa5VFHTH2rKSeT0VTrtFTxc,3056
28
+ mcm_cli-1.5.0.dist-info/NOTICE,sha256=Ldnl2MjRaXPxcldUdbI2NTybq60XAa2LowRhFrRTuiI,76
29
+ mcm_cli-1.5.0.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
30
+ mcm_cli-1.5.0.dist-info/entry_points.txt,sha256=qTHAWZ-ejSiU4t11RYwtAU8ScqhQPDeMVTG9y4wMVLg,60
31
+ mcm_cli-1.5.0.dist-info/top_level.txt,sha256=sh7oqIaqLQlMtKHlxHHgpV2xGMrBMPFWpSp0C6nvJ_Y,7
32
+ mcm_cli-1.5.0.dist-info/RECORD,,
mcmcli/__main__.py CHANGED
@@ -37,7 +37,7 @@ def version():
37
37
  """
38
38
  Show the tool version
39
39
  """
40
- typer.echo(f"Version: mcm-cli v1.4.1")
40
+ typer.echo(f"Version: mcm-cli v1.5.0")
41
41
 
42
42
  app.add_typer(mcmcli.command.account.app, name="account", help="Ad account management")
43
43
  app.add_typer(mcmcli.command.admin.app, name="admin", help="Platform administration")
mcmcli/command/admin.py CHANGED
@@ -68,7 +68,7 @@ def list_all_campaigns(
68
68
  print(error, file=sys.stderr, flush=True)
69
69
  return
70
70
 
71
- print("Account IDAccount Title,Campaign ID,Campaign Title,Ad Type,Start,End,Budget Period,Budget Amount,Enabling State,State,Created At,Updated At,Item IDs")
71
+ print("Account ID,Account Title,Campaign ID,Campaign Title,Ad Type,Start,End,Budget Period,Budget Amount,Enabling State,State,Created At,Updated At")
72
72
  for account_campaign in account_campaigns:
73
73
  a, c = account_campaign
74
74
 
@@ -78,7 +78,8 @@ def list_all_campaigns(
78
78
  print(f'"{c.budget.period}","{int(c.budget.amount.amount_micro) / 1000000}",', end="", flush=True)
79
79
  print(f'"{c.enabling_state}","{c.state}",', end="", flush=True)
80
80
  print(f'"{c.created_at}","{c.updated_at}",', end="", flush=True)
81
- print(f'"{";".join(c.catalog_item_ids)}"')
81
+ # print(f'"{";".join(c.catalog_item_ids)}"')
82
+ print("", flush=True)
82
83
 
83
84
  @app.command()
84
85
  def list_platform_users(
@@ -404,8 +405,6 @@ class AdminCommand:
404
405
  for id in accounts:
405
406
  account = accounts[id]
406
407
  echo('.')
407
- if account.state_info.state == "INACTIVE":
408
- continue
409
408
  # print(f'{account.id}, \"{account.title}\"')
410
409
  _, error, campaigns = cc.list_campaigns(account.id)
411
410
  if error:
@@ -51,7 +51,7 @@ def list_campaigns(
51
51
  print(curl)
52
52
  return
53
53
  if error:
54
- print(f"ERROR: {error.message}")
54
+ print(f"ERROR: {error.message}", file=sys.stderr, flush=True)
55
55
  return
56
56
  if to_json:
57
57
  json_dumps = [x.model_dump_json() for x in campaigns]
@@ -103,6 +103,47 @@ def read_campaign(
103
103
 
104
104
  return
105
105
 
106
+ @app.command()
107
+ def archive_campaign(
108
+ account_id: str = typer.Option(help="Ad account ID"),
109
+ campaign_id: str = typer.Option(help="Campaign ID"),
110
+ profile: str = typer.Option("default", help="Profile name of the MCM CLI."),
111
+ ):
112
+ """
113
+ Turn off (pause and disable) the campaign and archive it.
114
+ """
115
+ c = _create_campaign_command(profile)
116
+ if c is None:
117
+ return
118
+
119
+ _, error, campaign = c.read_campaign(account_id, campaign_id)
120
+ if error:
121
+ print(f"ERROR: Failed to read the campaign {campaign_id} of the ad account {account_id}: {error.message}", file=sys.stderr, flush=True)
122
+ return
123
+
124
+ if campaign.state == 'ARCHIVED':
125
+ print(f"The campaign {campaign_id} of the ad account {account_id} is already archived.")
126
+ return
127
+
128
+ # Turn off the campaign
129
+ campaign.enabling_state = 'DISABLED'
130
+ campaign.state = 'PAUSED'
131
+ #campaign.daily_budget.amount_micro = (campaign.daily_budget.amount_micro // 10000) * 10000
132
+ _, error, campaign = c.update_campaign(campaign)
133
+ if error:
134
+ print(f"ERROR: Failed to turn off the campaign {campaign_id} of the ad account {account_id}: {error.message}", file=sys.stderr, flush=True)
135
+ return
136
+
137
+ # Archive the campaign
138
+ campaign.hidden = True
139
+ campaign.state = 'ARCHIVED'
140
+ _, error, campaign = c.update_campaign(campaign)
141
+ if error:
142
+ print(f"ERROR: Failed to archive the campaign {campaign_id} of the ad account {account_id}: {error.message}", file=sys.stderr, flush=True)
143
+ return
144
+
145
+ print(f"Archived the campaign {campaign_id} of the ad account {account_id}.")
146
+
106
147
  @app.command()
107
148
  def list_campaign_items(
108
149
  account_id: str = typer.Option(help="Ad account ID"),
@@ -124,7 +165,7 @@ def list_campaign_items(
124
165
  print(curl)
125
166
  return
126
167
  if error:
127
- print(f"ERROR: {error.message}")
168
+ print(f"ERROR: {error.message}", file=sys.stderr, flush=True)
128
169
  return
129
170
  if to_json:
130
171
  json_dumps = [x.model_dump_json() for x in items]
@@ -156,7 +197,7 @@ def add_items_to_campaign(
156
197
 
157
198
  _, error, campaign = c.read_campaign(account_id, campaign_id)
158
199
  if error:
159
- print(f"ERROR: {error.message}")
200
+ print(f"ERROR: {error.message}", file=sys.stderr, flush=True)
160
201
  return
161
202
 
162
203
  #
@@ -173,7 +214,7 @@ def add_items_to_campaign(
173
214
  print(curl)
174
215
  return
175
216
  if error:
176
- print(f"ERROR: {error.message}")
217
+ print(f"ERROR: {error.message}", file=sys.stderr, flush=True)
177
218
  return
178
219
  if to_json:
179
220
  print(campaign.model_dump_json())
mcmcli/data/campaign.py CHANGED
@@ -20,7 +20,7 @@ from typing import Optional
20
20
  #
21
21
  class MicroPrice(BaseModel):
22
22
  currency: str
23
- amount_micro: str
23
+ amount_micro: int
24
24
 
25
25
  class Schedule(BaseModel):
26
26
  start: str
@@ -41,6 +41,23 @@ class Goal(BaseModel):
41
41
  optimize_fixed_cpc: Optional[TargetCpc] = None
42
42
  optimize_roas: Optional[TargetRoas] = None
43
43
 
44
+ class TargetingEvent(BaseModel):
45
+ event_type: str
46
+ matching_param: Optional[str] = None
47
+ negative: bool
48
+ matching_date: Optional[str] = None
49
+
50
+ class AudienceSetting(BaseModel):
51
+ event_based: Optional[list[TargetingEvent]] = None
52
+ label: Optional[str] = None
53
+ event_based_include_list: Optional[list[str]] = None
54
+ event_based_exclude_list: Optional[list[str]] = None
55
+
56
+ class Targeting(BaseModel):
57
+ campaign_targeting_placement_type: str
58
+ placement_setting: Optional[str]
59
+ audience_setting: Optional[AudienceSetting]
60
+
44
61
  class Campaign(BaseModel):
45
62
  id: str
46
63
  title: str
@@ -52,7 +69,7 @@ class Campaign(BaseModel):
52
69
  schedule: Schedule
53
70
  daily_budget: MicroPrice
54
71
  budget: Budget
55
- targeting: Optional[str]
72
+ targeting: Optional[Targeting]
56
73
  managed_setting: Optional[str]
57
74
  text_entry: str
58
75
  goal: Goal