mcm-cli 1.1.0__py3-none-any.whl → 1.2.0__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- {mcm_cli-1.1.0.dist-info → mcm_cli-1.2.0.dist-info}/METADATA +1 -1
- {mcm_cli-1.1.0.dist-info → mcm_cli-1.2.0.dist-info}/RECORD +11 -10
- {mcm_cli-1.1.0.dist-info → mcm_cli-1.2.0.dist-info}/WHEEL +1 -1
- mcmcli/__main__.py +1 -1
- mcmcli/command/account.py +333 -0
- mcmcli/data/item.py +42 -0
- mcmcli/requests.py +11 -0
- {mcm_cli-1.1.0.dist-info → mcm_cli-1.2.0.dist-info}/LICENSE +0 -0
- {mcm_cli-1.1.0.dist-info → mcm_cli-1.2.0.dist-info}/NOTICE +0 -0
- {mcm_cli-1.1.0.dist-info → mcm_cli-1.2.0.dist-info}/entry_points.txt +0 -0
- {mcm_cli-1.1.0.dist-info → mcm_cli-1.2.0.dist-info}/top_level.txt +0 -0
@@ -1,8 +1,8 @@
|
|
1
1
|
mcmcli/__init__.py,sha256=-U6lMZ9_99IXAKwnqnYXYr6NcO6TSmG-kxewgvJjU4k,575
|
2
|
-
mcmcli/__main__.py,sha256=
|
2
|
+
mcmcli/__main__.py,sha256=G9B6mZCD2JJpk8nHDdexuKfNigm8WZeFJXhutUEmIUE,1616
|
3
3
|
mcmcli/logging.py,sha256=xjRS5ey1ONx_d34qB1Fetb_SwPysoh2hzNDuNAaYYWQ,1739
|
4
|
-
mcmcli/requests.py,sha256=
|
5
|
-
mcmcli/command/account.py,sha256=
|
4
|
+
mcmcli/requests.py,sha256=ZoQULPpKdAvGtki25Jr6K2Xq2v213XLinzPHUeBi9wo,2601
|
5
|
+
mcmcli/command/account.py,sha256=kxJbBKYrw6OyCdaNZ0K0BEvKgZEAjj5azO-lNSeYLTM,25107
|
6
6
|
mcmcli/command/admin.py,sha256=nJ7rm0nm0jHPobg0PjNHIWaWURTQu6QEUEUKIo__GO0,3010
|
7
7
|
mcmcli/command/auth.py,sha256=QLdr_XFW5BVw9r4a7Kjj5BTBXpSux3AWI9eI03S8aiA,2480
|
8
8
|
mcmcli/command/config.py,sha256=sdzge-l_Yi2P_TlTgSLqShcGyPCzpW3QJzctpIvc-g4,4195
|
@@ -12,13 +12,14 @@ mcmcli/data/account.py,sha256=pe7tPapP6vlUD5D5L5Nh5k2bkWdYOK01Mpt5fBYFnJs,1782
|
|
12
12
|
mcmcli/data/account_user.py,sha256=27nQp52nMma5a3QszSJGqgq5Z0ivIb-nMZcZuhEgbEg,1328
|
13
13
|
mcmcli/data/decision.py,sha256=bQ5j_PbPRSFa0sY5g9UVqdNzl_2epchcz1lHoDVuV90,2880
|
14
14
|
mcmcli/data/error.py,sha256=d6xa_jTXumlA0EzXy2PJQ86ajBb0Pm90fss9R3LuHUc,1094
|
15
|
+
mcmcli/data/item.py,sha256=Z2xTRhU8T4vyJADO0l6-XPyQXvb9DX_OAjExhSXpW2A,1091
|
15
16
|
mcmcli/data/seller.py,sha256=40SA7QekM3a3svDrDYLo_QYJ68VUxDO0KeGejJMp4k4,1004
|
16
17
|
mcmcli/data/token.py,sha256=11wtyLHCAZHu0LVbNDPa-yipcL6lenxoYIKEI58VzFs,1744
|
17
18
|
mcmcli/data/wallet.py,sha256=W-CksF9SPqiv3jZg07Wy8ehVUP5Ot1Gbq2LEGNQCOC8,1906
|
18
|
-
mcm_cli-1.
|
19
|
-
mcm_cli-1.
|
20
|
-
mcm_cli-1.
|
21
|
-
mcm_cli-1.
|
22
|
-
mcm_cli-1.
|
23
|
-
mcm_cli-1.
|
24
|
-
mcm_cli-1.
|
19
|
+
mcm_cli-1.2.0.dist-info/LICENSE,sha256=RFhQPdSOiMTguUX7JSoIuTxA7HVzCbj_p8WU36HjUQQ,10947
|
20
|
+
mcm_cli-1.2.0.dist-info/METADATA,sha256=7ewr0UPyJ6IqNvXOSL7Gci2BryiET3dEqfnuM1BYOxc,3018
|
21
|
+
mcm_cli-1.2.0.dist-info/NOTICE,sha256=Ldnl2MjRaXPxcldUdbI2NTybq60XAa2LowRhFrRTuiI,76
|
22
|
+
mcm_cli-1.2.0.dist-info/WHEEL,sha256=OVMc5UfuAQiSplgO0_WdW7vXVGAt9Hdd6qtN4HotdyA,91
|
23
|
+
mcm_cli-1.2.0.dist-info/entry_points.txt,sha256=qTHAWZ-ejSiU4t11RYwtAU8ScqhQPDeMVTG9y4wMVLg,60
|
24
|
+
mcm_cli-1.2.0.dist-info/top_level.txt,sha256=sh7oqIaqLQlMtKHlxHHgpV2xGMrBMPFWpSp0C6nvJ_Y,7
|
25
|
+
mcm_cli-1.2.0.dist-info/RECORD,,
|
mcmcli/__main__.py
CHANGED
@@ -35,7 +35,7 @@ def version():
|
|
35
35
|
"""
|
36
36
|
Show the tool version
|
37
37
|
"""
|
38
|
-
typer.echo(f"Version: mcm-cli v1.
|
38
|
+
typer.echo(f"Version: mcm-cli v1.2.0")
|
39
39
|
|
40
40
|
app.add_typer(mcmcli.command.account.app, name="account", help="Ad account management")
|
41
41
|
app.add_typer(mcmcli.command.admin.app, name="admin", help="Platform administration")
|
mcmcli/command/account.py
CHANGED
@@ -16,6 +16,7 @@ from enum import Enum
|
|
16
16
|
from mcmcli.data.account import Account, AccountListWrapper
|
17
17
|
from mcmcli.data.account_user import User, UserWrapper, UserListWrapper
|
18
18
|
from mcmcli.data.error import Error
|
19
|
+
from mcmcli.data.item import ItemList, Item
|
19
20
|
from mcmcli.data.seller import Seller, SellerListWrapper
|
20
21
|
from mcmcli.requests import CurlString, api_request
|
21
22
|
from typing import Any, Callable, Dict, Optional, Tuple, TypeVar
|
@@ -95,6 +96,16 @@ def bulk_invite_ad_account_owners(
|
|
95
96
|
continue
|
96
97
|
account_creation_count += 1
|
97
98
|
|
99
|
+
#
|
100
|
+
# TODO: investigate if this step is necessary
|
101
|
+
# Activate the ad account
|
102
|
+
#
|
103
|
+
#if account:
|
104
|
+
# error = a.activate_account_with_retry(account)
|
105
|
+
# if error:
|
106
|
+
# print(f"\nERROR: Failed to activate the ad account {account_id}. {error.message}.", file=sys.stderr, flush=True)
|
107
|
+
# continue
|
108
|
+
|
98
109
|
error = a.send_invitation_email_with_retry(account_id, email_address, user_name, create_user, dry_run)
|
99
110
|
if error:
|
100
111
|
print(f"\nERROR: Failed to send the mail for the ad account ID {account_id}. {error.message}.", file=sys.stderr, flush=True)
|
@@ -151,6 +162,187 @@ def bulk_check_user_registrations(
|
|
151
162
|
print(f'"{account_id}","{is_account_exist}","{email_address}","{is_user_exist}","{user_role}","{user_status}"')
|
152
163
|
return
|
153
164
|
|
165
|
+
@app.command()
|
166
|
+
def delete_user(
|
167
|
+
account_id: str = typer.Option(help="Ad account ID"),
|
168
|
+
user_email: str = typer.Option(help="User's email address"),
|
169
|
+
email_notification: bool = typer.Option(True, help="Send the email notification to the user"),
|
170
|
+
profile: str = typer.Option("default", help="profile name of the MCM CLI."),
|
171
|
+
):
|
172
|
+
"""
|
173
|
+
Delete the email user. It will send the notification email to the user by default.
|
174
|
+
Please use the `--no-email-notification` option if you want to skip it.
|
175
|
+
"""
|
176
|
+
a = _create_account_command(profile)
|
177
|
+
if a is None:
|
178
|
+
return
|
179
|
+
|
180
|
+
err, users = a.list_account_users(account_id)
|
181
|
+
if err:
|
182
|
+
print(f"ERROR: {err}", file=sys.stderr, flush=True)
|
183
|
+
sys.exit()
|
184
|
+
if user_email not in users:
|
185
|
+
print(f"ERROR: The email user {user_email} was not found in the ad account {account_id}.", file=sys.stderr, flush=True)
|
186
|
+
sys.exit()
|
187
|
+
|
188
|
+
user_id = users[user_email].id
|
189
|
+
err = a.delete_user(account_id, user_id, email_notification)
|
190
|
+
if err:
|
191
|
+
print(f"ERROR: {err}", file=sys.stderr, flush=True)
|
192
|
+
sys.exit()
|
193
|
+
|
194
|
+
print(f'Successfully deleted the email user {user_email} from the ad account ID {account_id}.')
|
195
|
+
|
196
|
+
|
197
|
+
@app.command()
|
198
|
+
def invite_user(
|
199
|
+
account_id: str = typer.Option(help="Ad account ID"),
|
200
|
+
user_email: str = typer.Option(help="User's email address"),
|
201
|
+
user_name: str = typer.Option(help="User's name"),
|
202
|
+
user_role: UserRole = typer.Option(UserRole.AD_ACCOUNT_OWNER.value, help="User Role"),
|
203
|
+
to_curl: bool = typer.Option(False, help="Generate the curl command instead of executing it."),
|
204
|
+
profile: str = typer.Option("default", help="profile name of the MCM CLI."),
|
205
|
+
):
|
206
|
+
"""
|
207
|
+
Invite a user as an ad account owner. The process creates the ad account if it doesn’t exist
|
208
|
+
and sends an invitation email to the user.
|
209
|
+
"""
|
210
|
+
a = _create_account_command(profile)
|
211
|
+
if a is None:
|
212
|
+
return
|
213
|
+
|
214
|
+
#
|
215
|
+
# get the list of sellers
|
216
|
+
#
|
217
|
+
_, error, seller_dictionary = a.list_sellers()
|
218
|
+
if error:
|
219
|
+
print(f"ERROR: {error.message}")
|
220
|
+
sys.exit()
|
221
|
+
|
222
|
+
seller = _lookup_dict(account_id, seller_dictionary)
|
223
|
+
if seller is None:
|
224
|
+
print(f"ERROR: Could not find the ad account ID {account_id}")
|
225
|
+
sys.exit()
|
226
|
+
|
227
|
+
#
|
228
|
+
# create the ad account first
|
229
|
+
#
|
230
|
+
_, error, _ = a.create_account(seller.id, seller.title, to_curl=False)
|
231
|
+
if error and error.code != 6:
|
232
|
+
# error code 6 means the ad account already exists; we can ignore it.
|
233
|
+
print(f"ERROR: {error.message}")
|
234
|
+
sys.exit()
|
235
|
+
|
236
|
+
# We can assume that the ad account exists at this line, because we checked it above.
|
237
|
+
|
238
|
+
#
|
239
|
+
# invite the user
|
240
|
+
#
|
241
|
+
curl, error, user_join_request = a.invite_user(account_id, user_email, user_name, user_role, to_curl)
|
242
|
+
if to_curl:
|
243
|
+
print(curl)
|
244
|
+
elif error:
|
245
|
+
print(f"ERROR: {error.message}")
|
246
|
+
sys.exit()
|
247
|
+
else:
|
248
|
+
print(user_join_request)
|
249
|
+
|
250
|
+
|
251
|
+
@app.command()
|
252
|
+
def create_account(
|
253
|
+
account_id: str = typer.Option(help="Ad account ID"),
|
254
|
+
account_name: str = typer.Option(help="Ad account name"),
|
255
|
+
to_curl: bool = typer.Option(False, help="Generate the curl command instead of executing it."),
|
256
|
+
to_json: bool = typer.Option(False, help="Print raw output in json"),
|
257
|
+
profile: str = typer.Option("default", help="profile name of the MCM CLI."),
|
258
|
+
):
|
259
|
+
"""
|
260
|
+
Create a new ad account.
|
261
|
+
"""
|
262
|
+
a = _create_account_command(profile)
|
263
|
+
if a is None:
|
264
|
+
return
|
265
|
+
|
266
|
+
curl, error, account_info = a.create_account(account_id, account_name, to_curl)
|
267
|
+
if to_curl:
|
268
|
+
print(curl)
|
269
|
+
sys.exit()
|
270
|
+
if error:
|
271
|
+
print(f"ERROR: {error.message}")
|
272
|
+
sys.exit()
|
273
|
+
if account_info is None:
|
274
|
+
print(f"ERROR: account information is None, which is not supposed to be.")
|
275
|
+
sys.exit()
|
276
|
+
|
277
|
+
if to_json:
|
278
|
+
print(account_info.model_dump_json())
|
279
|
+
sys.exit()
|
280
|
+
|
281
|
+
print(f"""Ad account ID {account_info.id} ("{account_info.title}") has been created.""")
|
282
|
+
|
283
|
+
|
284
|
+
@app.command()
|
285
|
+
def list_accounts(
|
286
|
+
to_curl: bool = typer.Option(False, help="Generate the curl command instead of executing it."),
|
287
|
+
to_json: bool = typer.Option(False, help="Print raw output in json"),
|
288
|
+
profile: str = typer.Option("default", help="profile name of the MCM CLI."),
|
289
|
+
):
|
290
|
+
"""
|
291
|
+
List all ad accounts on the platform.
|
292
|
+
"""
|
293
|
+
a = _create_account_command(profile)
|
294
|
+
if a is None:
|
295
|
+
return
|
296
|
+
|
297
|
+
curl, error, accounts = a.list_accounts(to_curl)
|
298
|
+
if to_curl:
|
299
|
+
print(curl)
|
300
|
+
return
|
301
|
+
if error:
|
302
|
+
print(f"ERROR: {error.message}")
|
303
|
+
return
|
304
|
+
if to_json:
|
305
|
+
json_dumps = [x.model_dump_json() for x in accounts.values()]
|
306
|
+
print(f"[{','.join(json_dumps)}]")
|
307
|
+
return
|
308
|
+
|
309
|
+
print("Ad Account ID, State, Ad Account Title")
|
310
|
+
for a in accounts.values():
|
311
|
+
print(f"{a.id}, {a.state_info.state}, {a.title}")
|
312
|
+
|
313
|
+
return
|
314
|
+
|
315
|
+
@app.command()
|
316
|
+
def list_account_items(
|
317
|
+
account_id: str = typer.Option(help="Ad account ID"),
|
318
|
+
to_curl: bool = typer.Option(False, help="Generate the curl command instead of executing it."),
|
319
|
+
to_json: bool = typer.Option(False, help="Print raw output in json"),
|
320
|
+
profile: str = typer.Option("default", help="profile name of the MCM CLI."),
|
321
|
+
):
|
322
|
+
"""
|
323
|
+
List all items for a given ad account.
|
324
|
+
"""
|
325
|
+
a = _create_account_command(profile)
|
326
|
+
if a is None:
|
327
|
+
return
|
328
|
+
|
329
|
+
curl, error, items = a.list_account_items(account_id, to_curl)
|
330
|
+
|
331
|
+
if to_curl:
|
332
|
+
print(curl)
|
333
|
+
sys.exit()
|
334
|
+
if error:
|
335
|
+
print(f"ERROR: {error.message}")
|
336
|
+
sys.exit()
|
337
|
+
if to_json:
|
338
|
+
json_dumps = [x.model_dump_json() for x in items]
|
339
|
+
print(f"[{','.join(json_dumps)}]")
|
340
|
+
sys.exit()
|
341
|
+
|
342
|
+
print("Ad Account ID, Item ID, Is Active, Created At, Item Title")
|
343
|
+
for i in items:
|
344
|
+
print(f"{account_id}, {i.id}, {i.is_active}, {i.created_timestamp}, {i.title}")
|
345
|
+
|
154
346
|
|
155
347
|
class AccountCommand:
|
156
348
|
def __init__(
|
@@ -255,6 +447,21 @@ class AccountCommand:
|
|
255
447
|
return error
|
256
448
|
|
257
449
|
|
450
|
+
def delete_user(
|
451
|
+
self,
|
452
|
+
account_id,
|
453
|
+
user_id,
|
454
|
+
send_email_notification,
|
455
|
+
) -> Optional[Error]:
|
456
|
+
_api_url = f"{self.api_base_url}/ad-accounts/{account_id}/users/{user_id}?reason=UserDeleted"
|
457
|
+
if not send_email_notification:
|
458
|
+
_api_url += "&bypass_notification=true"
|
459
|
+
|
460
|
+
_, error, _ = api_request('DELETE', False, _api_url, self.headers)
|
461
|
+
|
462
|
+
return error
|
463
|
+
|
464
|
+
|
258
465
|
def invite_user(
|
259
466
|
self,
|
260
467
|
account_id,
|
@@ -285,6 +492,50 @@ class AccountCommand:
|
|
285
492
|
ret = UserWrapper(**json_obj).user
|
286
493
|
return None, None, ret
|
287
494
|
|
495
|
+
def activate_account(
|
496
|
+
self,
|
497
|
+
account: Account,
|
498
|
+
) -> Optional[Error]:
|
499
|
+
account.state_info.state = "ACTIVE"
|
500
|
+
account.state_info.state_case = "ACTIVATED"
|
501
|
+
|
502
|
+
_api_url = f"{self.api_base_url}/ad-accounts/{account.id}"
|
503
|
+
_payload = {
|
504
|
+
"ad_account": account.model_dump_json()
|
505
|
+
}
|
506
|
+
_, error, _ = api_request('POST', False, _api_url, self.headers, _payload)
|
507
|
+
if error:
|
508
|
+
return error
|
509
|
+
|
510
|
+
_api_url = f"{self.api_base_url}/ad_accounts/{account.id}/state-info"
|
511
|
+
_payload = account.state_info.model_dump_json()
|
512
|
+
_, error, _ = api_request('POST', False, _api_url, self.headers, _payload)
|
513
|
+
if error:
|
514
|
+
return error
|
515
|
+
|
516
|
+
return None
|
517
|
+
|
518
|
+
|
519
|
+
|
520
|
+
def activate_account_with_retry(
|
521
|
+
self,
|
522
|
+
account: Account,
|
523
|
+
) -> Optional[Error]:
|
524
|
+
retries = 0
|
525
|
+
delay = 1
|
526
|
+
max_retries = 3
|
527
|
+
while retries < max_retries:
|
528
|
+
error = self.activate_account(account)
|
529
|
+
if error and error.code == 16:
|
530
|
+
print(f"\nERROR: authentication token expired. Retrying...", file=sys.stderr, flush=True)
|
531
|
+
self.refresh_token()
|
532
|
+
retries += 1
|
533
|
+
time.sleep(delay)
|
534
|
+
continue
|
535
|
+
return error
|
536
|
+
return Error(code=16, message="Failed to regain an authentication token")
|
537
|
+
|
538
|
+
|
288
539
|
def create_account(
|
289
540
|
self,
|
290
541
|
account_id,
|
@@ -420,6 +671,88 @@ class AccountCommand:
|
|
420
671
|
)
|
421
672
|
|
422
673
|
|
674
|
+
def list_account_items(
|
675
|
+
self,
|
676
|
+
account_id,
|
677
|
+
to_curl=False
|
678
|
+
) -> tuple[
|
679
|
+
Optional[CurlString],
|
680
|
+
Optional[Error],
|
681
|
+
list[Item]
|
682
|
+
]:
|
683
|
+
_api_url = f"{self.api_base_url}/ad-accounts/{account_id}/items"
|
684
|
+
_payload = {
|
685
|
+
"ad_account_id": account_id,
|
686
|
+
"search_keyword":[],
|
687
|
+
"order_by": [{
|
688
|
+
"column": "ID",
|
689
|
+
"direction": "ASC"
|
690
|
+
}],
|
691
|
+
"filter": [
|
692
|
+
{
|
693
|
+
"column": "IS_ACTIVE",
|
694
|
+
"filter_operator": "EQ",
|
695
|
+
"value": "true or false",
|
696
|
+
}
|
697
|
+
],
|
698
|
+
"page_index": 1,
|
699
|
+
"page_size": MAX_NUM_ITEMS_PER_PAGE,
|
700
|
+
}
|
701
|
+
|
702
|
+
#
|
703
|
+
# Get active items
|
704
|
+
#
|
705
|
+
curl, error, active_items = self.list_account_items_(to_curl, _api_url, self.headers, _payload, True)
|
706
|
+
if curl:
|
707
|
+
return curl, None, []
|
708
|
+
if error:
|
709
|
+
return None, error, []
|
710
|
+
#
|
711
|
+
# Get inactive items
|
712
|
+
#
|
713
|
+
_, error, inactive_items = self.list_account_items_(to_curl, _api_url, self.headers, _payload, False)
|
714
|
+
if error:
|
715
|
+
return None, error, []
|
716
|
+
|
717
|
+
return None, None, active_items + inactive_items
|
718
|
+
|
719
|
+
|
720
|
+
def list_account_items_(
|
721
|
+
self,
|
722
|
+
to_curl,
|
723
|
+
_api_url,
|
724
|
+
_headers,
|
725
|
+
_payload,
|
726
|
+
_is_active
|
727
|
+
) -> tuple[
|
728
|
+
Optional[CurlString],
|
729
|
+
Optional[Error],
|
730
|
+
list[Item]
|
731
|
+
]:
|
732
|
+
items = []
|
733
|
+
num_items = 0
|
734
|
+
page_index = 1
|
735
|
+
while True:
|
736
|
+
_payload["page_index"] = page_index
|
737
|
+
_payload["filter"][0]["value"] = "true" if _is_active else "false"
|
738
|
+
|
739
|
+
curl, error, json_obj = api_request('POST', to_curl, _api_url, _headers, _payload)
|
740
|
+
if curl:
|
741
|
+
return curl, None, []
|
742
|
+
if error:
|
743
|
+
return None, error, []
|
744
|
+
|
745
|
+
item_group = ItemList(**json_obj)
|
746
|
+
items += item_group.rows
|
747
|
+
num_items += len(item_group.rows)
|
748
|
+
|
749
|
+
if num_items >= item_group.num_counts:
|
750
|
+
break
|
751
|
+
page_index += 1
|
752
|
+
|
753
|
+
return None, None, items
|
754
|
+
|
755
|
+
|
423
756
|
|
424
757
|
#
|
425
758
|
# Helper functions
|
mcmcli/data/item.py
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
# Copyright 2023 Moloco, Inc
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# https://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
from pydantic import BaseModel
|
16
|
+
from typing import Optional
|
17
|
+
|
18
|
+
#
|
19
|
+
# API response dataclasses
|
20
|
+
#
|
21
|
+
class Price(BaseModel):
|
22
|
+
currency: str
|
23
|
+
amount: float
|
24
|
+
|
25
|
+
class Item(BaseModel):
|
26
|
+
id: str
|
27
|
+
title: str
|
28
|
+
price: Price
|
29
|
+
sale_price: Price
|
30
|
+
link: str
|
31
|
+
image_link: str
|
32
|
+
category: str
|
33
|
+
review_count: str
|
34
|
+
rating_score: float
|
35
|
+
is_active: bool
|
36
|
+
is_new: Optional[bool]
|
37
|
+
created_timestamp: str
|
38
|
+
|
39
|
+
class ItemList(BaseModel):
|
40
|
+
rows: list[Item]
|
41
|
+
num_counts: int
|
42
|
+
created_timestamp_filter: str
|
mcmcli/requests.py
CHANGED
@@ -41,6 +41,15 @@ def get(url, headers):
|
|
41
41
|
except Exception as e:
|
42
42
|
return e, None
|
43
43
|
|
44
|
+
|
45
|
+
def delete(url, headers):
|
46
|
+
try:
|
47
|
+
res = requests.delete(url, headers=headers)
|
48
|
+
return None, json.loads(res.text)
|
49
|
+
except Exception as e:
|
50
|
+
return e, None
|
51
|
+
|
52
|
+
|
44
53
|
def post(url, headers, payload):
|
45
54
|
try:
|
46
55
|
res = requests.post(url, headers=headers, json=payload)
|
@@ -62,6 +71,8 @@ def api_request(method, to_curl, url, headers, payload=None) -> tuple[CurlString
|
|
62
71
|
|
63
72
|
if method == 'GET':
|
64
73
|
error, json_obj = get(url, headers)
|
74
|
+
elif method == 'DELETE':
|
75
|
+
error, json_obj = delete(url, headers)
|
65
76
|
elif method == 'POST':
|
66
77
|
error, json_obj = post(url, headers, payload)
|
67
78
|
elif method == 'PUT':
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|