tiktok-live-api 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.
@@ -0,0 +1,13 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ *$py.class
4
+ *.egg-info/
5
+ dist/
6
+ build/
7
+ *.egg
8
+ .eggs/
9
+ *.whl
10
+ .env
11
+ .venv/
12
+ venv/
13
+ env/
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 TikTool
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,255 @@
1
+ Metadata-Version: 2.4
2
+ Name: tiktok-live-api
3
+ Version: 1.0.0
4
+ Summary: TikTok LIVE API Client — Real-time chat, gifts, viewers, battles, and live captions from any TikTok livestream. Production-ready managed API.
5
+ Project-URL: Homepage, https://tik.tools
6
+ Project-URL: Documentation, https://tik.tools/docs
7
+ Project-URL: Repository, https://github.com/tiktool/live-python
8
+ Project-URL: Issues, https://github.com/tiktool/live-python/issues
9
+ Project-URL: Changelog, https://github.com/tiktool/live-python/releases
10
+ Author-email: TikTool <support@tik.tools>
11
+ License: MIT
12
+ License-File: LICENSE
13
+ Keywords: captions,chat,euler-stream,gifts,live-chat,live-streaming,real-time,speech-to-text,tiktok,tiktok-api,tiktok-bot,tiktok-data,tiktok-live,tiktok-live-api,tiktok-live-connector,tiktok-live-python,tiktok-live-sdk,tiktok-tools,transcription,translation,webcast,websocket
14
+ Classifier: Development Status :: 5 - Production/Stable
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: License :: OSI Approved :: MIT License
17
+ Classifier: Operating System :: OS Independent
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3.8
20
+ Classifier: Programming Language :: Python :: 3.9
21
+ Classifier: Programming Language :: Python :: 3.10
22
+ Classifier: Programming Language :: Python :: 3.11
23
+ Classifier: Programming Language :: Python :: 3.12
24
+ Classifier: Programming Language :: Python :: 3.13
25
+ Classifier: Topic :: Internet
26
+ Classifier: Topic :: Multimedia :: Sound/Audio :: Speech
27
+ Classifier: Topic :: Software Development :: Libraries
28
+ Classifier: Typing :: Typed
29
+ Requires-Python: >=3.8
30
+ Requires-Dist: websockets>=11.0
31
+ Description-Content-Type: text/markdown
32
+
33
+ # tiktok-live-api
34
+
35
+ **TikTok LIVE API Client for Python** — Connect to any TikTok LIVE stream and receive real-time chat messages, gifts, likes, follows, viewer counts, battles, and more.
36
+
37
+ [![PyPI](https://img.shields.io/pypi/v/tiktok-live-api)](https://pypi.org/project/tiktok-live-api/)
38
+ [![Python](https://img.shields.io/pypi/pyversions/tiktok-live-api)](https://pypi.org/project/tiktok-live-api/)
39
+ [![License](https://img.shields.io/pypi/l/tiktok-live-api)](https://github.com/tiktool/live-python/blob/main/LICENSE)
40
+
41
+ > **Production-ready alternative to the `TikTokLive` library.** Unlike `TikTokLive` which reverse-engineers TikTok's internal protocol and breaks frequently, `tiktok-live-api` connects to TikTool Live's managed API service — 99.9% uptime, zero maintenance. Also available for Node.js: `npm install @tiktool/live`.
42
+
43
+ ## Install
44
+
45
+ ```bash
46
+ pip install tiktok-live-api
47
+ ```
48
+
49
+ ## Quick Start
50
+
51
+ ```python
52
+ from tiktok_live_api import TikTokLive
53
+
54
+ client = TikTokLive("streamer_username", api_key="YOUR_API_KEY")
55
+
56
+ @client.on("chat")
57
+ def on_chat(event):
58
+ print(f"{event['user']['uniqueId']}: {event['comment']}")
59
+
60
+ @client.on("gift")
61
+ def on_gift(event):
62
+ print(f"{event['user']['uniqueId']} sent {event['giftName']} ({event['diamondCount']} 💎)")
63
+
64
+ @client.on("like")
65
+ def on_like(event):
66
+ print(f"{event['user']['uniqueId']} liked (total: {event['totalLikes']})")
67
+
68
+ @client.on("follow")
69
+ def on_follow(event):
70
+ print(f"{event['user']['uniqueId']} followed!")
71
+
72
+ @client.on("roomUserSeq")
73
+ def on_viewers(event):
74
+ print(f"{event['viewerCount']} viewers watching")
75
+
76
+ client.run()
77
+ ```
78
+
79
+ That's it. No complex setup, no protobuf, no reverse engineering.
80
+
81
+ ## Get a Free API Key
82
+
83
+ 1. Go to [tik.tools](https://tik.tools)
84
+ 2. Sign up (no credit card required)
85
+ 3. Copy your API key
86
+
87
+ The free Sandbox tier gives you 50 requests/day and 1 WebSocket connection.
88
+
89
+ ## Environment Variable
90
+
91
+ Instead of passing `api_key` directly, you can set it as an environment variable:
92
+
93
+ ```bash
94
+ # Linux / macOS
95
+ export TIKTOOL_API_KEY=your_api_key_here
96
+
97
+ # Windows (CMD)
98
+ set TIKTOOL_API_KEY=your_api_key_here
99
+
100
+ # Windows (PowerShell)
101
+ $env:TIKTOOL_API_KEY="your_api_key_here"
102
+ ```
103
+
104
+ ```bash
105
+ python my_bot.py
106
+ ```
107
+
108
+ ```python
109
+ from tiktok_live_api import TikTokLive
110
+
111
+ # Automatically reads TIKTOOL_API_KEY from environment
112
+ client = TikTokLive("streamer_username")
113
+ client.on("chat", lambda e: print(e["comment"]))
114
+ client.run()
115
+ ```
116
+
117
+ ## Events
118
+
119
+ | Event | Description | Key Fields |
120
+ |-------|-------------|------------|
121
+ | `chat` | Chat message | `user`, `comment`, `emotes` |
122
+ | `gift` | Virtual gift | `user`, `giftName`, `diamondCount`, `repeatCount` |
123
+ | `like` | Like event | `user`, `likeCount`, `totalLikes` |
124
+ | `follow` | New follower | `user` |
125
+ | `share` | Stream share | `user` |
126
+ | `member` | Viewer joined | `user` |
127
+ | `subscribe` | New subscriber | `user` |
128
+ | `roomUserSeq` | Viewer count | `viewerCount`, `topViewers` |
129
+ | `battle` | Battle event | `type`, `teams`, `scores` |
130
+ | `envelope` | Treasure chest | `diamonds`, `user` |
131
+ | `streamEnd` | Stream ended | `reason` |
132
+ | `connected` | Connected | `uniqueId` |
133
+ | `disconnected` | Disconnected | `uniqueId` |
134
+ | `error` | Error occurred | `error` |
135
+ | `event` | Catch-all | Full raw event |
136
+
137
+ ## Live Captions (Speech-to-Text)
138
+
139
+ Transcribe and translate any TikTok LIVE stream in real-time. **This feature is unique to TikTool Live — no other service offers it.**
140
+
141
+ ```python
142
+ from tiktok_live_api import TikTokCaptions
143
+
144
+ captions = TikTokCaptions(
145
+ "streamer_username",
146
+ api_key="YOUR_API_KEY",
147
+ translate="en", # translate to English
148
+ diarization=True, # identify who is speaking
149
+ )
150
+
151
+ @captions.on("caption")
152
+ def on_caption(event):
153
+ speaker = event.get("speaker", "")
154
+ text = event["text"]
155
+ is_final = event.get("isFinal", False)
156
+ print(f"[{speaker}] {text}{' ✓' if is_final else '...'}")
157
+
158
+ @captions.on("translation")
159
+ def on_translation(event):
160
+ print(f" → {event['text']}")
161
+
162
+ captions.run()
163
+ ```
164
+
165
+ ## Async Usage
166
+
167
+ For integration with async frameworks (FastAPI, aiohttp, etc.):
168
+
169
+ ```python
170
+ import asyncio
171
+ from tiktok_live_api import TikTokLive
172
+
173
+ async def main():
174
+ client = TikTokLive("streamer_username", api_key="YOUR_API_KEY")
175
+
176
+ @client.on("chat")
177
+ async def on_chat(event):
178
+ print(f"{event['user']['uniqueId']}: {event['comment']}")
179
+
180
+ await client.connect()
181
+
182
+ asyncio.run(main())
183
+ ```
184
+
185
+ ## Chat Bot Example
186
+
187
+ ```python
188
+ from tiktok_live_api import TikTokLive
189
+
190
+ client = TikTokLive("streamer_username", api_key="YOUR_API_KEY")
191
+ gift_leaderboard = {}
192
+ message_count = 0
193
+
194
+ @client.on("chat")
195
+ def on_chat(event):
196
+ global message_count
197
+ message_count += 1
198
+ msg = event["comment"].lower().strip()
199
+ user = event["user"]["uniqueId"]
200
+
201
+ if msg == "!hello":
202
+ print(f">> BOT: Welcome {user}! 👋")
203
+ elif msg == "!stats":
204
+ print(f">> BOT: {message_count} messages, {len(gift_leaderboard)} gifters")
205
+ elif msg == "!top":
206
+ top = sorted(gift_leaderboard.items(), key=lambda x: -x[1])[:5]
207
+ for i, (name, diamonds) in enumerate(top):
208
+ print(f" {i+1}. {name} — {diamonds} 💎")
209
+
210
+ @client.on("gift")
211
+ def on_gift(event):
212
+ user = event["user"]["uniqueId"]
213
+ diamonds = event.get("diamondCount", 0)
214
+ gift_leaderboard[user] = gift_leaderboard.get(user, 0) + diamonds
215
+
216
+ client.run()
217
+ ```
218
+
219
+ ## Why tiktok-live-api?
220
+
221
+ | | tiktok-live-api | TikTokLive (Python) | tiktok-live-connector (Node.js) |
222
+ |---|---|---|---|
223
+ | **Stability** | ✓ Managed API, 99.9% uptime | ✗ Breaks on TikTok updates | ✗ Breaks on TikTok updates |
224
+ | **Live Captions** | ✓ AI speech-to-text | ✗ | ✗ |
225
+ | **Maintenance** | ✓ Zero — we handle it | ✗ You fix breakages | ✗ You fix breakages |
226
+ | **CAPTCHA Solving** | ✓ Built-in (Pro+) | ✗ | ✗ |
227
+ | **Feed Discovery** | ✓ See who's live | ✗ | ✗ |
228
+ | **Free Tier** | ✓ 50 requests/day | ✓ Free (unreliable) | ✓ Free (unreliable) |
229
+
230
+ ## Pricing
231
+
232
+ | Tier | Requests/Day | WebSocket Connections | Price |
233
+ |------|-------------|----------------------|-------|
234
+ | Sandbox | 50 | 1 (60s) | Free |
235
+ | Basic | 10,000 | 3 (8h) | $7/week |
236
+ | Pro | 75,000 | 50 (8h) | $15/week |
237
+ | Ultra | 300,000 | 500 (8h) | $45/week |
238
+
239
+ ## Also Available
240
+
241
+ - **Node.js/TypeScript**: [`npm install @tiktool/live`](https://www.npmjs.com/package/@tiktool/live)
242
+ - **Any language**: Connect via WebSocket: `wss://api.tik.tools?uniqueId=USERNAME&apiKey=KEY`
243
+ - **Unreal Engine**: Native C++/Blueprint plugin
244
+
245
+ ## Links
246
+
247
+ - **Website**: [tik.tools](https://tik.tools)
248
+ - **Documentation**: [tik.tools/docs](https://tik.tools/docs)
249
+ - **Python Guide**: [tik.tools/guides/python-tiktok-live](https://tik.tools/guides/python-tiktok-live)
250
+ - **GitHub**: [github.com/tiktool/live-python](https://github.com/tiktool/live-python)
251
+ - **npm (Node.js)**: [@tiktool/live](https://www.npmjs.com/package/@tiktool/live)
252
+
253
+ ## License
254
+
255
+ MIT
@@ -0,0 +1,223 @@
1
+ # tiktok-live-api
2
+
3
+ **TikTok LIVE API Client for Python** — Connect to any TikTok LIVE stream and receive real-time chat messages, gifts, likes, follows, viewer counts, battles, and more.
4
+
5
+ [![PyPI](https://img.shields.io/pypi/v/tiktok-live-api)](https://pypi.org/project/tiktok-live-api/)
6
+ [![Python](https://img.shields.io/pypi/pyversions/tiktok-live-api)](https://pypi.org/project/tiktok-live-api/)
7
+ [![License](https://img.shields.io/pypi/l/tiktok-live-api)](https://github.com/tiktool/live-python/blob/main/LICENSE)
8
+
9
+ > **Production-ready alternative to the `TikTokLive` library.** Unlike `TikTokLive` which reverse-engineers TikTok's internal protocol and breaks frequently, `tiktok-live-api` connects to TikTool Live's managed API service — 99.9% uptime, zero maintenance. Also available for Node.js: `npm install @tiktool/live`.
10
+
11
+ ## Install
12
+
13
+ ```bash
14
+ pip install tiktok-live-api
15
+ ```
16
+
17
+ ## Quick Start
18
+
19
+ ```python
20
+ from tiktok_live_api import TikTokLive
21
+
22
+ client = TikTokLive("streamer_username", api_key="YOUR_API_KEY")
23
+
24
+ @client.on("chat")
25
+ def on_chat(event):
26
+ print(f"{event['user']['uniqueId']}: {event['comment']}")
27
+
28
+ @client.on("gift")
29
+ def on_gift(event):
30
+ print(f"{event['user']['uniqueId']} sent {event['giftName']} ({event['diamondCount']} 💎)")
31
+
32
+ @client.on("like")
33
+ def on_like(event):
34
+ print(f"{event['user']['uniqueId']} liked (total: {event['totalLikes']})")
35
+
36
+ @client.on("follow")
37
+ def on_follow(event):
38
+ print(f"{event['user']['uniqueId']} followed!")
39
+
40
+ @client.on("roomUserSeq")
41
+ def on_viewers(event):
42
+ print(f"{event['viewerCount']} viewers watching")
43
+
44
+ client.run()
45
+ ```
46
+
47
+ That's it. No complex setup, no protobuf, no reverse engineering.
48
+
49
+ ## Get a Free API Key
50
+
51
+ 1. Go to [tik.tools](https://tik.tools)
52
+ 2. Sign up (no credit card required)
53
+ 3. Copy your API key
54
+
55
+ The free Sandbox tier gives you 50 requests/day and 1 WebSocket connection.
56
+
57
+ ## Environment Variable
58
+
59
+ Instead of passing `api_key` directly, you can set it as an environment variable:
60
+
61
+ ```bash
62
+ # Linux / macOS
63
+ export TIKTOOL_API_KEY=your_api_key_here
64
+
65
+ # Windows (CMD)
66
+ set TIKTOOL_API_KEY=your_api_key_here
67
+
68
+ # Windows (PowerShell)
69
+ $env:TIKTOOL_API_KEY="your_api_key_here"
70
+ ```
71
+
72
+ ```bash
73
+ python my_bot.py
74
+ ```
75
+
76
+ ```python
77
+ from tiktok_live_api import TikTokLive
78
+
79
+ # Automatically reads TIKTOOL_API_KEY from environment
80
+ client = TikTokLive("streamer_username")
81
+ client.on("chat", lambda e: print(e["comment"]))
82
+ client.run()
83
+ ```
84
+
85
+ ## Events
86
+
87
+ | Event | Description | Key Fields |
88
+ |-------|-------------|------------|
89
+ | `chat` | Chat message | `user`, `comment`, `emotes` |
90
+ | `gift` | Virtual gift | `user`, `giftName`, `diamondCount`, `repeatCount` |
91
+ | `like` | Like event | `user`, `likeCount`, `totalLikes` |
92
+ | `follow` | New follower | `user` |
93
+ | `share` | Stream share | `user` |
94
+ | `member` | Viewer joined | `user` |
95
+ | `subscribe` | New subscriber | `user` |
96
+ | `roomUserSeq` | Viewer count | `viewerCount`, `topViewers` |
97
+ | `battle` | Battle event | `type`, `teams`, `scores` |
98
+ | `envelope` | Treasure chest | `diamonds`, `user` |
99
+ | `streamEnd` | Stream ended | `reason` |
100
+ | `connected` | Connected | `uniqueId` |
101
+ | `disconnected` | Disconnected | `uniqueId` |
102
+ | `error` | Error occurred | `error` |
103
+ | `event` | Catch-all | Full raw event |
104
+
105
+ ## Live Captions (Speech-to-Text)
106
+
107
+ Transcribe and translate any TikTok LIVE stream in real-time. **This feature is unique to TikTool Live — no other service offers it.**
108
+
109
+ ```python
110
+ from tiktok_live_api import TikTokCaptions
111
+
112
+ captions = TikTokCaptions(
113
+ "streamer_username",
114
+ api_key="YOUR_API_KEY",
115
+ translate="en", # translate to English
116
+ diarization=True, # identify who is speaking
117
+ )
118
+
119
+ @captions.on("caption")
120
+ def on_caption(event):
121
+ speaker = event.get("speaker", "")
122
+ text = event["text"]
123
+ is_final = event.get("isFinal", False)
124
+ print(f"[{speaker}] {text}{' ✓' if is_final else '...'}")
125
+
126
+ @captions.on("translation")
127
+ def on_translation(event):
128
+ print(f" → {event['text']}")
129
+
130
+ captions.run()
131
+ ```
132
+
133
+ ## Async Usage
134
+
135
+ For integration with async frameworks (FastAPI, aiohttp, etc.):
136
+
137
+ ```python
138
+ import asyncio
139
+ from tiktok_live_api import TikTokLive
140
+
141
+ async def main():
142
+ client = TikTokLive("streamer_username", api_key="YOUR_API_KEY")
143
+
144
+ @client.on("chat")
145
+ async def on_chat(event):
146
+ print(f"{event['user']['uniqueId']}: {event['comment']}")
147
+
148
+ await client.connect()
149
+
150
+ asyncio.run(main())
151
+ ```
152
+
153
+ ## Chat Bot Example
154
+
155
+ ```python
156
+ from tiktok_live_api import TikTokLive
157
+
158
+ client = TikTokLive("streamer_username", api_key="YOUR_API_KEY")
159
+ gift_leaderboard = {}
160
+ message_count = 0
161
+
162
+ @client.on("chat")
163
+ def on_chat(event):
164
+ global message_count
165
+ message_count += 1
166
+ msg = event["comment"].lower().strip()
167
+ user = event["user"]["uniqueId"]
168
+
169
+ if msg == "!hello":
170
+ print(f">> BOT: Welcome {user}! 👋")
171
+ elif msg == "!stats":
172
+ print(f">> BOT: {message_count} messages, {len(gift_leaderboard)} gifters")
173
+ elif msg == "!top":
174
+ top = sorted(gift_leaderboard.items(), key=lambda x: -x[1])[:5]
175
+ for i, (name, diamonds) in enumerate(top):
176
+ print(f" {i+1}. {name} — {diamonds} 💎")
177
+
178
+ @client.on("gift")
179
+ def on_gift(event):
180
+ user = event["user"]["uniqueId"]
181
+ diamonds = event.get("diamondCount", 0)
182
+ gift_leaderboard[user] = gift_leaderboard.get(user, 0) + diamonds
183
+
184
+ client.run()
185
+ ```
186
+
187
+ ## Why tiktok-live-api?
188
+
189
+ | | tiktok-live-api | TikTokLive (Python) | tiktok-live-connector (Node.js) |
190
+ |---|---|---|---|
191
+ | **Stability** | ✓ Managed API, 99.9% uptime | ✗ Breaks on TikTok updates | ✗ Breaks on TikTok updates |
192
+ | **Live Captions** | ✓ AI speech-to-text | ✗ | ✗ |
193
+ | **Maintenance** | ✓ Zero — we handle it | ✗ You fix breakages | ✗ You fix breakages |
194
+ | **CAPTCHA Solving** | ✓ Built-in (Pro+) | ✗ | ✗ |
195
+ | **Feed Discovery** | ✓ See who's live | ✗ | ✗ |
196
+ | **Free Tier** | ✓ 50 requests/day | ✓ Free (unreliable) | ✓ Free (unreliable) |
197
+
198
+ ## Pricing
199
+
200
+ | Tier | Requests/Day | WebSocket Connections | Price |
201
+ |------|-------------|----------------------|-------|
202
+ | Sandbox | 50 | 1 (60s) | Free |
203
+ | Basic | 10,000 | 3 (8h) | $7/week |
204
+ | Pro | 75,000 | 50 (8h) | $15/week |
205
+ | Ultra | 300,000 | 500 (8h) | $45/week |
206
+
207
+ ## Also Available
208
+
209
+ - **Node.js/TypeScript**: [`npm install @tiktool/live`](https://www.npmjs.com/package/@tiktool/live)
210
+ - **Any language**: Connect via WebSocket: `wss://api.tik.tools?uniqueId=USERNAME&apiKey=KEY`
211
+ - **Unreal Engine**: Native C++/Blueprint plugin
212
+
213
+ ## Links
214
+
215
+ - **Website**: [tik.tools](https://tik.tools)
216
+ - **Documentation**: [tik.tools/docs](https://tik.tools/docs)
217
+ - **Python Guide**: [tik.tools/guides/python-tiktok-live](https://tik.tools/guides/python-tiktok-live)
218
+ - **GitHub**: [github.com/tiktool/live-python](https://github.com/tiktool/live-python)
219
+ - **npm (Node.js)**: [@tiktool/live](https://www.npmjs.com/package/@tiktool/live)
220
+
221
+ ## License
222
+
223
+ MIT
@@ -0,0 +1,61 @@
1
+ """Basic example — connect to a TikTok LIVE stream and print all events.
2
+
3
+ Usage:
4
+ # Set environment variables first:
5
+ # Linux/macOS: export TIKTOOL_API_KEY=your_key TIKTOK_USERNAME=streamer
6
+ # Windows CMD: set TIKTOOL_API_KEY=your_key & set TIKTOK_USERNAME=streamer
7
+ # PowerShell: $env:TIKTOOL_API_KEY="your_key"; $env:TIKTOK_USERNAME="streamer"
8
+
9
+ python basic.py
10
+ """
11
+
12
+ import os
13
+ import sys
14
+
15
+ from tiktok_live_api import TikTokLive
16
+
17
+ USERNAME = os.environ.get("TIKTOK_USERNAME", "")
18
+ if not USERNAME:
19
+ print("Set TIKTOK_USERNAME environment variable to the streamer's username.")
20
+ sys.exit(1)
21
+
22
+ client = TikTokLive(USERNAME)
23
+
24
+
25
+ @client.on("connected")
26
+ def on_connected(event):
27
+ print(f"Connected to @{event['uniqueId']}")
28
+
29
+
30
+ @client.on("chat")
31
+ def on_chat(event):
32
+ print(f"[chat] {event['user']['uniqueId']}: {event['comment']}")
33
+
34
+
35
+ @client.on("gift")
36
+ def on_gift(event):
37
+ diamonds = event.get("diamondCount", 0)
38
+ print(f"[gift] {event['user']['uniqueId']} sent {event['giftName']} ({diamonds} diamonds)")
39
+
40
+
41
+ @client.on("like")
42
+ def on_like(event):
43
+ print(f"[like] {event['user']['uniqueId']} liked (total: {event['totalLikes']})")
44
+
45
+
46
+ @client.on("follow")
47
+ def on_follow(event):
48
+ print(f"[follow] {event['user']['uniqueId']} followed")
49
+
50
+
51
+ @client.on("roomUserSeq")
52
+ def on_viewers(event):
53
+ print(f"[viewers] {event['viewerCount']} watching")
54
+
55
+
56
+ @client.on("streamEnd")
57
+ def on_stream_end(event):
58
+ print("[stream] Stream has ended.")
59
+
60
+
61
+ client.run()
@@ -0,0 +1,48 @@
1
+ """Live Captions example — transcribe and translate a TikTok LIVE stream.
2
+
3
+ Usage:
4
+ # Set environment variables first:
5
+ # Linux/macOS: export TIKTOOL_API_KEY=your_key TIKTOK_USERNAME=streamer
6
+ # Windows CMD: set TIKTOOL_API_KEY=your_key & set TIKTOK_USERNAME=streamer
7
+ # PowerShell: $env:TIKTOOL_API_KEY="your_key"; $env:TIKTOK_USERNAME="streamer"
8
+
9
+ python captions.py
10
+ """
11
+
12
+ import os
13
+ import sys
14
+
15
+ from tiktok_live_api import TikTokCaptions
16
+
17
+ USERNAME = os.environ.get("TIKTOK_USERNAME", "")
18
+ if not USERNAME:
19
+ print("Set TIKTOK_USERNAME environment variable to the streamer's username.")
20
+ sys.exit(1)
21
+
22
+ captions = TikTokCaptions(
23
+ USERNAME,
24
+ translate="en",
25
+ diarization=True,
26
+ )
27
+
28
+
29
+ @captions.on("connected")
30
+ def on_connected(event):
31
+ print(f"Listening to @{event['uniqueId']}")
32
+
33
+
34
+ @captions.on("caption")
35
+ def on_caption(event):
36
+ speaker = event.get("speaker", "")
37
+ text = event["text"]
38
+ is_final = event.get("isFinal", False)
39
+ status = "FINAL" if is_final else "partial"
40
+ print(f"[{status}] [{speaker}] {text}")
41
+
42
+
43
+ @captions.on("translation")
44
+ def on_translation(event):
45
+ print(f" -> {event['text']}")
46
+
47
+
48
+ captions.run()
@@ -0,0 +1,54 @@
1
+ """Chat bot example — respond to commands and track a gift leaderboard.
2
+
3
+ Usage:
4
+ # Set environment variables first:
5
+ # Linux/macOS: export TIKTOOL_API_KEY=your_key TIKTOK_USERNAME=streamer
6
+ # Windows CMD: set TIKTOOL_API_KEY=your_key & set TIKTOK_USERNAME=streamer
7
+ # PowerShell: $env:TIKTOOL_API_KEY="your_key"; $env:TIKTOK_USERNAME="streamer"
8
+
9
+ python chat_bot.py
10
+ """
11
+
12
+ import os
13
+ import sys
14
+ from typing import Dict
15
+
16
+ from tiktok_live_api import TikTokLive
17
+
18
+ USERNAME = os.environ.get("TIKTOK_USERNAME", "")
19
+ if not USERNAME:
20
+ print("Set TIKTOK_USERNAME environment variable to the streamer's username.")
21
+ sys.exit(1)
22
+
23
+ client = TikTokLive(USERNAME)
24
+
25
+ gift_leaderboard: Dict[str, int] = {}
26
+ message_count = 0
27
+
28
+
29
+ @client.on("chat")
30
+ def on_chat(event):
31
+ global message_count
32
+ message_count += 1
33
+ msg = event["comment"].lower().strip()
34
+ user = event["user"]["uniqueId"]
35
+
36
+ if msg == "!hello":
37
+ print(f">> BOT: Welcome {user}!")
38
+ elif msg == "!stats":
39
+ print(f">> BOT: {message_count} messages, {len(gift_leaderboard)} gifters")
40
+ elif msg == "!top":
41
+ top = sorted(gift_leaderboard.items(), key=lambda x: -x[1])[:5]
42
+ for rank, (name, diamonds) in enumerate(top, start=1):
43
+ print(f" {rank}. {name} - {diamonds} diamonds")
44
+
45
+
46
+ @client.on("gift")
47
+ def on_gift(event):
48
+ user = event["user"]["uniqueId"]
49
+ diamonds = event.get("diamondCount", 0)
50
+ gift_leaderboard[user] = gift_leaderboard.get(user, 0) + diamonds
51
+ print(f"[gift] {user} sent {event['giftName']} ({diamonds} diamonds)")
52
+
53
+
54
+ client.run()
@@ -0,0 +1,68 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "tiktok-live-api"
7
+ version = "1.0.0"
8
+ description = "TikTok LIVE API Client — Real-time chat, gifts, viewers, battles, and live captions from any TikTok livestream. Production-ready managed API."
9
+ readme = "README.md"
10
+ license = {text = "MIT"}
11
+ requires-python = ">=3.8"
12
+ authors = [
13
+ {name = "TikTool", email = "support@tik.tools"}
14
+ ]
15
+ keywords = [
16
+ "tiktok",
17
+ "tiktok-live",
18
+ "tiktok-api",
19
+ "tiktok-live-api",
20
+ "tiktok-live-connector",
21
+ "live-streaming",
22
+ "websocket",
23
+ "chat",
24
+ "gifts",
25
+ "webcast",
26
+ "real-time",
27
+ "speech-to-text",
28
+ "captions",
29
+ "transcription",
30
+ "translation",
31
+ "tiktok-data",
32
+ "tiktok-bot",
33
+ "live-chat",
34
+ "tiktok-live-python",
35
+ "tiktok-tools",
36
+ "euler-stream",
37
+ "tiktok-live-sdk"
38
+ ]
39
+ classifiers = [
40
+ "Development Status :: 5 - Production/Stable",
41
+ "Intended Audience :: Developers",
42
+ "License :: OSI Approved :: MIT License",
43
+ "Operating System :: OS Independent",
44
+ "Programming Language :: Python :: 3",
45
+ "Programming Language :: Python :: 3.8",
46
+ "Programming Language :: Python :: 3.9",
47
+ "Programming Language :: Python :: 3.10",
48
+ "Programming Language :: Python :: 3.11",
49
+ "Programming Language :: Python :: 3.12",
50
+ "Programming Language :: Python :: 3.13",
51
+ "Topic :: Internet",
52
+ "Topic :: Software Development :: Libraries",
53
+ "Topic :: Multimedia :: Sound/Audio :: Speech",
54
+ "Typing :: Typed",
55
+ ]
56
+ dependencies = [
57
+ "websockets>=11.0",
58
+ ]
59
+
60
+ [project.urls]
61
+ Homepage = "https://tik.tools"
62
+ Documentation = "https://tik.tools/docs"
63
+ Repository = "https://github.com/tiktool/live-python"
64
+ Issues = "https://github.com/tiktool/live-python/issues"
65
+ Changelog = "https://github.com/tiktool/live-python/releases"
66
+
67
+ [tool.hatch.build.targets.wheel]
68
+ packages = ["tiktok_live_api"]
@@ -0,0 +1,50 @@
1
+ """TikTok Live API — TikTok LIVE stream data client for Python.
2
+
3
+ Connect to any TikTok LIVE stream and receive real-time events:
4
+ chat messages, gifts, likes, follows, viewer counts, battles, and more.
5
+
6
+ Usage::
7
+
8
+ from tiktok_live_api import TikTokLive
9
+
10
+ client = TikTokLive("streamer_username", api_key="YOUR_KEY")
11
+
12
+ @client.on("chat")
13
+ def on_chat(event):
14
+ print(f"{event['user']['uniqueId']}: {event['comment']}")
15
+
16
+ client.run()
17
+
18
+ See https://tik.tools/docs for full documentation.
19
+ """
20
+
21
+ from tiktok_live_api.client import TikTokLive
22
+ from tiktok_live_api.captions import TikTokCaptions
23
+ from tiktok_live_api.types import (
24
+ TikTokUser,
25
+ ChatEvent,
26
+ GiftEvent,
27
+ LikeEvent,
28
+ MemberEvent,
29
+ SocialEvent,
30
+ RoomUserSeqEvent,
31
+ BattleEvent,
32
+ CaptionEvent,
33
+ TranslationEvent,
34
+ )
35
+
36
+ __all__ = [
37
+ "TikTokLive",
38
+ "TikTokCaptions",
39
+ "TikTokUser",
40
+ "ChatEvent",
41
+ "GiftEvent",
42
+ "LikeEvent",
43
+ "MemberEvent",
44
+ "SocialEvent",
45
+ "RoomUserSeqEvent",
46
+ "BattleEvent",
47
+ "CaptionEvent",
48
+ "TranslationEvent",
49
+ ]
50
+ __version__ = "1.0.0"
@@ -0,0 +1,203 @@
1
+ """TikTokCaptions — Real-time AI speech-to-text for TikTok LIVE streams."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import asyncio
6
+ import json
7
+ import logging
8
+ import os
9
+ import signal
10
+ from typing import Any, Callable, Dict, List, Optional, Union
11
+
12
+ import websockets
13
+ import websockets.client
14
+
15
+ logger = logging.getLogger("tiktok_live_api.captions")
16
+
17
+ EventHandler = Callable[[Dict[str, Any]], None]
18
+ AsyncEventHandler = Callable[[Dict[str, Any]], Any]
19
+ AnyHandler = Union[EventHandler, AsyncEventHandler]
20
+
21
+ CAPTIONS_BASE = "wss://api.tik.tools/captions"
22
+ _VERSION = "1.0.0"
23
+
24
+
25
+ class TikTokCaptions:
26
+ """Real-time AI speech-to-text transcription for TikTok LIVE streams.
27
+
28
+ This is a unique feature not available in any other TikTok LIVE library.
29
+
30
+ Args:
31
+ unique_id: TikTok username (without @).
32
+ api_key: Your TikTool API key. Get one at https://tik.tools
33
+ translate: Target language code for real-time translation (e.g. ``"en"``, ``"es"``).
34
+ diarization: Enable speaker identification (default ``True``).
35
+
36
+ Example::
37
+
38
+ from tiktok_live_api import TikTokCaptions
39
+
40
+ captions = TikTokCaptions("streamer", api_key="KEY", translate="en")
41
+
42
+ @captions.on("caption")
43
+ def on_caption(event):
44
+ print(f"[{event.get('speaker', '')}] {event['text']}")
45
+
46
+ captions.run()
47
+ """
48
+
49
+ def __init__(
50
+ self,
51
+ unique_id: str,
52
+ *,
53
+ api_key: Optional[str] = None,
54
+ translate: Optional[str] = None,
55
+ diarization: bool = True,
56
+ ) -> None:
57
+ self.unique_id = unique_id.lstrip("@")
58
+ self.api_key = api_key or os.environ.get("TIKTOOL_API_KEY", "")
59
+ if not self.api_key:
60
+ raise ValueError(
61
+ "api_key is required. Get a free key at https://tik.tools"
62
+ )
63
+ self.translate = translate
64
+ self.diarization = diarization
65
+
66
+ self._handlers: Dict[str, List[AnyHandler]] = {}
67
+ self._ws: Optional[websockets.client.WebSocketClientProtocol] = None
68
+ self._loop: Optional[asyncio.AbstractEventLoop] = None
69
+ self._connected = False
70
+ self._intentional_close = False
71
+
72
+ @property
73
+ def connected(self) -> bool:
74
+ """Whether the captions client is currently connected."""
75
+ return self._connected
76
+
77
+ def on(
78
+ self, event: str, handler: Optional[AnyHandler] = None
79
+ ) -> Any:
80
+ """Register an event handler. Can be used as a decorator or called directly.
81
+
82
+ Supported events:
83
+ caption, translation, credits, status, error, connected, disconnected
84
+
85
+ Usage as decorator::
86
+
87
+ @captions.on("caption")
88
+ def on_caption(event):
89
+ print(event["text"])
90
+
91
+ Usage as method::
92
+
93
+ captions.on("translation", lambda e: print(e["text"]))
94
+ """
95
+ if handler is not None:
96
+ self._handlers.setdefault(event, []).append(handler)
97
+ return handler
98
+
99
+ def decorator(fn: AnyHandler) -> AnyHandler:
100
+ self._handlers.setdefault(event, []).append(fn)
101
+ return fn
102
+
103
+ return decorator
104
+
105
+ def _emit(self, event: str, data: Any = None) -> None:
106
+ for handler in self._handlers.get(event, []):
107
+ try:
108
+ result = handler(data)
109
+ if asyncio.iscoroutine(result):
110
+ loop = self._loop or asyncio.get_event_loop()
111
+ loop.create_task(result)
112
+ except Exception as exc:
113
+ logger.error("Error in '%s' handler: %s", event, exc)
114
+
115
+ async def start(self) -> None:
116
+ """Start receiving captions from the stream.
117
+
118
+ For most use cases, prefer :meth:`run` which handles the event loop
119
+ automatically. Use ``start`` when integrating with an existing
120
+ async application.
121
+ """
122
+ self._intentional_close = False
123
+ self._loop = asyncio.get_event_loop()
124
+ params = f"uniqueId={self.unique_id}&apiKey={self.api_key}"
125
+ if self.translate:
126
+ params += f"&translate={self.translate}"
127
+ if self.diarization:
128
+ params += "&diarization=true"
129
+
130
+ uri = f"{CAPTIONS_BASE}?{params}"
131
+
132
+ try:
133
+ self._ws = await websockets.connect(
134
+ uri,
135
+ additional_headers={"User-Agent": f"tiktok-live-api-python/{_VERSION}"},
136
+ ping_interval=10,
137
+ ping_timeout=30,
138
+ )
139
+ except Exception as exc:
140
+ self._emit("error", {"error": str(exc)})
141
+ raise
142
+
143
+ self._connected = True
144
+ self._emit("connected", {"uniqueId": self.unique_id})
145
+
146
+ try:
147
+ async for raw in self._ws:
148
+ try:
149
+ event = json.loads(raw)
150
+ except (json.JSONDecodeError, TypeError):
151
+ continue
152
+
153
+ msg_type = event.get("type", "unknown")
154
+ self._emit(msg_type, event)
155
+ except websockets.ConnectionClosed:
156
+ pass
157
+ except Exception as exc:
158
+ self._emit("error", {"error": str(exc)})
159
+ finally:
160
+ self._connected = False
161
+ self._emit("disconnected", {"uniqueId": self.unique_id})
162
+
163
+ def stop(self) -> None:
164
+ """Stop receiving captions."""
165
+ self._intentional_close = True
166
+ if self._ws is not None:
167
+ if self._loop is not None and self._loop.is_running():
168
+ self._loop.create_task(self._ws.close())
169
+ else:
170
+ try:
171
+ asyncio.get_event_loop().run_until_complete(self._ws.close())
172
+ except RuntimeError:
173
+ pass
174
+ self._connected = False
175
+
176
+ def run(self) -> None:
177
+ """Start receiving captions and block until stopped.
178
+
179
+ Creates an event loop, connects to the captions stream, and blocks
180
+ until the stream ends or :meth:`stop` is called::
181
+
182
+ from tiktok_live_api import TikTokCaptions
183
+
184
+ captions = TikTokCaptions("streamer", api_key="KEY", translate="en")
185
+ captions.on("caption", lambda e: print(e["text"]))
186
+ captions.run()
187
+ """
188
+ loop = asyncio.new_event_loop()
189
+ asyncio.set_event_loop(loop)
190
+ self._loop = loop
191
+
192
+ for sig in (signal.SIGINT, signal.SIGTERM):
193
+ try:
194
+ loop.add_signal_handler(sig, self.stop)
195
+ except (NotImplementedError, ValueError, OSError):
196
+ pass
197
+
198
+ try:
199
+ loop.run_until_complete(self.start())
200
+ except KeyboardInterrupt:
201
+ self.stop()
202
+ finally:
203
+ loop.close()
@@ -0,0 +1,238 @@
1
+ """TikTokLive client — connect to any TikTok LIVE stream via WebSocket."""
2
+ # ruff: noqa: E402
3
+
4
+ from __future__ import annotations
5
+
6
+ import asyncio
7
+ import json
8
+ import logging
9
+ import os
10
+ import signal
11
+ from typing import Any, Callable, Dict, List, Optional, Union
12
+
13
+ import websockets
14
+ import websockets.client
15
+
16
+ logger = logging.getLogger("tiktok_live_api")
17
+
18
+ EventHandler = Callable[[Dict[str, Any]], None]
19
+ AsyncEventHandler = Callable[[Dict[str, Any]], Any]
20
+ AnyHandler = Union[EventHandler, AsyncEventHandler]
21
+
22
+ WS_BASE = "wss://api.tik.tools"
23
+ _VERSION = "1.0.0"
24
+
25
+
26
+ class TikTokLive:
27
+ """Connect to a TikTok LIVE stream and receive real-time events.
28
+
29
+ Args:
30
+ unique_id: TikTok username (without @).
31
+ api_key: Your TikTool API key. Get one free at https://tik.tools
32
+ auto_reconnect: Auto-reconnect on disconnect (default True).
33
+ max_reconnect_attempts: Max reconnection attempts (default 5).
34
+
35
+ Example::
36
+
37
+ from tiktok_live_api import TikTokLive
38
+
39
+ client = TikTokLive("streamer_username", api_key="YOUR_KEY")
40
+
41
+ @client.on("chat")
42
+ def on_chat(event):
43
+ print(f"{event['user']['uniqueId']}: {event['comment']}")
44
+
45
+ client.run()
46
+ """
47
+
48
+ def __init__(
49
+ self,
50
+ unique_id: str,
51
+ *,
52
+ api_key: Optional[str] = None,
53
+ auto_reconnect: bool = True,
54
+ max_reconnect_attempts: int = 5,
55
+ ) -> None:
56
+ self.unique_id = unique_id.lstrip("@")
57
+ self.api_key = api_key or os.environ.get("TIKTOOL_API_KEY", "")
58
+ if not self.api_key:
59
+ raise ValueError(
60
+ "api_key is required. Get a free key at https://tik.tools"
61
+ )
62
+ self.auto_reconnect = auto_reconnect
63
+ self.max_reconnect_attempts = max_reconnect_attempts
64
+
65
+ self._handlers: Dict[str, List[AnyHandler]] = {}
66
+ self._ws: Optional[websockets.client.WebSocketClientProtocol] = None
67
+ self._loop: Optional[asyncio.AbstractEventLoop] = None
68
+ self._connected = False
69
+ self._intentional_close = False
70
+ self._reconnect_attempts = 0
71
+ self._event_count = 0
72
+
73
+ @property
74
+ def connected(self) -> bool:
75
+ """Whether the client is currently connected."""
76
+ return self._connected
77
+
78
+ @property
79
+ def event_count(self) -> int:
80
+ """Total number of events received."""
81
+ return self._event_count
82
+
83
+ def on(
84
+ self, event: str, handler: Optional[AnyHandler] = None
85
+ ) -> Any:
86
+ """Register an event handler. Can be used as a decorator or called directly.
87
+
88
+ Supported events:
89
+ connected, chat, gift, like, follow, share, member, subscribe,
90
+ roomUserSeq, roomInfo, battle, envelope, streamEnd, error,
91
+ disconnected, event (catch-all)
92
+
93
+ Usage as decorator::
94
+
95
+ @client.on("chat")
96
+ def on_chat(event):
97
+ print(event["comment"])
98
+
99
+ Usage as method::
100
+
101
+ client.on("gift", lambda e: print(e["giftName"]))
102
+ """
103
+ if handler is not None:
104
+ self._handlers.setdefault(event, []).append(handler)
105
+ return handler
106
+
107
+ def decorator(fn: AnyHandler) -> AnyHandler:
108
+ self._handlers.setdefault(event, []).append(fn)
109
+ return fn
110
+
111
+ return decorator
112
+
113
+ def _emit(self, event: str, data: Any = None) -> None:
114
+ for handler in self._handlers.get(event, []):
115
+ try:
116
+ result = handler(data)
117
+ if asyncio.iscoroutine(result):
118
+ loop = self._loop or asyncio.get_event_loop()
119
+ loop.create_task(result)
120
+ except Exception as exc:
121
+ logger.error("Error in '%s' handler: %s", event, exc)
122
+
123
+ async def connect(self) -> None:
124
+ """Connect to the TikTok LIVE stream.
125
+
126
+ For most use cases, prefer :meth:`run` which handles the event loop
127
+ setup automatically. Use ``connect`` directly when integrating with
128
+ an existing async application (FastAPI, aiohttp, etc.)::
129
+
130
+ import asyncio
131
+ from tiktok_live_api import TikTokLive
132
+
133
+ async def main():
134
+ client = TikTokLive("username", api_key="KEY")
135
+ client.on("chat", lambda e: print(e["comment"]))
136
+ await client.connect()
137
+
138
+ asyncio.run(main())
139
+ """
140
+ self._intentional_close = False
141
+ self._loop = asyncio.get_event_loop()
142
+ uri = f"{WS_BASE}?uniqueId={self.unique_id}&apiKey={self.api_key}"
143
+
144
+ try:
145
+ self._ws = await websockets.connect(
146
+ uri,
147
+ additional_headers={"User-Agent": f"tiktok-live-api-python/{_VERSION}"},
148
+ ping_interval=10,
149
+ ping_timeout=30,
150
+ close_timeout=5,
151
+ )
152
+ except Exception as exc:
153
+ self._emit("error", {"error": str(exc)})
154
+ raise
155
+
156
+ self._connected = True
157
+ self._reconnect_attempts = 0
158
+ self._emit("connected", {"uniqueId": self.unique_id})
159
+
160
+ try:
161
+ async for raw in self._ws:
162
+ try:
163
+ event = json.loads(raw)
164
+ except (json.JSONDecodeError, TypeError):
165
+ continue
166
+
167
+ self._event_count += 1
168
+ event_type = event.get("event", "unknown")
169
+ data = event.get("data", event)
170
+
171
+ self._emit("event", event)
172
+ self._emit(event_type, data)
173
+ except websockets.ConnectionClosed:
174
+ pass
175
+ except Exception as exc:
176
+ self._emit("error", {"error": str(exc)})
177
+ finally:
178
+ self._connected = False
179
+ self._emit("disconnected", {"uniqueId": self.unique_id})
180
+
181
+ if (
182
+ not self._intentional_close
183
+ and self.auto_reconnect
184
+ and self._reconnect_attempts < self.max_reconnect_attempts
185
+ ):
186
+ self._reconnect_attempts += 1
187
+ delay = min(2 ** (self._reconnect_attempts - 1), 30)
188
+ logger.info(
189
+ "Reconnecting in %ds (attempt %d/%d)...",
190
+ delay,
191
+ self._reconnect_attempts,
192
+ self.max_reconnect_attempts,
193
+ )
194
+ await asyncio.sleep(delay)
195
+ await self.connect()
196
+
197
+ def disconnect(self) -> None:
198
+ """Disconnect from the stream."""
199
+ self._intentional_close = True
200
+ if self._ws is not None:
201
+ if self._loop is not None and self._loop.is_running():
202
+ self._loop.create_task(self._ws.close())
203
+ else:
204
+ try:
205
+ asyncio.get_event_loop().run_until_complete(self._ws.close())
206
+ except RuntimeError:
207
+ pass
208
+ self._connected = False
209
+
210
+ def run(self) -> None:
211
+ """Connect and block until disconnected.
212
+
213
+ This is the simplest way to use the client. It creates an event loop,
214
+ connects to the stream, and blocks until the stream ends or
215
+ :meth:`disconnect` is called::
216
+
217
+ from tiktok_live_api import TikTokLive
218
+
219
+ client = TikTokLive("streamer", api_key="KEY")
220
+ client.on("chat", lambda e: print(e["comment"]))
221
+ client.run()
222
+ """
223
+ loop = asyncio.new_event_loop()
224
+ asyncio.set_event_loop(loop)
225
+ self._loop = loop
226
+
227
+ for sig in (signal.SIGINT, signal.SIGTERM):
228
+ try:
229
+ loop.add_signal_handler(sig, self.disconnect)
230
+ except (NotImplementedError, ValueError, OSError):
231
+ pass
232
+
233
+ try:
234
+ loop.run_until_complete(self.connect())
235
+ except KeyboardInterrupt:
236
+ self.disconnect()
237
+ finally:
238
+ loop.close()
@@ -0,0 +1 @@
1
+ py_typed
@@ -0,0 +1,113 @@
1
+ """Type definitions for TikTok LIVE API events.
2
+
3
+ These types can be used for IDE autocompletion and type checking
4
+ when handling events from :class:`~tiktok_live_api.TikTokLive` and
5
+ :class:`~tiktok_live_api.TikTokCaptions`.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import sys
11
+ from typing import Any, Dict, List
12
+
13
+ if sys.version_info >= (3, 8):
14
+ from typing import TypedDict
15
+ else:
16
+ from typing_extensions import TypedDict
17
+
18
+ __all__ = [
19
+ "TikTokUser",
20
+ "ChatEvent",
21
+ "GiftEvent",
22
+ "LikeEvent",
23
+ "MemberEvent",
24
+ "SocialEvent",
25
+ "RoomUserSeqEvent",
26
+ "BattleEvent",
27
+ "CaptionEvent",
28
+ "TranslationEvent",
29
+ ]
30
+
31
+
32
+ class TikTokUser(TypedDict, total=False):
33
+ """User profile attached to most LIVE events."""
34
+
35
+ userId: str
36
+ uniqueId: str
37
+ nickname: str
38
+ profilePictureUrl: str
39
+ followRole: int
40
+ isSubscriber: bool
41
+
42
+
43
+ class ChatEvent(TypedDict, total=False):
44
+ """Payload for ``chat`` events."""
45
+
46
+ user: TikTokUser
47
+ comment: str
48
+ emotes: List[Dict[str, Any]]
49
+
50
+
51
+ class GiftEvent(TypedDict, total=False):
52
+ """Payload for ``gift`` events."""
53
+
54
+ user: TikTokUser
55
+ giftId: int
56
+ giftName: str
57
+ diamondCount: int
58
+ repeatCount: int
59
+ repeatEnd: bool
60
+
61
+
62
+ class LikeEvent(TypedDict, total=False):
63
+ """Payload for ``like`` events."""
64
+
65
+ user: TikTokUser
66
+ likeCount: int
67
+ totalLikes: int
68
+
69
+
70
+ class MemberEvent(TypedDict, total=False):
71
+ """Payload for ``member`` (viewer join) events."""
72
+
73
+ user: TikTokUser
74
+ actionId: int
75
+
76
+
77
+ class SocialEvent(TypedDict, total=False):
78
+ """Payload for ``follow`` and ``share`` events."""
79
+
80
+ user: TikTokUser
81
+ eventType: str
82
+
83
+
84
+ class RoomUserSeqEvent(TypedDict, total=False):
85
+ """Payload for ``roomUserSeq`` (viewer count) events."""
86
+
87
+ viewerCount: int
88
+ topViewers: List[TikTokUser]
89
+
90
+
91
+ class BattleEvent(TypedDict, total=False):
92
+ """Payload for ``battle`` events."""
93
+
94
+ type: str
95
+ teams: List[Dict[str, Any]]
96
+ scores: List[int]
97
+
98
+
99
+ class CaptionEvent(TypedDict, total=False):
100
+ """Payload for ``caption`` events from :class:`~tiktok_live_api.TikTokCaptions`."""
101
+
102
+ text: str
103
+ speaker: str
104
+ isFinal: bool
105
+ language: str
106
+
107
+
108
+ class TranslationEvent(TypedDict, total=False):
109
+ """Payload for ``translation`` events from :class:`~tiktok_live_api.TikTokCaptions`."""
110
+
111
+ text: str
112
+ sourceLanguage: str
113
+ targetLanguage: str