upload-post 2.4.0__tar.gz → 2.5.0__tar.gz

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: upload-post
3
- Version: 2.4.0
3
+ Version: 2.5.0
4
4
  Summary: Cross-platform social media upload for TikTok, Instagram, YouTube, LinkedIn, Facebook, Pinterest, Threads, Reddit, Bluesky, Discord, Telegram, and X (Twitter)
5
5
  Home-page: https://www.upload-post.com/
6
6
  Author: Upload-Post
@@ -5,7 +5,7 @@ with open("README.md", "r", encoding="utf-8") as fh:
5
5
 
6
6
  setup(
7
7
  name="upload-post",
8
- version="2.4.0",
8
+ version="2.5.0",
9
9
  author="Upload-Post",
10
10
  author_email="hi@img2html.com",
11
11
  description="Cross-platform social media upload for TikTok, Instagram, YouTube, LinkedIn, Facebook, Pinterest, Threads, Reddit, Bluesky, Discord, Telegram, and X (Twitter)",
@@ -15,7 +15,7 @@ Example:
15
15
  ... )
16
16
  """
17
17
 
18
- __version__ = "2.4.0"
18
+ __version__ = "2.5.0"
19
19
 
20
20
  from .api_client import UploadPostClient, UploadPostError
21
21
 
@@ -904,6 +904,53 @@ class UploadPostClient:
904
904
  """
905
905
  return self._request("/uploadposts/history", "GET", params={"page": page, "limit": limit})
906
906
 
907
+ def retry_post(
908
+ self,
909
+ request_id: Optional[str] = None,
910
+ job_id: Optional[str] = None
911
+ ) -> Dict:
912
+ """
913
+ Retry a failed post.
914
+
915
+ Args:
916
+ request_id: Request ID of the post to retry.
917
+ job_id: Job ID of the post to retry.
918
+
919
+ One of request_id or job_id is required.
920
+
921
+ Returns:
922
+ Retry result.
923
+ """
924
+ json_data = {}
925
+ if request_id is not None:
926
+ json_data["request_id"] = request_id
927
+ if job_id is not None:
928
+ json_data["job_id"] = job_id
929
+ return self._request("/uploadposts/posts/retry", "POST", json_data=json_data)
930
+
931
+ def unpublish_post(
932
+ self,
933
+ user: str,
934
+ platform: str,
935
+ post_id: str
936
+ ) -> Dict:
937
+ """
938
+ Unpublish (delete) a previously published post.
939
+
940
+ Args:
941
+ user: Profile username.
942
+ platform: Platform name (facebook, youtube, x, linkedin, threads).
943
+ post_id: ID of the published post to unpublish.
944
+
945
+ Returns:
946
+ Unpublish result.
947
+ """
948
+ return self._request("/uploadposts/posts/unpublish", "POST", json_data={
949
+ "user": user,
950
+ "platform": platform,
951
+ "post_id": post_id
952
+ })
953
+
907
954
  def get_analytics(self, profile_username: str, platforms: Optional[List[str]] = None,
908
955
  page_id: Optional[str] = None, page_urn: Optional[str] = None) -> Dict:
909
956
  """
@@ -913,7 +960,10 @@ class UploadPostClient:
913
960
  profile_username: Profile username.
914
961
  platforms: Filter by platforms (instagram, linkedin, facebook, x, youtube, tiktok, threads, pinterest, reddit).
915
962
  page_id: Facebook Page ID (required for Facebook analytics).
916
- page_urn: LinkedIn page URN (defaults to "me" for personal profile).
963
+ page_urn: LinkedIn organization/company page URN or numeric ID. LinkedIn
964
+ analytics are only available for pages you administer; personal profiles
965
+ are not supported (LinkedIn's API exposes no member-level analytics). If
966
+ omitted, the first administered organization page is used.
917
967
 
918
968
  Returns:
919
969
  Analytics data per platform. For Instagram, the response includes both
@@ -1291,32 +1341,43 @@ class UploadPostClient:
1291
1341
  def get_post_comments(
1292
1342
  self,
1293
1343
  user: str,
1344
+ platform: str = "instagram",
1294
1345
  post_id: Optional[str] = None,
1295
- post_url: Optional[str] = None
1346
+ post_url: Optional[str] = None,
1347
+ limit: Optional[int] = None,
1348
+ after: Optional[str] = None
1296
1349
  ) -> Dict:
1297
1350
  """
1298
- Get comments on an Instagram post.
1351
+ Get comments on a post.
1299
1352
 
1300
1353
  Args:
1301
1354
  user: Profile username.
1302
- post_id: Numeric media ID (provide post_id or post_url).
1303
- post_url: Full Instagram post URL (provide post_id or post_url).
1355
+ platform: Platform name (instagram, facebook, youtube, linkedin).
1356
+ post_id: Post/media ID (provide post_id or post_url).
1357
+ post_url: Full post URL (provide post_id or post_url).
1358
+ limit: Maximum number of comments to return.
1359
+ after: Pagination cursor for the next page of comments.
1304
1360
 
1305
1361
  Returns:
1306
1362
  Comments data including comment IDs, text, timestamps, and user info.
1307
1363
  """
1308
- params = {"platform": "instagram", "user": user}
1364
+ params = {"platform": platform, "user": user}
1309
1365
  if post_id:
1310
1366
  params["post_id"] = post_id
1311
1367
  if post_url:
1312
1368
  params["post_url"] = post_url
1369
+ if limit is not None:
1370
+ params["limit"] = limit
1371
+ if after is not None:
1372
+ params["after"] = after
1313
1373
  return self._request("/uploadposts/comments", "GET", params=params)
1314
1374
 
1315
1375
  def reply_to_comment(
1316
1376
  self,
1317
1377
  user: str,
1318
1378
  comment_id: str,
1319
- message: str
1379
+ message: str,
1380
+ buttons: Optional[List[Dict]] = None
1320
1381
  ) -> Dict:
1321
1382
  """
1322
1383
  Send a private reply (DM) to the author of an Instagram comment.
@@ -1325,16 +1386,21 @@ class UploadPostClient:
1325
1386
  user: Profile username.
1326
1387
  comment_id: Comment ID from get_post_comments.
1327
1388
  message: Reply message text.
1389
+ buttons: Optional list of web_url buttons (max 3) rendered in the Instagram
1390
+ DM. Each item is a dict like {"title": "Open", "url": "https://..."}.
1328
1391
 
1329
1392
  Returns:
1330
1393
  Reply result with recipient_id and message_id.
1331
1394
  """
1332
- return self._request("/uploadposts/comments/reply", "POST", json_data={
1395
+ json_data = {
1333
1396
  "platform": "instagram",
1334
1397
  "user": user,
1335
1398
  "comment_id": comment_id,
1336
1399
  "message": message
1337
- })
1400
+ }
1401
+ if buttons is not None:
1402
+ json_data["buttons"] = buttons
1403
+ return self._request("/uploadposts/comments/reply", "POST", json_data=json_data)
1338
1404
 
1339
1405
  def public_reply_to_comment(
1340
1406
  self,
@@ -1360,6 +1426,72 @@ class UploadPostClient:
1360
1426
  "message": message
1361
1427
  })
1362
1428
 
1429
+ def create_comment(
1430
+ self,
1431
+ user: str,
1432
+ platform: str,
1433
+ message: str,
1434
+ post_id: Optional[str] = None,
1435
+ post_url: Optional[str] = None,
1436
+ comment_id: Optional[str] = None
1437
+ ) -> Dict:
1438
+ """
1439
+ Create a comment on a post, or reply to an existing comment.
1440
+
1441
+ Args:
1442
+ user: Profile username.
1443
+ platform: Platform name (instagram, facebook, youtube, linkedin).
1444
+ message: Comment text.
1445
+ post_id: Post/media ID to comment on.
1446
+ post_url: Full post URL to comment on.
1447
+ comment_id: Existing comment ID to reply to.
1448
+
1449
+ One of post_id, post_url or comment_id is required.
1450
+
1451
+ Returns:
1452
+ Creation result with the new comment ID.
1453
+ """
1454
+ json_data = {
1455
+ "platform": platform,
1456
+ "user": user,
1457
+ "message": message
1458
+ }
1459
+ if post_id is not None:
1460
+ json_data["post_id"] = post_id
1461
+ if post_url is not None:
1462
+ json_data["post_url"] = post_url
1463
+ if comment_id is not None:
1464
+ json_data["comment_id"] = comment_id
1465
+ return self._request("/uploadposts/comments/create", "POST", json_data=json_data)
1466
+
1467
+ def delete_comment(
1468
+ self,
1469
+ user: str,
1470
+ platform: str,
1471
+ comment_id: str,
1472
+ post_id: Optional[str] = None
1473
+ ) -> Dict:
1474
+ """
1475
+ Delete a comment on a post.
1476
+
1477
+ Args:
1478
+ user: Profile username.
1479
+ platform: Platform name (instagram, facebook, youtube, linkedin).
1480
+ comment_id: Comment ID to delete.
1481
+ post_id: Post URN (required for LinkedIn).
1482
+
1483
+ Returns:
1484
+ Deletion result.
1485
+ """
1486
+ json_data = {
1487
+ "platform": platform,
1488
+ "user": user,
1489
+ "comment_id": comment_id
1490
+ }
1491
+ if post_id is not None:
1492
+ json_data["post_id"] = post_id
1493
+ return self._request("/uploadposts/comments/delete", "DELETE", json_data=json_data)
1494
+
1363
1495
  # ==================== Google Business ====================
1364
1496
 
1365
1497
  def get_google_business_locations(self, profile: Optional[str] = None) -> Dict:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: upload-post
3
- Version: 2.4.0
3
+ Version: 2.5.0
4
4
  Summary: Cross-platform social media upload for TikTok, Instagram, YouTube, LinkedIn, Facebook, Pinterest, Threads, Reddit, Bluesky, Discord, Telegram, and X (Twitter)
5
5
  Home-page: https://www.upload-post.com/
6
6
  Author: Upload-Post
File without changes
File without changes