late-sdk 1.0.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.
- late_sdk-1.0.0/.env.example +6 -0
- late_sdk-1.0.0/.gitignore +83 -0
- late_sdk-1.0.0/PKG-INFO +277 -0
- late_sdk-1.0.0/README.md +231 -0
- late_sdk-1.0.0/claude-desktop-config.json +16 -0
- late_sdk-1.0.0/examples/01_basic_usage.py +61 -0
- late_sdk-1.0.0/examples/02_schedule_from_csv.py +52 -0
- late_sdk-1.0.0/examples/03_cross_posting.py +74 -0
- late_sdk-1.0.0/examples/04_ai_content_generation.py +72 -0
- late_sdk-1.0.0/examples/05_download_tools.py +58 -0
- late_sdk-1.0.0/examples/data/sample_posts.csv +6 -0
- late_sdk-1.0.0/examples/publish_post.py +52 -0
- late_sdk-1.0.0/pyproject.toml +147 -0
- late_sdk-1.0.0/scripts/generate_models.py +115 -0
- late_sdk-1.0.0/src/late/__init__.py +33 -0
- late_sdk-1.0.0/src/late/ai/__init__.py +24 -0
- late_sdk-1.0.0/src/late/ai/content_generator.py +152 -0
- late_sdk-1.0.0/src/late/ai/protocols.py +72 -0
- late_sdk-1.0.0/src/late/ai/providers/__init__.py +7 -0
- late_sdk-1.0.0/src/late/ai/providers/openai.py +157 -0
- late_sdk-1.0.0/src/late/client/__init__.py +32 -0
- late_sdk-1.0.0/src/late/client/base.py +326 -0
- late_sdk-1.0.0/src/late/client/exceptions.py +97 -0
- late_sdk-1.0.0/src/late/client/late_client.py +80 -0
- late_sdk-1.0.0/src/late/client/rate_limiter.py +110 -0
- late_sdk-1.0.0/src/late/mcp/__init__.py +5 -0
- late_sdk-1.0.0/src/late/mcp/__main__.py +6 -0
- late_sdk-1.0.0/src/late/mcp/server.py +576 -0
- late_sdk-1.0.0/src/late/models/__init__.py +58 -0
- late_sdk-1.0.0/src/late/models/_generated/models.py +818 -0
- late_sdk-1.0.0/src/late/pipelines/__init__.py +14 -0
- late_sdk-1.0.0/src/late/pipelines/cross_poster.py +205 -0
- late_sdk-1.0.0/src/late/pipelines/csv_scheduler.py +168 -0
- late_sdk-1.0.0/src/late/resources/__init__.py +23 -0
- late_sdk-1.0.0/src/late/resources/accounts.py +43 -0
- late_sdk-1.0.0/src/late/resources/analytics.py +44 -0
- late_sdk-1.0.0/src/late/resources/base.py +44 -0
- late_sdk-1.0.0/src/late/resources/media.py +169 -0
- late_sdk-1.0.0/src/late/resources/posts.py +163 -0
- late_sdk-1.0.0/src/late/resources/profiles.py +62 -0
- late_sdk-1.0.0/src/late/resources/queue.py +39 -0
- late_sdk-1.0.0/src/late/resources/tools.py +105 -0
- late_sdk-1.0.0/src/late/resources/users.py +34 -0
- late_sdk-1.0.0/tests/__init__.py +1 -0
- late_sdk-1.0.0/tests/conftest.py +15 -0
- late_sdk-1.0.0/tests/test_client.py +115 -0
- late_sdk-1.0.0/tests/test_exhaustive.py +853 -0
- late_sdk-1.0.0/uv.lock +1689 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
develop-eggs/
|
|
13
|
+
dist/
|
|
14
|
+
downloads/
|
|
15
|
+
eggs/
|
|
16
|
+
.eggs/
|
|
17
|
+
lib/
|
|
18
|
+
lib64/
|
|
19
|
+
parts/
|
|
20
|
+
sdist/
|
|
21
|
+
var/
|
|
22
|
+
wheels/
|
|
23
|
+
*.egg-info/
|
|
24
|
+
.installed.cfg
|
|
25
|
+
*.egg
|
|
26
|
+
|
|
27
|
+
# PyInstaller
|
|
28
|
+
*.manifest
|
|
29
|
+
*.spec
|
|
30
|
+
|
|
31
|
+
# Installer logs
|
|
32
|
+
pip-log.txt
|
|
33
|
+
pip-delete-this-directory.txt
|
|
34
|
+
|
|
35
|
+
# Unit test / coverage reports
|
|
36
|
+
htmlcov/
|
|
37
|
+
.tox/
|
|
38
|
+
.nox/
|
|
39
|
+
.coverage
|
|
40
|
+
.coverage.*
|
|
41
|
+
.cache
|
|
42
|
+
nosetests.xml
|
|
43
|
+
coverage.xml
|
|
44
|
+
*.cover
|
|
45
|
+
*.py,cover
|
|
46
|
+
.hypothesis/
|
|
47
|
+
.pytest_cache/
|
|
48
|
+
|
|
49
|
+
# Translations
|
|
50
|
+
*.mo
|
|
51
|
+
*.pot
|
|
52
|
+
|
|
53
|
+
# Environments
|
|
54
|
+
.env
|
|
55
|
+
.env.local
|
|
56
|
+
.venv
|
|
57
|
+
env/
|
|
58
|
+
venv/
|
|
59
|
+
ENV/
|
|
60
|
+
env.bak/
|
|
61
|
+
venv.bak/
|
|
62
|
+
|
|
63
|
+
# IDEs
|
|
64
|
+
.idea/
|
|
65
|
+
.vscode/
|
|
66
|
+
*.swp
|
|
67
|
+
*.swo
|
|
68
|
+
*~
|
|
69
|
+
|
|
70
|
+
# mypy
|
|
71
|
+
.mypy_cache/
|
|
72
|
+
.dmypy.json
|
|
73
|
+
dmypy.json
|
|
74
|
+
|
|
75
|
+
# ruff
|
|
76
|
+
.ruff_cache/
|
|
77
|
+
|
|
78
|
+
# OS
|
|
79
|
+
.DS_Store
|
|
80
|
+
Thumbs.db
|
|
81
|
+
|
|
82
|
+
# Project specific
|
|
83
|
+
*.log
|
late_sdk-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: late-sdk
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Python SDK for Late API - Social Media Scheduling
|
|
5
|
+
Project-URL: Homepage, https://getlate.dev
|
|
6
|
+
Project-URL: Documentation, https://docs.getlate.dev
|
|
7
|
+
Project-URL: Repository, https://github.com/getlate/late-python-starter
|
|
8
|
+
Project-URL: Issues, https://github.com/getlate/late-python-starter/issues
|
|
9
|
+
Author-email: Late <hello@getlate.dev>
|
|
10
|
+
License: MIT
|
|
11
|
+
Keywords: api-client,facebook,instagram,late,linkedin,scheduling,social-media,tiktok,twitter,youtube
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Topic :: Internet :: WWW/HTTP
|
|
22
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
23
|
+
Classifier: Typing :: Typed
|
|
24
|
+
Requires-Python: >=3.10
|
|
25
|
+
Requires-Dist: httpx>=0.27.0
|
|
26
|
+
Requires-Dist: pydantic>=2.0.0
|
|
27
|
+
Provides-Extra: ai
|
|
28
|
+
Requires-Dist: openai>=1.0.0; extra == 'ai'
|
|
29
|
+
Provides-Extra: all
|
|
30
|
+
Requires-Dist: anthropic>=0.40.0; extra == 'all'
|
|
31
|
+
Requires-Dist: mcp>=1.0.0; extra == 'all'
|
|
32
|
+
Requires-Dist: openai>=1.0.0; extra == 'all'
|
|
33
|
+
Provides-Extra: anthropic
|
|
34
|
+
Requires-Dist: anthropic>=0.40.0; extra == 'anthropic'
|
|
35
|
+
Provides-Extra: dev
|
|
36
|
+
Requires-Dist: datamodel-code-generator>=0.26.0; extra == 'dev'
|
|
37
|
+
Requires-Dist: mypy>=1.13.0; extra == 'dev'
|
|
38
|
+
Requires-Dist: pytest-asyncio>=0.24.0; extra == 'dev'
|
|
39
|
+
Requires-Dist: pytest-cov>=6.0.0; extra == 'dev'
|
|
40
|
+
Requires-Dist: pytest>=8.0.0; extra == 'dev'
|
|
41
|
+
Requires-Dist: respx>=0.21.0; extra == 'dev'
|
|
42
|
+
Requires-Dist: ruff>=0.8.0; extra == 'dev'
|
|
43
|
+
Provides-Extra: mcp
|
|
44
|
+
Requires-Dist: mcp>=1.0.0; extra == 'mcp'
|
|
45
|
+
Description-Content-Type: text/markdown
|
|
46
|
+
|
|
47
|
+
# Late Python SDK
|
|
48
|
+
|
|
49
|
+
Python SDK for [Late API](https://getlate.dev) - Schedule social media posts across multiple platforms.
|
|
50
|
+
|
|
51
|
+
## Installation
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
pip install late-sdk
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Quick Start
|
|
58
|
+
|
|
59
|
+
```python
|
|
60
|
+
from late import Late
|
|
61
|
+
|
|
62
|
+
client = Late(api_key="your_api_key")
|
|
63
|
+
|
|
64
|
+
# List connected accounts
|
|
65
|
+
accounts = client.accounts.list()
|
|
66
|
+
|
|
67
|
+
# Create a scheduled post
|
|
68
|
+
from datetime import datetime, timedelta
|
|
69
|
+
|
|
70
|
+
post = client.posts.create(
|
|
71
|
+
content="Hello from Late!",
|
|
72
|
+
platforms=[{"platform": "twitter", "accountId": "your_account_id"}],
|
|
73
|
+
scheduled_for=datetime.now() + timedelta(hours=1),
|
|
74
|
+
)
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## 🤖 Claude Desktop Integration (MCP)
|
|
80
|
+
|
|
81
|
+
Schedule posts directly from Claude Desktop using natural language.
|
|
82
|
+
|
|
83
|
+
### Setup in 3 Steps
|
|
84
|
+
|
|
85
|
+
**1. Install uv** (package manager)
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
# macOS / Linux
|
|
89
|
+
curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
90
|
+
|
|
91
|
+
# Windows (PowerShell)
|
|
92
|
+
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
**2. Add to Claude Desktop config**
|
|
96
|
+
|
|
97
|
+
Open the config file:
|
|
98
|
+
- **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
99
|
+
- **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
|
|
100
|
+
|
|
101
|
+
Add this:
|
|
102
|
+
|
|
103
|
+
```json
|
|
104
|
+
{
|
|
105
|
+
"mcpServers": {
|
|
106
|
+
"late": {
|
|
107
|
+
"command": "uvx",
|
|
108
|
+
"args": ["--from", "late-sdk[mcp]", "late-mcp"],
|
|
109
|
+
"env": {
|
|
110
|
+
"LATE_API_KEY": "your_api_key_here"
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
> Get your API key at [getlate.dev/dashboard/api-keys](https://getlate.dev/dashboard/api-keys)
|
|
118
|
+
|
|
119
|
+
**3. Restart Claude Desktop**
|
|
120
|
+
|
|
121
|
+
Done! Ask Claude things like:
|
|
122
|
+
- *"Post 'Hello world!' to Twitter"*
|
|
123
|
+
- *"Schedule a LinkedIn post for tomorrow at 9am"*
|
|
124
|
+
- *"Show my connected accounts"*
|
|
125
|
+
|
|
126
|
+
<details>
|
|
127
|
+
<summary><b>Alternative: Using pip instead of uvx</b></summary>
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
pip install late-sdk[mcp]
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
```json
|
|
134
|
+
{
|
|
135
|
+
"mcpServers": {
|
|
136
|
+
"late": {
|
|
137
|
+
"command": "python",
|
|
138
|
+
"args": ["-m", "late.mcp"],
|
|
139
|
+
"env": {
|
|
140
|
+
"LATE_API_KEY": "your_api_key_here"
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
</details>
|
|
148
|
+
|
|
149
|
+
### Uploading Images/Videos
|
|
150
|
+
|
|
151
|
+
Since Claude can't access local files, use the browser upload flow:
|
|
152
|
+
|
|
153
|
+
1. Ask Claude: *"I want to post an image to Instagram"*
|
|
154
|
+
2. Claude gives you an upload link → open it in your browser
|
|
155
|
+
3. Upload your file and tell Claude *"done"*
|
|
156
|
+
4. Claude creates the post with your media
|
|
157
|
+
|
|
158
|
+
### Available Commands
|
|
159
|
+
|
|
160
|
+
| Command | What it does |
|
|
161
|
+
|---------|--------------|
|
|
162
|
+
| `list_accounts` | Show connected social accounts |
|
|
163
|
+
| `create_post` | Create scheduled or immediate post |
|
|
164
|
+
| `publish_now` | Publish immediately |
|
|
165
|
+
| `cross_post` | Post to multiple platforms |
|
|
166
|
+
| `list_posts` | Show your posts |
|
|
167
|
+
| `retry_post` | Retry a failed post |
|
|
168
|
+
| `generate_upload_link` | Get link to upload media |
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## SDK Features
|
|
173
|
+
|
|
174
|
+
### Async Support
|
|
175
|
+
|
|
176
|
+
```python
|
|
177
|
+
import asyncio
|
|
178
|
+
from late import Late
|
|
179
|
+
|
|
180
|
+
async def main():
|
|
181
|
+
async with Late(api_key="...") as client:
|
|
182
|
+
posts = await client.posts.alist(status="scheduled")
|
|
183
|
+
|
|
184
|
+
asyncio.run(main())
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### AI Content Generation
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
pip install late-sdk[ai]
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
```python
|
|
194
|
+
from late.ai import ContentGenerator, GenerateRequest
|
|
195
|
+
|
|
196
|
+
generator = ContentGenerator(provider="openai", api_key="sk-...")
|
|
197
|
+
|
|
198
|
+
response = generator.generate(
|
|
199
|
+
GenerateRequest(
|
|
200
|
+
prompt="Write a tweet about Python",
|
|
201
|
+
platform="twitter",
|
|
202
|
+
tone="casual",
|
|
203
|
+
)
|
|
204
|
+
)
|
|
205
|
+
|
|
206
|
+
print(response.text)
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### CSV Scheduling
|
|
210
|
+
|
|
211
|
+
```python
|
|
212
|
+
from late import Late
|
|
213
|
+
from late.pipelines import CSVSchedulerPipeline
|
|
214
|
+
|
|
215
|
+
client = Late(api_key="...")
|
|
216
|
+
pipeline = CSVSchedulerPipeline(client)
|
|
217
|
+
|
|
218
|
+
# Validate first
|
|
219
|
+
results = pipeline.schedule("posts.csv", dry_run=True)
|
|
220
|
+
|
|
221
|
+
# Then schedule
|
|
222
|
+
results = pipeline.schedule("posts.csv")
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
### Cross-Posting
|
|
226
|
+
|
|
227
|
+
```python
|
|
228
|
+
from late.pipelines import CrossPosterPipeline, PlatformConfig
|
|
229
|
+
|
|
230
|
+
cross_poster = CrossPosterPipeline(client)
|
|
231
|
+
|
|
232
|
+
results = await cross_poster.post(
|
|
233
|
+
content="Big announcement!",
|
|
234
|
+
platforms=[
|
|
235
|
+
PlatformConfig("twitter", "tw_123"),
|
|
236
|
+
PlatformConfig("linkedin", "li_456", delay_minutes=5),
|
|
237
|
+
],
|
|
238
|
+
)
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
---
|
|
242
|
+
|
|
243
|
+
## API Reference
|
|
244
|
+
|
|
245
|
+
### Resources
|
|
246
|
+
|
|
247
|
+
| Resource | Methods |
|
|
248
|
+
|----------|---------|
|
|
249
|
+
| `client.posts` | `list`, `get`, `create`, `update`, `delete`, `retry` |
|
|
250
|
+
| `client.profiles` | `list`, `get`, `create`, `update`, `delete` |
|
|
251
|
+
| `client.accounts` | `list`, `get` |
|
|
252
|
+
| `client.media` | `upload`, `upload_multiple` |
|
|
253
|
+
| `client.analytics` | `get`, `get_usage` |
|
|
254
|
+
| `client.tools` | `youtube_download`, `instagram_download`, `tiktok_download`, `generate_caption` |
|
|
255
|
+
| `client.queue` | `get_slots`, `preview`, `next_slot` |
|
|
256
|
+
|
|
257
|
+
### Client Options
|
|
258
|
+
|
|
259
|
+
```python
|
|
260
|
+
client = Late(
|
|
261
|
+
api_key="...",
|
|
262
|
+
timeout=30.0, # seconds
|
|
263
|
+
max_retries=3,
|
|
264
|
+
)
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
## Links
|
|
270
|
+
|
|
271
|
+
- [Late Website](https://getlate.dev)
|
|
272
|
+
- [API Documentation](https://docs.getlate.dev)
|
|
273
|
+
- [Get API Key](https://getlate.dev/dashboard/api-keys)
|
|
274
|
+
|
|
275
|
+
## License
|
|
276
|
+
|
|
277
|
+
MIT
|
late_sdk-1.0.0/README.md
ADDED
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
# Late Python SDK
|
|
2
|
+
|
|
3
|
+
Python SDK for [Late API](https://getlate.dev) - Schedule social media posts across multiple platforms.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install late-sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
from late import Late
|
|
15
|
+
|
|
16
|
+
client = Late(api_key="your_api_key")
|
|
17
|
+
|
|
18
|
+
# List connected accounts
|
|
19
|
+
accounts = client.accounts.list()
|
|
20
|
+
|
|
21
|
+
# Create a scheduled post
|
|
22
|
+
from datetime import datetime, timedelta
|
|
23
|
+
|
|
24
|
+
post = client.posts.create(
|
|
25
|
+
content="Hello from Late!",
|
|
26
|
+
platforms=[{"platform": "twitter", "accountId": "your_account_id"}],
|
|
27
|
+
scheduled_for=datetime.now() + timedelta(hours=1),
|
|
28
|
+
)
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## 🤖 Claude Desktop Integration (MCP)
|
|
34
|
+
|
|
35
|
+
Schedule posts directly from Claude Desktop using natural language.
|
|
36
|
+
|
|
37
|
+
### Setup in 3 Steps
|
|
38
|
+
|
|
39
|
+
**1. Install uv** (package manager)
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
# macOS / Linux
|
|
43
|
+
curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
44
|
+
|
|
45
|
+
# Windows (PowerShell)
|
|
46
|
+
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
**2. Add to Claude Desktop config**
|
|
50
|
+
|
|
51
|
+
Open the config file:
|
|
52
|
+
- **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
53
|
+
- **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
|
|
54
|
+
|
|
55
|
+
Add this:
|
|
56
|
+
|
|
57
|
+
```json
|
|
58
|
+
{
|
|
59
|
+
"mcpServers": {
|
|
60
|
+
"late": {
|
|
61
|
+
"command": "uvx",
|
|
62
|
+
"args": ["--from", "late-sdk[mcp]", "late-mcp"],
|
|
63
|
+
"env": {
|
|
64
|
+
"LATE_API_KEY": "your_api_key_here"
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
> Get your API key at [getlate.dev/dashboard/api-keys](https://getlate.dev/dashboard/api-keys)
|
|
72
|
+
|
|
73
|
+
**3. Restart Claude Desktop**
|
|
74
|
+
|
|
75
|
+
Done! Ask Claude things like:
|
|
76
|
+
- *"Post 'Hello world!' to Twitter"*
|
|
77
|
+
- *"Schedule a LinkedIn post for tomorrow at 9am"*
|
|
78
|
+
- *"Show my connected accounts"*
|
|
79
|
+
|
|
80
|
+
<details>
|
|
81
|
+
<summary><b>Alternative: Using pip instead of uvx</b></summary>
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
pip install late-sdk[mcp]
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
```json
|
|
88
|
+
{
|
|
89
|
+
"mcpServers": {
|
|
90
|
+
"late": {
|
|
91
|
+
"command": "python",
|
|
92
|
+
"args": ["-m", "late.mcp"],
|
|
93
|
+
"env": {
|
|
94
|
+
"LATE_API_KEY": "your_api_key_here"
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
</details>
|
|
102
|
+
|
|
103
|
+
### Uploading Images/Videos
|
|
104
|
+
|
|
105
|
+
Since Claude can't access local files, use the browser upload flow:
|
|
106
|
+
|
|
107
|
+
1. Ask Claude: *"I want to post an image to Instagram"*
|
|
108
|
+
2. Claude gives you an upload link → open it in your browser
|
|
109
|
+
3. Upload your file and tell Claude *"done"*
|
|
110
|
+
4. Claude creates the post with your media
|
|
111
|
+
|
|
112
|
+
### Available Commands
|
|
113
|
+
|
|
114
|
+
| Command | What it does |
|
|
115
|
+
|---------|--------------|
|
|
116
|
+
| `list_accounts` | Show connected social accounts |
|
|
117
|
+
| `create_post` | Create scheduled or immediate post |
|
|
118
|
+
| `publish_now` | Publish immediately |
|
|
119
|
+
| `cross_post` | Post to multiple platforms |
|
|
120
|
+
| `list_posts` | Show your posts |
|
|
121
|
+
| `retry_post` | Retry a failed post |
|
|
122
|
+
| `generate_upload_link` | Get link to upload media |
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## SDK Features
|
|
127
|
+
|
|
128
|
+
### Async Support
|
|
129
|
+
|
|
130
|
+
```python
|
|
131
|
+
import asyncio
|
|
132
|
+
from late import Late
|
|
133
|
+
|
|
134
|
+
async def main():
|
|
135
|
+
async with Late(api_key="...") as client:
|
|
136
|
+
posts = await client.posts.alist(status="scheduled")
|
|
137
|
+
|
|
138
|
+
asyncio.run(main())
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### AI Content Generation
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
pip install late-sdk[ai]
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
```python
|
|
148
|
+
from late.ai import ContentGenerator, GenerateRequest
|
|
149
|
+
|
|
150
|
+
generator = ContentGenerator(provider="openai", api_key="sk-...")
|
|
151
|
+
|
|
152
|
+
response = generator.generate(
|
|
153
|
+
GenerateRequest(
|
|
154
|
+
prompt="Write a tweet about Python",
|
|
155
|
+
platform="twitter",
|
|
156
|
+
tone="casual",
|
|
157
|
+
)
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
print(response.text)
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### CSV Scheduling
|
|
164
|
+
|
|
165
|
+
```python
|
|
166
|
+
from late import Late
|
|
167
|
+
from late.pipelines import CSVSchedulerPipeline
|
|
168
|
+
|
|
169
|
+
client = Late(api_key="...")
|
|
170
|
+
pipeline = CSVSchedulerPipeline(client)
|
|
171
|
+
|
|
172
|
+
# Validate first
|
|
173
|
+
results = pipeline.schedule("posts.csv", dry_run=True)
|
|
174
|
+
|
|
175
|
+
# Then schedule
|
|
176
|
+
results = pipeline.schedule("posts.csv")
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### Cross-Posting
|
|
180
|
+
|
|
181
|
+
```python
|
|
182
|
+
from late.pipelines import CrossPosterPipeline, PlatformConfig
|
|
183
|
+
|
|
184
|
+
cross_poster = CrossPosterPipeline(client)
|
|
185
|
+
|
|
186
|
+
results = await cross_poster.post(
|
|
187
|
+
content="Big announcement!",
|
|
188
|
+
platforms=[
|
|
189
|
+
PlatformConfig("twitter", "tw_123"),
|
|
190
|
+
PlatformConfig("linkedin", "li_456", delay_minutes=5),
|
|
191
|
+
],
|
|
192
|
+
)
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
---
|
|
196
|
+
|
|
197
|
+
## API Reference
|
|
198
|
+
|
|
199
|
+
### Resources
|
|
200
|
+
|
|
201
|
+
| Resource | Methods |
|
|
202
|
+
|----------|---------|
|
|
203
|
+
| `client.posts` | `list`, `get`, `create`, `update`, `delete`, `retry` |
|
|
204
|
+
| `client.profiles` | `list`, `get`, `create`, `update`, `delete` |
|
|
205
|
+
| `client.accounts` | `list`, `get` |
|
|
206
|
+
| `client.media` | `upload`, `upload_multiple` |
|
|
207
|
+
| `client.analytics` | `get`, `get_usage` |
|
|
208
|
+
| `client.tools` | `youtube_download`, `instagram_download`, `tiktok_download`, `generate_caption` |
|
|
209
|
+
| `client.queue` | `get_slots`, `preview`, `next_slot` |
|
|
210
|
+
|
|
211
|
+
### Client Options
|
|
212
|
+
|
|
213
|
+
```python
|
|
214
|
+
client = Late(
|
|
215
|
+
api_key="...",
|
|
216
|
+
timeout=30.0, # seconds
|
|
217
|
+
max_retries=3,
|
|
218
|
+
)
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
---
|
|
222
|
+
|
|
223
|
+
## Links
|
|
224
|
+
|
|
225
|
+
- [Late Website](https://getlate.dev)
|
|
226
|
+
- [API Documentation](https://docs.getlate.dev)
|
|
227
|
+
- [Get API Key](https://getlate.dev/dashboard/api-keys)
|
|
228
|
+
|
|
229
|
+
## License
|
|
230
|
+
|
|
231
|
+
MIT
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"mcpServers": {
|
|
3
|
+
"late": {
|
|
4
|
+
"command": "uv",
|
|
5
|
+
"args": [
|
|
6
|
+
"run",
|
|
7
|
+
"--directory",
|
|
8
|
+
"/Users/carlos/Documents/WebDev/Freelance/miquel-palet/late-python-starter",
|
|
9
|
+
"late-mcp"
|
|
10
|
+
],
|
|
11
|
+
"env": {
|
|
12
|
+
"LATE_API_KEY": "YOUR_API_KEY_HERE"
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Basic usage example for Late Python SDK.
|
|
3
|
+
|
|
4
|
+
This example demonstrates:
|
|
5
|
+
- Initializing the client
|
|
6
|
+
- Listing profiles and accounts
|
|
7
|
+
- Creating a scheduled post
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import os
|
|
11
|
+
from datetime import datetime, timedelta
|
|
12
|
+
|
|
13
|
+
from late import Late
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def main() -> None:
|
|
17
|
+
# Initialize client
|
|
18
|
+
api_key = os.getenv("LATE_API_KEY")
|
|
19
|
+
if not api_key:
|
|
20
|
+
print("Set LATE_API_KEY environment variable")
|
|
21
|
+
return
|
|
22
|
+
|
|
23
|
+
client = Late(api_key=api_key)
|
|
24
|
+
|
|
25
|
+
# List profiles
|
|
26
|
+
print("=== Profiles ===")
|
|
27
|
+
profiles = client.profiles.list()
|
|
28
|
+
for profile in profiles.get("profiles", []):
|
|
29
|
+
print(f" - {profile['name']} (ID: {profile['_id']})")
|
|
30
|
+
|
|
31
|
+
# List connected accounts
|
|
32
|
+
print("\n=== Connected Accounts ===")
|
|
33
|
+
accounts = client.accounts.list()
|
|
34
|
+
for account in accounts.get("accounts", []):
|
|
35
|
+
print(f" - {account['platform']}: {account.get('username', 'N/A')}")
|
|
36
|
+
|
|
37
|
+
# List scheduled posts
|
|
38
|
+
print("\n=== Scheduled Posts ===")
|
|
39
|
+
posts = client.posts.list(status="scheduled", limit=5)
|
|
40
|
+
for post in posts.get("posts", []):
|
|
41
|
+
print(f" - {post['content'][:50]}... ({post['status']})")
|
|
42
|
+
|
|
43
|
+
# Create a new post (example - uncomment to use)
|
|
44
|
+
# if accounts.get("accounts"):
|
|
45
|
+
# account = accounts["accounts"][0]
|
|
46
|
+
# scheduled_time = datetime.now() + timedelta(hours=1)
|
|
47
|
+
#
|
|
48
|
+
# post = client.posts.create(
|
|
49
|
+
# content="Hello from Late Python SDK!",
|
|
50
|
+
# platforms=[{
|
|
51
|
+
# "platform": account["platform"],
|
|
52
|
+
# "accountId": account["_id"],
|
|
53
|
+
# }],
|
|
54
|
+
# scheduled_for=scheduled_time,
|
|
55
|
+
# tags=["test", "late-sdk"],
|
|
56
|
+
# )
|
|
57
|
+
# print(f"\nCreated post: {post['post']['_id']}")
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
if __name__ == "__main__":
|
|
61
|
+
main()
|