marqetive-lib 0.1.22__tar.gz → 0.2.2__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.
- {marqetive_lib-0.1.22 → marqetive_lib-0.2.2}/PKG-INFO +1 -1
- {marqetive_lib-0.1.22 → marqetive_lib-0.2.2}/pyproject.toml +1 -1
- {marqetive_lib-0.1.22 → marqetive_lib-0.2.2}/src/marqetive/__init__.py +3 -1
- {marqetive_lib-0.1.22 → marqetive_lib-0.2.2}/src/marqetive/core/base.py +4 -0
- {marqetive_lib-0.1.22 → marqetive_lib-0.2.2}/src/marqetive/core/exceptions.py +46 -0
- {marqetive_lib-0.1.22 → marqetive_lib-0.2.2}/src/marqetive/platforms/twitter/client.py +14 -0
- {marqetive_lib-0.1.22 → marqetive_lib-0.2.2}/README.md +0 -0
- {marqetive_lib-0.1.22 → marqetive_lib-0.2.2}/src/marqetive/core/__init__.py +0 -0
- {marqetive_lib-0.1.22 → marqetive_lib-0.2.2}/src/marqetive/core/client.py +0 -0
- {marqetive_lib-0.1.22 → marqetive_lib-0.2.2}/src/marqetive/core/models.py +0 -0
- {marqetive_lib-0.1.22 → marqetive_lib-0.2.2}/src/marqetive/factory.py +0 -0
- {marqetive_lib-0.1.22 → marqetive_lib-0.2.2}/src/marqetive/platforms/__init__.py +0 -0
- {marqetive_lib-0.1.22 → marqetive_lib-0.2.2}/src/marqetive/platforms/instagram/__init__.py +0 -0
- {marqetive_lib-0.1.22 → marqetive_lib-0.2.2}/src/marqetive/platforms/instagram/client.py +0 -0
- {marqetive_lib-0.1.22 → marqetive_lib-0.2.2}/src/marqetive/platforms/instagram/exceptions.py +0 -0
- {marqetive_lib-0.1.22 → marqetive_lib-0.2.2}/src/marqetive/platforms/instagram/media.py +0 -0
- {marqetive_lib-0.1.22 → marqetive_lib-0.2.2}/src/marqetive/platforms/instagram/models.py +0 -0
- {marqetive_lib-0.1.22 → marqetive_lib-0.2.2}/src/marqetive/platforms/linkedin/__init__.py +0 -0
- {marqetive_lib-0.1.22 → marqetive_lib-0.2.2}/src/marqetive/platforms/linkedin/client.py +0 -0
- {marqetive_lib-0.1.22 → marqetive_lib-0.2.2}/src/marqetive/platforms/linkedin/exceptions.py +0 -0
- {marqetive_lib-0.1.22 → marqetive_lib-0.2.2}/src/marqetive/platforms/linkedin/media.py +0 -0
- {marqetive_lib-0.1.22 → marqetive_lib-0.2.2}/src/marqetive/platforms/linkedin/models.py +0 -0
- {marqetive_lib-0.1.22 → marqetive_lib-0.2.2}/src/marqetive/platforms/tiktok/__init__.py +0 -0
- {marqetive_lib-0.1.22 → marqetive_lib-0.2.2}/src/marqetive/platforms/tiktok/client.py +0 -0
- {marqetive_lib-0.1.22 → marqetive_lib-0.2.2}/src/marqetive/platforms/tiktok/exceptions.py +0 -0
- {marqetive_lib-0.1.22 → marqetive_lib-0.2.2}/src/marqetive/platforms/tiktok/media.py +0 -0
- {marqetive_lib-0.1.22 → marqetive_lib-0.2.2}/src/marqetive/platforms/tiktok/models.py +0 -0
- {marqetive_lib-0.1.22 → marqetive_lib-0.2.2}/src/marqetive/platforms/twitter/__init__.py +0 -0
- {marqetive_lib-0.1.22 → marqetive_lib-0.2.2}/src/marqetive/platforms/twitter/exceptions.py +0 -0
- {marqetive_lib-0.1.22 → marqetive_lib-0.2.2}/src/marqetive/platforms/twitter/media.py +0 -0
- {marqetive_lib-0.1.22 → marqetive_lib-0.2.2}/src/marqetive/platforms/twitter/models.py +0 -0
- {marqetive_lib-0.1.22 → marqetive_lib-0.2.2}/src/marqetive/py.typed +0 -0
- {marqetive_lib-0.1.22 → marqetive_lib-0.2.2}/src/marqetive/utils/__init__.py +0 -0
- {marqetive_lib-0.1.22 → marqetive_lib-0.2.2}/src/marqetive/utils/file_handlers.py +0 -0
- {marqetive_lib-0.1.22 → marqetive_lib-0.2.2}/src/marqetive/utils/helpers.py +0 -0
- {marqetive_lib-0.1.22 → marqetive_lib-0.2.2}/src/marqetive/utils/media.py +0 -0
- {marqetive_lib-0.1.22 → marqetive_lib-0.2.2}/src/marqetive/utils/oauth.py +0 -0
- {marqetive_lib-0.1.22 → marqetive_lib-0.2.2}/src/marqetive/utils/retry.py +0 -0
|
@@ -47,6 +47,7 @@ from marqetive.core.exceptions import (
|
|
|
47
47
|
PlatformError,
|
|
48
48
|
PostNotFoundError,
|
|
49
49
|
RateLimitError,
|
|
50
|
+
ThreadCancelledException,
|
|
50
51
|
ValidationError,
|
|
51
52
|
)
|
|
52
53
|
|
|
@@ -79,7 +80,7 @@ from marqetive.utils.helpers import format_response
|
|
|
79
80
|
# Retry utilities
|
|
80
81
|
from marqetive.utils.retry import STANDARD_BACKOFF, BackoffConfig, retry_async
|
|
81
82
|
|
|
82
|
-
__version__ = "0.2.
|
|
83
|
+
__version__ = "0.2.2"
|
|
83
84
|
|
|
84
85
|
__all__ = [
|
|
85
86
|
# Core
|
|
@@ -119,6 +120,7 @@ __all__ = [
|
|
|
119
120
|
"MediaUploadError",
|
|
120
121
|
"ValidationError",
|
|
121
122
|
"InvalidFileTypeError",
|
|
123
|
+
"ThreadCancelledException",
|
|
122
124
|
# Types
|
|
123
125
|
"ProgressCallback",
|
|
124
126
|
# Utilities
|
|
@@ -389,6 +389,7 @@ class SocialMediaPlatform(ABC):
|
|
|
389
389
|
async def create_thread(
|
|
390
390
|
self,
|
|
391
391
|
posts: list[PostCreateRequest],
|
|
392
|
+
cancellation_check: Callable[[], Awaitable[bool]] | None = None,
|
|
392
393
|
) -> list[Post]:
|
|
393
394
|
"""Create a thread of connected posts.
|
|
394
395
|
|
|
@@ -400,6 +401,8 @@ class SocialMediaPlatform(ABC):
|
|
|
400
401
|
posts: List of post requests to create as a thread.
|
|
401
402
|
Each post can have its own content, media, etc.
|
|
402
403
|
First post is the head of the thread.
|
|
404
|
+
cancellation_check: Optional async callback that returns True if the
|
|
405
|
+
thread creation should be cancelled. Called before each post.
|
|
403
406
|
|
|
404
407
|
Returns:
|
|
405
408
|
List of Post objects for each post in the thread.
|
|
@@ -408,6 +411,7 @@ class SocialMediaPlatform(ABC):
|
|
|
408
411
|
NotImplementedError: If platform doesn't support threads.
|
|
409
412
|
ValidationError: If posts list is empty.
|
|
410
413
|
PlatformAuthError: If not authenticated.
|
|
414
|
+
ThreadCancelledException: If cancelled mid-thread (includes posted items).
|
|
411
415
|
|
|
412
416
|
Example:
|
|
413
417
|
>>> # Twitter thread example
|
|
@@ -4,6 +4,13 @@ This module defines platform-specific exceptions for handling errors
|
|
|
4
4
|
that may occur during API interactions with various social media platforms.
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from typing import TYPE_CHECKING
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from marqetive.core.models import Post
|
|
13
|
+
|
|
7
14
|
|
|
8
15
|
class PlatformError(Exception):
|
|
9
16
|
"""Base exception for all platform-related errors.
|
|
@@ -266,3 +273,42 @@ class InvalidFileTypeError(PlatformError):
|
|
|
266
273
|
if self.file_type:
|
|
267
274
|
return f"{base_message} | File type: {self.file_type}"
|
|
268
275
|
return base_message
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
class ThreadCancelledException(PlatformError):
|
|
279
|
+
"""Raised when a thread is cancelled mid-posting.
|
|
280
|
+
|
|
281
|
+
This exception is raised when:
|
|
282
|
+
- A cancellation callback returns True during thread creation
|
|
283
|
+
- Thread posting is interrupted before completion
|
|
284
|
+
|
|
285
|
+
The exception includes the list of posts that were successfully
|
|
286
|
+
created before cancellation, allowing the caller to handle rollback.
|
|
287
|
+
|
|
288
|
+
Args:
|
|
289
|
+
message: Human-readable error message
|
|
290
|
+
platform: Name of the platform where cancellation occurred
|
|
291
|
+
posted_tweets: List of Post objects that were created before cancellation
|
|
292
|
+
|
|
293
|
+
Example:
|
|
294
|
+
>>> try:
|
|
295
|
+
... await client.create_thread(tweets, cancellation_check=check_cancel)
|
|
296
|
+
... except ThreadCancelledException as e:
|
|
297
|
+
... for post in e.posted_tweets:
|
|
298
|
+
... await client.delete_post(post.post_id)
|
|
299
|
+
"""
|
|
300
|
+
|
|
301
|
+
def __init__(
|
|
302
|
+
self,
|
|
303
|
+
message: str,
|
|
304
|
+
platform: str | None = None,
|
|
305
|
+
posted_tweets: list[Post] | None = None,
|
|
306
|
+
) -> None:
|
|
307
|
+
self.posted_tweets = posted_tweets or []
|
|
308
|
+
super().__init__(message, platform)
|
|
309
|
+
|
|
310
|
+
def _format_message(self) -> str:
|
|
311
|
+
"""Format the error message with posted tweet count."""
|
|
312
|
+
base_message = super()._format_message()
|
|
313
|
+
count = len(self.posted_tweets)
|
|
314
|
+
return f"{base_message} | Posted tweets: {count}"
|
|
@@ -6,6 +6,7 @@ ABC for Twitter (X), using the Twitter API v2 via tweepy.
|
|
|
6
6
|
API Documentation: https://developer.x.com/en/docs/twitter-api
|
|
7
7
|
"""
|
|
8
8
|
|
|
9
|
+
from collections.abc import Awaitable, Callable
|
|
9
10
|
from datetime import datetime
|
|
10
11
|
from typing import Any
|
|
11
12
|
|
|
@@ -20,6 +21,7 @@ from marqetive.core.exceptions import (
|
|
|
20
21
|
PlatformError,
|
|
21
22
|
PostNotFoundError,
|
|
22
23
|
RateLimitError,
|
|
24
|
+
ThreadCancelledException,
|
|
23
25
|
ValidationError,
|
|
24
26
|
)
|
|
25
27
|
from marqetive.core.models import (
|
|
@@ -681,6 +683,7 @@ class TwitterClient(SocialMediaPlatform):
|
|
|
681
683
|
async def create_thread(
|
|
682
684
|
self,
|
|
683
685
|
posts: list[PostCreateRequest],
|
|
686
|
+
cancellation_check: Callable[[], Awaitable[bool]] | None = None,
|
|
684
687
|
) -> list[Post]:
|
|
685
688
|
"""Create a Twitter thread (multiple linked tweets).
|
|
686
689
|
|
|
@@ -691,6 +694,8 @@ class TwitterClient(SocialMediaPlatform):
|
|
|
691
694
|
posts: List of PostCreateRequest objects to create as a thread.
|
|
692
695
|
First tweet is the head of the thread.
|
|
693
696
|
Use TwitterPostRequest for Twitter-specific features.
|
|
697
|
+
cancellation_check: Optional async callback that returns True if the
|
|
698
|
+
thread creation should be cancelled. Called before each tweet.
|
|
694
699
|
|
|
695
700
|
Returns:
|
|
696
701
|
List of Post objects for each tweet in the thread.
|
|
@@ -699,6 +704,7 @@ class TwitterClient(SocialMediaPlatform):
|
|
|
699
704
|
ValidationError: If posts list is empty.
|
|
700
705
|
PlatformAuthError: If not authenticated.
|
|
701
706
|
MediaUploadError: If media upload fails.
|
|
707
|
+
ThreadCancelledException: If cancelled mid-thread (includes posted tweets).
|
|
702
708
|
RuntimeError: If client not used as context manager.
|
|
703
709
|
|
|
704
710
|
Example:
|
|
@@ -723,6 +729,14 @@ class TwitterClient(SocialMediaPlatform):
|
|
|
723
729
|
reply_to_id: str | None = None
|
|
724
730
|
|
|
725
731
|
for idx, post_request in enumerate(posts):
|
|
732
|
+
# Check cancellation BEFORE posting each tweet
|
|
733
|
+
if cancellation_check is not None and await cancellation_check():
|
|
734
|
+
raise ThreadCancelledException(
|
|
735
|
+
f"Thread cancelled after {len(created_posts)} of {len(posts)} tweets",
|
|
736
|
+
platform=self.platform_name,
|
|
737
|
+
posted_tweets=created_posts,
|
|
738
|
+
)
|
|
739
|
+
|
|
726
740
|
# Convert to TwitterPostRequest if needed and set reply chain
|
|
727
741
|
if isinstance(post_request, TwitterPostRequest):
|
|
728
742
|
if reply_to_id is not None:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{marqetive_lib-0.1.22 → marqetive_lib-0.2.2}/src/marqetive/platforms/instagram/exceptions.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|