marqetive-lib 0.2.2__py3-none-any.whl → 0.2.3__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.
@@ -612,6 +612,20 @@ class LinkedInClient(SocialMediaPlatform):
612
612
  raw_data=response.data,
613
613
  )
614
614
 
615
+ except httpx.HTTPStatusError as e:
616
+ # Extract error details from LinkedIn's response body
617
+ error_details = ""
618
+ try:
619
+ error_body = e.response.json()
620
+ error_details = f" | Details: {error_body}"
621
+ except Exception:
622
+ if e.response.text:
623
+ error_details = f" | Response: {e.response.text[:500]}"
624
+
625
+ raise PlatformError(
626
+ f"Failed to create LinkedIn post: {e}{error_details}",
627
+ platform=self.platform_name,
628
+ ) from e
615
629
  except httpx.HTTPError as e:
616
630
  raise PlatformError(
617
631
  f"Failed to create LinkedIn post: {e}",
@@ -1,6 +1,7 @@
1
1
  """Twitter/X platform integration."""
2
2
 
3
3
  from marqetive.platforms.twitter.client import TwitterClient
4
+ from marqetive.platforms.twitter.exceptions import TwitterUnauthorizedError
4
5
  from marqetive.platforms.twitter.models import (
5
6
  TwitterDMRequest,
6
7
  TwitterGroupDMRequest,
@@ -12,4 +13,5 @@ __all__ = [
12
13
  "TwitterPostRequest",
13
14
  "TwitterDMRequest",
14
15
  "TwitterGroupDMRequest",
16
+ "TwitterUnauthorizedError",
15
17
  ]
@@ -40,6 +40,7 @@ from marqetive.core.models import (
40
40
  PostUpdateRequest,
41
41
  ProgressStatus,
42
42
  )
43
+ from marqetive.platforms.twitter.exceptions import TwitterUnauthorizedError
43
44
  from marqetive.platforms.twitter.media import MediaCategory, TwitterMediaManager
44
45
  from marqetive.platforms.twitter.models import TwitterDMRequest, TwitterPostRequest
45
46
 
@@ -312,6 +313,11 @@ class TwitterClient(SocialMediaPlatform):
312
313
  platform=self.platform_name,
313
314
  status_code=429,
314
315
  ) from e
316
+ if "401" in str(e):
317
+ raise TwitterUnauthorizedError(
318
+ "Unauthorized: Invalid or expired access token",
319
+ error_code=89,
320
+ ) from e
315
321
  raise PlatformError(
316
322
  f"Failed to create tweet: {e}",
317
323
  platform=self.platform_name,
@@ -362,6 +368,11 @@ class TwitterClient(SocialMediaPlatform):
362
368
  status_code=404,
363
369
  ) from e
364
370
  except tweepy.TweepyException as e:
371
+ if "401" in str(e):
372
+ raise TwitterUnauthorizedError(
373
+ "Unauthorized: Invalid or expired access token",
374
+ error_code=89,
375
+ ) from e
365
376
  raise PlatformError(
366
377
  f"Failed to fetch tweet: {e}",
367
378
  platform=self.platform_name,
@@ -415,6 +426,11 @@ class TwitterClient(SocialMediaPlatform):
415
426
  status_code=404,
416
427
  ) from e
417
428
  except tweepy.TweepyException as e:
429
+ if "401" in str(e):
430
+ raise TwitterUnauthorizedError(
431
+ "Unauthorized: Invalid or expired access token",
432
+ error_code=89,
433
+ ) from e
418
434
  raise PlatformError(
419
435
  f"Failed to delete tweet: {e}",
420
436
  platform=self.platform_name,
@@ -458,6 +474,16 @@ class TwitterClient(SocialMediaPlatform):
458
474
 
459
475
  return comments
460
476
 
477
+ except httpx.HTTPStatusError as e:
478
+ if e.response.status_code == 401:
479
+ raise TwitterUnauthorizedError(
480
+ "Unauthorized: Invalid or expired access token",
481
+ error_code=89,
482
+ ) from e
483
+ raise PlatformError(
484
+ f"Failed to fetch replies: {e}",
485
+ platform=self.platform_name,
486
+ ) from e
461
487
  except httpx.HTTPError as e:
462
488
  raise PlatformError(
463
489
  f"Failed to fetch replies: {e}",
@@ -515,6 +541,11 @@ class TwitterClient(SocialMediaPlatform):
515
541
  )
516
542
 
517
543
  except tweepy.TweepyException as e:
544
+ if "401" in str(e):
545
+ raise TwitterUnauthorizedError(
546
+ "Unauthorized: Invalid or expired access token",
547
+ error_code=89,
548
+ ) from e
518
549
  raise PlatformError(
519
550
  f"Failed to create reply: {e}",
520
551
  platform=self.platform_name,
@@ -633,6 +664,11 @@ class TwitterClient(SocialMediaPlatform):
633
664
  platform=self.platform_name,
634
665
  status_code=429,
635
666
  ) from e
667
+ if "401" in str(e):
668
+ raise TwitterUnauthorizedError(
669
+ "Unauthorized: Invalid or expired access token",
670
+ error_code=89,
671
+ ) from e
636
672
  raise PlatformError(
637
673
  f"Failed to retweet: {e}",
638
674
  platform=self.platform_name,
@@ -673,6 +709,11 @@ class TwitterClient(SocialMediaPlatform):
673
709
  platform=self.platform_name,
674
710
  status_code=429,
675
711
  ) from e
712
+ if "401" in str(e):
713
+ raise TwitterUnauthorizedError(
714
+ "Unauthorized: Invalid or expired access token",
715
+ error_code=89,
716
+ ) from e
676
717
  raise PlatformError(
677
718
  f"Failed to unretweet: {e}",
678
719
  platform=self.platform_name,
@@ -1108,6 +1149,11 @@ class TwitterClient(SocialMediaPlatform):
1108
1149
  platform=self.platform_name,
1109
1150
  status_code=429,
1110
1151
  ) from e
1152
+ if "401" in str(e):
1153
+ raise TwitterUnauthorizedError(
1154
+ "Unauthorized: Invalid or expired access token",
1155
+ error_code=89,
1156
+ ) from e
1111
1157
  raise PlatformError(
1112
1158
  f"Failed to create group conversation: {e}",
1113
1159
  platform=self.platform_name,
@@ -270,6 +270,41 @@ def get_retry_delay(
270
270
  return 5.0
271
271
 
272
272
 
273
+ class TwitterUnauthorizedError(PlatformAuthError):
274
+ """Raised when Twitter API returns 401 Unauthorized.
275
+
276
+ Common causes:
277
+ - Invalid or expired access token
278
+ - Revoked app permissions
279
+ - Invalid bearer token
280
+
281
+ Attributes:
282
+ error_code: Twitter-specific error code (e.g., 89 for invalid token).
283
+ """
284
+
285
+ def __init__(
286
+ self,
287
+ message: str,
288
+ *,
289
+ status_code: int = 401,
290
+ error_code: int | None = None,
291
+ ) -> None:
292
+ """Initialize Twitter unauthorized error.
293
+
294
+ Args:
295
+ message: Error message.
296
+ status_code: HTTP status code (default 401).
297
+ error_code: Twitter-specific error code.
298
+ """
299
+ super().__init__(
300
+ message,
301
+ platform="twitter",
302
+ status_code=status_code,
303
+ requires_reconnection=True,
304
+ )
305
+ self.error_code = error_code
306
+
307
+
273
308
  class TwitterAPIError(PlatformError):
274
309
  """Twitter API specific error with detailed information.
275
310
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: marqetive-lib
3
- Version: 0.2.2
3
+ Version: 0.2.3
4
4
  Summary: Modern Python utilities for web APIs
5
5
  Keywords: api,utilities,web,http,marqetive
6
6
  Requires-Python: >=3.12
@@ -12,7 +12,7 @@ marqetive/platforms/instagram/exceptions.py,sha256=TcD_pX4eSx_k4yW8DgfA6SGPiAz3V
12
12
  marqetive/platforms/instagram/media.py,sha256=0ZbUbpwJ025_hccL9X8qced_-LJGoL_-NdS84Op97VE,23228
13
13
  marqetive/platforms/instagram/models.py,sha256=20v3m1037y3b_WlsKF8zAOgV23nFu63tfmmUN1CefOI,2769
14
14
  marqetive/platforms/linkedin/__init__.py,sha256=_FrdZpqcXjcUW6C-25zGV7poGih9yzs6y1AFnuizTUQ,1384
15
- marqetive/platforms/linkedin/client.py,sha256=lMHvb5dpDozHDKu6g27tSZPDHgZuQzrNCWZhZIzWmpc,74249
15
+ marqetive/platforms/linkedin/client.py,sha256=-0YiAPv75zwsjuOoCEb7OFFH5gIlaRLd7eHDTWmLg3U,74826
16
16
  marqetive/platforms/linkedin/exceptions.py,sha256=i5fARUkZik46bS3htZBwUInVzetsZx1APpKEXLrCKf0,9762
17
17
  marqetive/platforms/linkedin/media.py,sha256=-kpkL5brYhx8cZlFS5ueDgY4eSZWqHoB6xp8jZU2cyI,25931
18
18
  marqetive/platforms/linkedin/models.py,sha256=n7DqwVxYSbGYBmeEJ1woCZ6XhUIHcLx8Gpm8uCBACzI,12620
@@ -21,9 +21,9 @@ marqetive/platforms/tiktok/client.py,sha256=IhLCphzu_qxTSP6CDFqLBQqM3zJ7bLy7uHDS
21
21
  marqetive/platforms/tiktok/exceptions.py,sha256=vxwyAKujMGZJh0LetG1QsLF95QfUs_kR6ujsWSHGqL0,10124
22
22
  marqetive/platforms/tiktok/media.py,sha256=NmvzvzfaZMmzIx88wkXI5tWLd4vYN1VJXN-IkaEAO2c,28638
23
23
  marqetive/platforms/tiktok/models.py,sha256=WWdjuFqhTIR8SnHkz-8UaNc5Mm2PrGomwQ3W7pJcQFg,2962
24
- marqetive/platforms/twitter/__init__.py,sha256=0-EETW3kIAw7kFo-JuOivS42BDVdNJfqHe2depIbx2U,339
25
- marqetive/platforms/twitter/client.py,sha256=BCVPz-wIKJx1FThm-dI9QfTVG9VdYLYBPOWJEzX8QJc,42417
26
- marqetive/platforms/twitter/exceptions.py,sha256=eZ-dJKOXH_-bAMg29zWKbEqMFud29piEJ5IWfC9wFts,8926
24
+ marqetive/platforms/twitter/__init__.py,sha256=etiNzWd0EznrDbFTlc71dc_Cm-aqAM7RIwpj8qrYEiE,447
25
+ marqetive/platforms/twitter/client.py,sha256=u9eKm4NOO8NpzdfpwzxBYJ8zn6OXbMTIa4Zv9xhvPdQ,44370
26
+ marqetive/platforms/twitter/exceptions.py,sha256=AvXzucqF2P6F3-lynayt461oj9e1luCh2-El5pXqZL4,9832
27
27
  marqetive/platforms/twitter/media.py,sha256=KpPxnLCas8NhnsEvaXSJZ7To4wW4FY0YqQvUkJIIr7g,28010
28
28
  marqetive/platforms/twitter/models.py,sha256=afFK1jJyrIC6BvY6ShkHlg-KnvawdeLGS-hB-GoloWA,4579
29
29
  marqetive/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -33,6 +33,6 @@ marqetive/utils/helpers.py,sha256=Sh5HZD6AOJig_6T84n6JsKLosIkKIkpkiYTl69rnOOw,13
33
33
  marqetive/utils/media.py,sha256=reVousdueG-h5jeI6uLGqVCfjYxlsMiWhx6XZwg-iHY,14664
34
34
  marqetive/utils/oauth.py,sha256=3TtbUCVuGxtOBxIUvVJH_DUMIHrP76XDpabPYaLXhTU,15392
35
35
  marqetive/utils/retry.py,sha256=UcgrmVBVG5zd30_11mZnRnTaSFrbUYXBO1DrXPR0f8E,7627
36
- marqetive_lib-0.2.2.dist-info/METADATA,sha256=fVQO0Nibz4TvbzU_K_WuUo6SmwbJ2V7lsVWN75CQEVE,7875
37
- marqetive_lib-0.2.2.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
38
- marqetive_lib-0.2.2.dist-info/RECORD,,
36
+ marqetive_lib-0.2.3.dist-info/METADATA,sha256=T0UBSJTAxAmzhrSsGFzzymlLrqZMTnzYhaOnJkhldy0,7875
37
+ marqetive_lib-0.2.3.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
38
+ marqetive_lib-0.2.3.dist-info/RECORD,,