marqetive-lib 0.1.5__tar.gz → 0.1.7__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.7/PKG-INFO +289 -0
- marqetive_lib-0.1.7/README.md +255 -0
- {marqetive_lib-0.1.5 → marqetive_lib-0.1.7}/pyproject.toml +1 -1
- {marqetive_lib-0.1.5 → marqetive_lib-0.1.7}/src/marqetive/__init__.py +13 -7
- {marqetive_lib-0.1.5 → marqetive_lib-0.1.7}/src/marqetive/core/__init__.py +6 -4
- {marqetive_lib-0.1.5 → marqetive_lib-0.1.7}/src/marqetive/core/base.py +92 -13
- {marqetive_lib-0.1.5 → marqetive_lib-0.1.7}/src/marqetive/core/models.py +111 -7
- marqetive_lib-0.1.7/src/marqetive/platforms/instagram/__init__.py +6 -0
- {marqetive_lib-0.1.5 → marqetive_lib-0.1.7}/src/marqetive/platforms/instagram/media.py +79 -13
- marqetive_lib-0.1.7/src/marqetive/platforms/instagram/models.py +74 -0
- marqetive_lib-0.1.7/src/marqetive/platforms/linkedin/__init__.py +54 -0
- marqetive_lib-0.1.7/src/marqetive/platforms/linkedin/client.py +1621 -0
- {marqetive_lib-0.1.5 → marqetive_lib-0.1.7}/src/marqetive/platforms/linkedin/media.py +156 -47
- marqetive_lib-0.1.7/src/marqetive/platforms/linkedin/models.py +413 -0
- marqetive_lib-0.1.7/src/marqetive/platforms/tiktok/__init__.py +6 -0
- {marqetive_lib-0.1.5 → marqetive_lib-0.1.7}/src/marqetive/platforms/tiktok/media.py +112 -51
- marqetive_lib-0.1.7/src/marqetive/platforms/tiktok/models.py +82 -0
- marqetive_lib-0.1.7/src/marqetive/platforms/twitter/__init__.py +6 -0
- {marqetive_lib-0.1.5 → marqetive_lib-0.1.7}/src/marqetive/platforms/twitter/client.py +86 -0
- {marqetive_lib-0.1.5 → marqetive_lib-0.1.7}/src/marqetive/platforms/twitter/media.py +133 -65
- marqetive_lib-0.1.7/src/marqetive/platforms/twitter/models.py +58 -0
- marqetive_lib-0.1.5/PKG-INFO +0 -260
- marqetive_lib-0.1.5/README.md +0 -226
- marqetive_lib-0.1.5/src/marqetive/platforms/instagram/__init__.py +0 -5
- marqetive_lib-0.1.5/src/marqetive/platforms/linkedin/__init__.py +0 -5
- marqetive_lib-0.1.5/src/marqetive/platforms/linkedin/client.py +0 -737
- marqetive_lib-0.1.5/src/marqetive/platforms/tiktok/__init__.py +0 -5
- marqetive_lib-0.1.5/src/marqetive/platforms/twitter/__init__.py +0 -5
- {marqetive_lib-0.1.5 → marqetive_lib-0.1.7}/src/marqetive/core/client.py +0 -0
- {marqetive_lib-0.1.5 → marqetive_lib-0.1.7}/src/marqetive/core/exceptions.py +0 -0
- {marqetive_lib-0.1.5 → marqetive_lib-0.1.7}/src/marqetive/factory.py +0 -0
- {marqetive_lib-0.1.5 → marqetive_lib-0.1.7}/src/marqetive/platforms/__init__.py +0 -0
- {marqetive_lib-0.1.5 → marqetive_lib-0.1.7}/src/marqetive/platforms/instagram/client.py +0 -0
- {marqetive_lib-0.1.5 → marqetive_lib-0.1.7}/src/marqetive/platforms/instagram/exceptions.py +0 -0
- {marqetive_lib-0.1.5 → marqetive_lib-0.1.7}/src/marqetive/platforms/linkedin/exceptions.py +0 -0
- {marqetive_lib-0.1.5 → marqetive_lib-0.1.7}/src/marqetive/platforms/tiktok/client.py +0 -0
- {marqetive_lib-0.1.5 → marqetive_lib-0.1.7}/src/marqetive/platforms/tiktok/exceptions.py +0 -0
- {marqetive_lib-0.1.5 → marqetive_lib-0.1.7}/src/marqetive/platforms/twitter/exceptions.py +0 -0
- {marqetive_lib-0.1.5 → marqetive_lib-0.1.7}/src/marqetive/py.typed +0 -0
- {marqetive_lib-0.1.5 → marqetive_lib-0.1.7}/src/marqetive/utils/__init__.py +0 -0
- {marqetive_lib-0.1.5 → marqetive_lib-0.1.7}/src/marqetive/utils/file_handlers.py +0 -0
- {marqetive_lib-0.1.5 → marqetive_lib-0.1.7}/src/marqetive/utils/helpers.py +0 -0
- {marqetive_lib-0.1.5 → marqetive_lib-0.1.7}/src/marqetive/utils/media.py +0 -0
- {marqetive_lib-0.1.5 → marqetive_lib-0.1.7}/src/marqetive/utils/oauth.py +0 -0
- {marqetive_lib-0.1.5 → marqetive_lib-0.1.7}/src/marqetive/utils/retry.py +0 -0
- {marqetive_lib-0.1.5 → marqetive_lib-0.1.7}/src/marqetive/utils/token_validator.py +0 -0
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: marqetive-lib
|
|
3
|
+
Version: 0.1.7
|
|
4
|
+
Summary: Modern Python utilities for web APIs
|
|
5
|
+
Keywords: api,utilities,web,http,marqetive
|
|
6
|
+
Requires-Python: >=3.12
|
|
7
|
+
Classifier: Development Status :: 3 - Alpha
|
|
8
|
+
Classifier: Intended Audience :: Developers
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
12
|
+
Classifier: Topic :: Internet :: WWW/HTTP
|
|
13
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
14
|
+
Provides-Extra: dev
|
|
15
|
+
Provides-Extra: docs
|
|
16
|
+
Requires-Dist: aiofiles (>=24.0.0)
|
|
17
|
+
Requires-Dist: httpx (>=0.28.1)
|
|
18
|
+
Requires-Dist: mkdocs (>=1.5.0) ; extra == "docs"
|
|
19
|
+
Requires-Dist: mkdocs-material (>=9.5.0) ; extra == "docs"
|
|
20
|
+
Requires-Dist: mkdocstrings[python] (>=0.30.1) ; extra == "docs"
|
|
21
|
+
Requires-Dist: pydantic (>=2.0.0)
|
|
22
|
+
Requires-Dist: pyright (>=1.1.0) ; extra == "dev"
|
|
23
|
+
Requires-Dist: pytest (>=9.0.0) ; extra == "dev"
|
|
24
|
+
Requires-Dist: pytest-asyncio (>=1.3.0) ; extra == "dev"
|
|
25
|
+
Requires-Dist: pytest-cov (>=7.0.0) ; extra == "dev"
|
|
26
|
+
Requires-Dist: ruff (>=0.14.4) ; extra == "dev"
|
|
27
|
+
Requires-Dist: tweepy (>=4.16.0,<5.0.0)
|
|
28
|
+
Project-URL: Documentation, https://marqetive-lib.readthedocs.io
|
|
29
|
+
Project-URL: Homepage, https://github.com/yourusername/marqetive-lib
|
|
30
|
+
Project-URL: Issues, https://github.com/yourusername/marqetive-lib/issues
|
|
31
|
+
Project-URL: Repository, https://github.com/yourusername/marqetive-lib
|
|
32
|
+
Description-Content-Type: text/markdown
|
|
33
|
+
|
|
34
|
+
# MarqetiveLib
|
|
35
|
+
|
|
36
|
+
Modern Python library for social media platform integrations - Simple, type-safe, and async-ready.
|
|
37
|
+
|
|
38
|
+
## Supported Platforms
|
|
39
|
+
|
|
40
|
+
- **Twitter/X** - Post tweets, upload media, manage threads
|
|
41
|
+
- **LinkedIn** - Share updates, upload images and videos
|
|
42
|
+
- **Instagram** - Create posts with media via Graph API
|
|
43
|
+
- **TikTok** - Upload and publish videos
|
|
44
|
+
|
|
45
|
+
## Features
|
|
46
|
+
|
|
47
|
+
- **Unified API**: Single interface for all social media platforms
|
|
48
|
+
- **Async-First**: Built for modern async Python applications
|
|
49
|
+
- **Type-Safe**: Full type hints and Pyright compliance
|
|
50
|
+
- **Auto Token Refresh**: Factory handles OAuth token lifecycle automatically
|
|
51
|
+
- **Media Upload**: Progress tracking for large file uploads
|
|
52
|
+
- **Retry Logic**: Exponential backoff with jitter for transient failures
|
|
53
|
+
- **Well Tested**: Comprehensive test coverage
|
|
54
|
+
|
|
55
|
+
## Installation
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
pip install marqetive
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Or with Poetry:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
poetry add marqetive
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Quick Start
|
|
68
|
+
|
|
69
|
+
```python
|
|
70
|
+
import asyncio
|
|
71
|
+
from marqetive import get_client, AuthCredentials, PostCreateRequest
|
|
72
|
+
|
|
73
|
+
async def main():
|
|
74
|
+
# Create credentials for your platform
|
|
75
|
+
credentials = AuthCredentials(
|
|
76
|
+
platform="twitter",
|
|
77
|
+
access_token="your_access_token",
|
|
78
|
+
refresh_token="your_refresh_token"
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
# Get authenticated client (auto-refreshes token if expired)
|
|
82
|
+
client = await get_client(credentials)
|
|
83
|
+
|
|
84
|
+
# Use client as async context manager
|
|
85
|
+
async with client:
|
|
86
|
+
request = PostCreateRequest(content="Hello from MarqetiveLib!")
|
|
87
|
+
post = await client.create_post(request)
|
|
88
|
+
print(f"Posted! ID: {post.platform_id}")
|
|
89
|
+
|
|
90
|
+
asyncio.run(main())
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Platform Examples
|
|
94
|
+
|
|
95
|
+
### Twitter
|
|
96
|
+
|
|
97
|
+
```python
|
|
98
|
+
from marqetive import get_client, AuthCredentials, PostCreateRequest
|
|
99
|
+
|
|
100
|
+
credentials = AuthCredentials(
|
|
101
|
+
platform="twitter",
|
|
102
|
+
access_token="your_access_token",
|
|
103
|
+
refresh_token="your_refresh_token" # Optional, for token refresh
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
client = await get_client(credentials)
|
|
107
|
+
async with client:
|
|
108
|
+
# Text post
|
|
109
|
+
post = await client.create_post(PostCreateRequest(content="Hello Twitter!"))
|
|
110
|
+
|
|
111
|
+
# Post with media
|
|
112
|
+
post = await client.create_post(PostCreateRequest(
|
|
113
|
+
content="Check out this image!",
|
|
114
|
+
media_paths=["/path/to/image.jpg"]
|
|
115
|
+
))
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### LinkedIn
|
|
119
|
+
|
|
120
|
+
```python
|
|
121
|
+
from marqetive import get_client, AuthCredentials, PostCreateRequest
|
|
122
|
+
|
|
123
|
+
credentials = AuthCredentials(
|
|
124
|
+
platform="linkedin",
|
|
125
|
+
access_token="your_access_token",
|
|
126
|
+
user_id="urn:li:person:your_person_id" # Required for LinkedIn
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
client = await get_client(credentials)
|
|
130
|
+
async with client:
|
|
131
|
+
post = await client.create_post(PostCreateRequest(
|
|
132
|
+
content="Excited to share this update!"
|
|
133
|
+
))
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Instagram
|
|
137
|
+
|
|
138
|
+
```python
|
|
139
|
+
from marqetive import get_client, AuthCredentials, PostCreateRequest
|
|
140
|
+
|
|
141
|
+
credentials = AuthCredentials(
|
|
142
|
+
platform="instagram",
|
|
143
|
+
access_token="your_access_token",
|
|
144
|
+
user_id="your_instagram_business_account_id" # Required
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
client = await get_client(credentials)
|
|
148
|
+
async with client:
|
|
149
|
+
# Instagram requires media for posts
|
|
150
|
+
post = await client.create_post(PostCreateRequest(
|
|
151
|
+
content="Beautiful day! #photography",
|
|
152
|
+
media_paths=["/path/to/photo.jpg"]
|
|
153
|
+
))
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### TikTok
|
|
157
|
+
|
|
158
|
+
```python
|
|
159
|
+
from marqetive import get_client, AuthCredentials, PostCreateRequest
|
|
160
|
+
|
|
161
|
+
credentials = AuthCredentials(
|
|
162
|
+
platform="tiktok",
|
|
163
|
+
access_token="your_access_token",
|
|
164
|
+
additional_data={"open_id": "your_open_id"} # Required for TikTok
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
client = await get_client(credentials)
|
|
168
|
+
async with client:
|
|
169
|
+
post = await client.create_post(PostCreateRequest(
|
|
170
|
+
content="Check out this video!",
|
|
171
|
+
media_paths=["/path/to/video.mp4"]
|
|
172
|
+
))
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
## Using Custom OAuth Credentials
|
|
176
|
+
|
|
177
|
+
```python
|
|
178
|
+
from marqetive import PlatformFactory, AuthCredentials, PostCreateRequest
|
|
179
|
+
|
|
180
|
+
# Create factory with your OAuth app credentials
|
|
181
|
+
factory = PlatformFactory(
|
|
182
|
+
twitter_client_id="your_client_id",
|
|
183
|
+
twitter_client_secret="your_client_secret",
|
|
184
|
+
linkedin_client_id="your_linkedin_client_id",
|
|
185
|
+
linkedin_client_secret="your_linkedin_client_secret"
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
credentials = AuthCredentials(
|
|
189
|
+
platform="twitter",
|
|
190
|
+
access_token="user_access_token",
|
|
191
|
+
refresh_token="user_refresh_token"
|
|
192
|
+
)
|
|
193
|
+
|
|
194
|
+
# Get client with automatic token refresh
|
|
195
|
+
client = await factory.get_client(credentials)
|
|
196
|
+
async with client:
|
|
197
|
+
post = await client.create_post(PostCreateRequest(content="Hello!"))
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## Progress Tracking for Media Uploads
|
|
201
|
+
|
|
202
|
+
```python
|
|
203
|
+
def progress_callback(operation: str, progress: int, total: int, message: str | None):
|
|
204
|
+
percent = (progress / total) * 100 if total > 0 else 0
|
|
205
|
+
print(f"{operation}: {percent:.1f}% - {message or ''}")
|
|
206
|
+
|
|
207
|
+
client = await get_client(credentials, progress_callback=progress_callback)
|
|
208
|
+
async with client:
|
|
209
|
+
post = await client.create_post(PostCreateRequest(
|
|
210
|
+
content="Uploading video...",
|
|
211
|
+
media_paths=["/path/to/large_video.mp4"]
|
|
212
|
+
))
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
## Error Handling
|
|
216
|
+
|
|
217
|
+
```python
|
|
218
|
+
from marqetive import get_client, AuthCredentials, PostCreateRequest
|
|
219
|
+
from marqetive.core.exceptions import (
|
|
220
|
+
PlatformError,
|
|
221
|
+
PlatformAuthError,
|
|
222
|
+
RateLimitError,
|
|
223
|
+
MediaUploadError
|
|
224
|
+
)
|
|
225
|
+
|
|
226
|
+
try:
|
|
227
|
+
client = await get_client(credentials)
|
|
228
|
+
async with client:
|
|
229
|
+
post = await client.create_post(request)
|
|
230
|
+
except PlatformAuthError as e:
|
|
231
|
+
print(f"Authentication failed: {e}")
|
|
232
|
+
# Token may need refresh or reconnection
|
|
233
|
+
except RateLimitError as e:
|
|
234
|
+
print(f"Rate limited. Retry after: {e.retry_after} seconds")
|
|
235
|
+
except MediaUploadError as e:
|
|
236
|
+
print(f"Media upload failed: {e}")
|
|
237
|
+
except PlatformError as e:
|
|
238
|
+
print(f"Platform error: {e}")
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
## Development
|
|
242
|
+
|
|
243
|
+
### Setup Development Environment
|
|
244
|
+
|
|
245
|
+
```bash
|
|
246
|
+
# Clone the repository
|
|
247
|
+
git clone https://github.com/your-org/marqetive-lib.git
|
|
248
|
+
cd marqetive-lib
|
|
249
|
+
|
|
250
|
+
# Install Poetry if you haven't already
|
|
251
|
+
curl -sSL https://install.python-poetry.org | python3 -
|
|
252
|
+
|
|
253
|
+
# Install dependencies
|
|
254
|
+
poetry install --with dev,docs
|
|
255
|
+
|
|
256
|
+
# Activate virtual environment
|
|
257
|
+
poetry shell
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
### Running Tests
|
|
261
|
+
|
|
262
|
+
```bash
|
|
263
|
+
# Run tests
|
|
264
|
+
poetry run pytest
|
|
265
|
+
|
|
266
|
+
# Run tests with coverage
|
|
267
|
+
poetry run pytest --cov=src/marqetive --cov-report=term-missing
|
|
268
|
+
|
|
269
|
+
# Run platform-specific tests
|
|
270
|
+
poetry run pytest tests/platforms/test_twitter.py
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
### Code Quality
|
|
274
|
+
|
|
275
|
+
```bash
|
|
276
|
+
# Lint code with Ruff
|
|
277
|
+
poetry run ruff check .
|
|
278
|
+
|
|
279
|
+
# Format code with Ruff
|
|
280
|
+
poetry run ruff format .
|
|
281
|
+
|
|
282
|
+
# Type check with Pyright
|
|
283
|
+
poetry run pyright src/
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
## License
|
|
287
|
+
|
|
288
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
289
|
+
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
# MarqetiveLib
|
|
2
|
+
|
|
3
|
+
Modern Python library for social media platform integrations - Simple, type-safe, and async-ready.
|
|
4
|
+
|
|
5
|
+
## Supported Platforms
|
|
6
|
+
|
|
7
|
+
- **Twitter/X** - Post tweets, upload media, manage threads
|
|
8
|
+
- **LinkedIn** - Share updates, upload images and videos
|
|
9
|
+
- **Instagram** - Create posts with media via Graph API
|
|
10
|
+
- **TikTok** - Upload and publish videos
|
|
11
|
+
|
|
12
|
+
## Features
|
|
13
|
+
|
|
14
|
+
- **Unified API**: Single interface for all social media platforms
|
|
15
|
+
- **Async-First**: Built for modern async Python applications
|
|
16
|
+
- **Type-Safe**: Full type hints and Pyright compliance
|
|
17
|
+
- **Auto Token Refresh**: Factory handles OAuth token lifecycle automatically
|
|
18
|
+
- **Media Upload**: Progress tracking for large file uploads
|
|
19
|
+
- **Retry Logic**: Exponential backoff with jitter for transient failures
|
|
20
|
+
- **Well Tested**: Comprehensive test coverage
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pip install marqetive
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Or with Poetry:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
poetry add marqetive
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Quick Start
|
|
35
|
+
|
|
36
|
+
```python
|
|
37
|
+
import asyncio
|
|
38
|
+
from marqetive import get_client, AuthCredentials, PostCreateRequest
|
|
39
|
+
|
|
40
|
+
async def main():
|
|
41
|
+
# Create credentials for your platform
|
|
42
|
+
credentials = AuthCredentials(
|
|
43
|
+
platform="twitter",
|
|
44
|
+
access_token="your_access_token",
|
|
45
|
+
refresh_token="your_refresh_token"
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
# Get authenticated client (auto-refreshes token if expired)
|
|
49
|
+
client = await get_client(credentials)
|
|
50
|
+
|
|
51
|
+
# Use client as async context manager
|
|
52
|
+
async with client:
|
|
53
|
+
request = PostCreateRequest(content="Hello from MarqetiveLib!")
|
|
54
|
+
post = await client.create_post(request)
|
|
55
|
+
print(f"Posted! ID: {post.platform_id}")
|
|
56
|
+
|
|
57
|
+
asyncio.run(main())
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Platform Examples
|
|
61
|
+
|
|
62
|
+
### Twitter
|
|
63
|
+
|
|
64
|
+
```python
|
|
65
|
+
from marqetive import get_client, AuthCredentials, PostCreateRequest
|
|
66
|
+
|
|
67
|
+
credentials = AuthCredentials(
|
|
68
|
+
platform="twitter",
|
|
69
|
+
access_token="your_access_token",
|
|
70
|
+
refresh_token="your_refresh_token" # Optional, for token refresh
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
client = await get_client(credentials)
|
|
74
|
+
async with client:
|
|
75
|
+
# Text post
|
|
76
|
+
post = await client.create_post(PostCreateRequest(content="Hello Twitter!"))
|
|
77
|
+
|
|
78
|
+
# Post with media
|
|
79
|
+
post = await client.create_post(PostCreateRequest(
|
|
80
|
+
content="Check out this image!",
|
|
81
|
+
media_paths=["/path/to/image.jpg"]
|
|
82
|
+
))
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### LinkedIn
|
|
86
|
+
|
|
87
|
+
```python
|
|
88
|
+
from marqetive import get_client, AuthCredentials, PostCreateRequest
|
|
89
|
+
|
|
90
|
+
credentials = AuthCredentials(
|
|
91
|
+
platform="linkedin",
|
|
92
|
+
access_token="your_access_token",
|
|
93
|
+
user_id="urn:li:person:your_person_id" # Required for LinkedIn
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
client = await get_client(credentials)
|
|
97
|
+
async with client:
|
|
98
|
+
post = await client.create_post(PostCreateRequest(
|
|
99
|
+
content="Excited to share this update!"
|
|
100
|
+
))
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Instagram
|
|
104
|
+
|
|
105
|
+
```python
|
|
106
|
+
from marqetive import get_client, AuthCredentials, PostCreateRequest
|
|
107
|
+
|
|
108
|
+
credentials = AuthCredentials(
|
|
109
|
+
platform="instagram",
|
|
110
|
+
access_token="your_access_token",
|
|
111
|
+
user_id="your_instagram_business_account_id" # Required
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
client = await get_client(credentials)
|
|
115
|
+
async with client:
|
|
116
|
+
# Instagram requires media for posts
|
|
117
|
+
post = await client.create_post(PostCreateRequest(
|
|
118
|
+
content="Beautiful day! #photography",
|
|
119
|
+
media_paths=["/path/to/photo.jpg"]
|
|
120
|
+
))
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### TikTok
|
|
124
|
+
|
|
125
|
+
```python
|
|
126
|
+
from marqetive import get_client, AuthCredentials, PostCreateRequest
|
|
127
|
+
|
|
128
|
+
credentials = AuthCredentials(
|
|
129
|
+
platform="tiktok",
|
|
130
|
+
access_token="your_access_token",
|
|
131
|
+
additional_data={"open_id": "your_open_id"} # Required for TikTok
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
client = await get_client(credentials)
|
|
135
|
+
async with client:
|
|
136
|
+
post = await client.create_post(PostCreateRequest(
|
|
137
|
+
content="Check out this video!",
|
|
138
|
+
media_paths=["/path/to/video.mp4"]
|
|
139
|
+
))
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## Using Custom OAuth Credentials
|
|
143
|
+
|
|
144
|
+
```python
|
|
145
|
+
from marqetive import PlatformFactory, AuthCredentials, PostCreateRequest
|
|
146
|
+
|
|
147
|
+
# Create factory with your OAuth app credentials
|
|
148
|
+
factory = PlatformFactory(
|
|
149
|
+
twitter_client_id="your_client_id",
|
|
150
|
+
twitter_client_secret="your_client_secret",
|
|
151
|
+
linkedin_client_id="your_linkedin_client_id",
|
|
152
|
+
linkedin_client_secret="your_linkedin_client_secret"
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
credentials = AuthCredentials(
|
|
156
|
+
platform="twitter",
|
|
157
|
+
access_token="user_access_token",
|
|
158
|
+
refresh_token="user_refresh_token"
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
# Get client with automatic token refresh
|
|
162
|
+
client = await factory.get_client(credentials)
|
|
163
|
+
async with client:
|
|
164
|
+
post = await client.create_post(PostCreateRequest(content="Hello!"))
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## Progress Tracking for Media Uploads
|
|
168
|
+
|
|
169
|
+
```python
|
|
170
|
+
def progress_callback(operation: str, progress: int, total: int, message: str | None):
|
|
171
|
+
percent = (progress / total) * 100 if total > 0 else 0
|
|
172
|
+
print(f"{operation}: {percent:.1f}% - {message or ''}")
|
|
173
|
+
|
|
174
|
+
client = await get_client(credentials, progress_callback=progress_callback)
|
|
175
|
+
async with client:
|
|
176
|
+
post = await client.create_post(PostCreateRequest(
|
|
177
|
+
content="Uploading video...",
|
|
178
|
+
media_paths=["/path/to/large_video.mp4"]
|
|
179
|
+
))
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
## Error Handling
|
|
183
|
+
|
|
184
|
+
```python
|
|
185
|
+
from marqetive import get_client, AuthCredentials, PostCreateRequest
|
|
186
|
+
from marqetive.core.exceptions import (
|
|
187
|
+
PlatformError,
|
|
188
|
+
PlatformAuthError,
|
|
189
|
+
RateLimitError,
|
|
190
|
+
MediaUploadError
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
try:
|
|
194
|
+
client = await get_client(credentials)
|
|
195
|
+
async with client:
|
|
196
|
+
post = await client.create_post(request)
|
|
197
|
+
except PlatformAuthError as e:
|
|
198
|
+
print(f"Authentication failed: {e}")
|
|
199
|
+
# Token may need refresh or reconnection
|
|
200
|
+
except RateLimitError as e:
|
|
201
|
+
print(f"Rate limited. Retry after: {e.retry_after} seconds")
|
|
202
|
+
except MediaUploadError as e:
|
|
203
|
+
print(f"Media upload failed: {e}")
|
|
204
|
+
except PlatformError as e:
|
|
205
|
+
print(f"Platform error: {e}")
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
## Development
|
|
209
|
+
|
|
210
|
+
### Setup Development Environment
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
# Clone the repository
|
|
214
|
+
git clone https://github.com/your-org/marqetive-lib.git
|
|
215
|
+
cd marqetive-lib
|
|
216
|
+
|
|
217
|
+
# Install Poetry if you haven't already
|
|
218
|
+
curl -sSL https://install.python-poetry.org | python3 -
|
|
219
|
+
|
|
220
|
+
# Install dependencies
|
|
221
|
+
poetry install --with dev,docs
|
|
222
|
+
|
|
223
|
+
# Activate virtual environment
|
|
224
|
+
poetry shell
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### Running Tests
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
# Run tests
|
|
231
|
+
poetry run pytest
|
|
232
|
+
|
|
233
|
+
# Run tests with coverage
|
|
234
|
+
poetry run pytest --cov=src/marqetive --cov-report=term-missing
|
|
235
|
+
|
|
236
|
+
# Run platform-specific tests
|
|
237
|
+
poetry run pytest tests/platforms/test_twitter.py
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
### Code Quality
|
|
241
|
+
|
|
242
|
+
```bash
|
|
243
|
+
# Lint code with Ruff
|
|
244
|
+
poetry run ruff check .
|
|
245
|
+
|
|
246
|
+
# Format code with Ruff
|
|
247
|
+
poetry run ruff format .
|
|
248
|
+
|
|
249
|
+
# Type check with Pyright
|
|
250
|
+
poetry run pyright src/
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
## License
|
|
254
|
+
|
|
255
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
@@ -62,6 +62,8 @@ from marqetive.core.models import (
|
|
|
62
62
|
PostCreateRequest,
|
|
63
63
|
PostStatus,
|
|
64
64
|
PostUpdateRequest,
|
|
65
|
+
ProgressEvent,
|
|
66
|
+
ProgressStatus,
|
|
65
67
|
)
|
|
66
68
|
|
|
67
69
|
# Factory
|
|
@@ -85,17 +87,21 @@ __all__ = [
|
|
|
85
87
|
"BackoffConfig",
|
|
86
88
|
"STANDARD_BACKOFF",
|
|
87
89
|
"retry_async",
|
|
88
|
-
#
|
|
89
|
-
"AuthCredentials",
|
|
90
|
+
# Enums
|
|
90
91
|
"AccountStatus",
|
|
91
|
-
"
|
|
92
|
+
"CommentStatus",
|
|
93
|
+
"MediaType",
|
|
92
94
|
"PostStatus",
|
|
93
|
-
"
|
|
94
|
-
|
|
95
|
+
"ProgressStatus",
|
|
96
|
+
# Core Models
|
|
97
|
+
"AuthCredentials",
|
|
95
98
|
"Comment",
|
|
96
|
-
"CommentStatus",
|
|
97
99
|
"MediaAttachment",
|
|
98
|
-
"
|
|
100
|
+
"Post",
|
|
101
|
+
"ProgressEvent",
|
|
102
|
+
# Base Request Models
|
|
103
|
+
"PostCreateRequest",
|
|
104
|
+
"PostUpdateRequest",
|
|
99
105
|
# Exceptions
|
|
100
106
|
"PlatformError",
|
|
101
107
|
"PlatformAuthError",
|
|
@@ -31,17 +31,19 @@ __all__ = [
|
|
|
31
31
|
# Base class
|
|
32
32
|
"SocialMediaPlatform",
|
|
33
33
|
"ProgressCallback",
|
|
34
|
-
#
|
|
34
|
+
# Enums
|
|
35
35
|
"AccountStatus",
|
|
36
|
+
"CommentStatus",
|
|
37
|
+
"MediaType",
|
|
38
|
+
"PostStatus",
|
|
39
|
+
# Core Models
|
|
36
40
|
"AuthCredentials",
|
|
37
41
|
"Comment",
|
|
38
|
-
"CommentStatus",
|
|
39
42
|
"MediaAttachment",
|
|
40
|
-
"MediaType",
|
|
41
43
|
"PlatformResponse",
|
|
42
44
|
"Post",
|
|
45
|
+
# Base Request Models
|
|
43
46
|
"PostCreateRequest",
|
|
44
|
-
"PostStatus",
|
|
45
47
|
"PostUpdateRequest",
|
|
46
48
|
# Exceptions
|
|
47
49
|
"InvalidFileTypeError",
|