piratetok-live-py
Connect to any TikTok Live stream and receive real-time events in Python. No signing server, no API keys, no authentication required.
import asyncio
from piratetok_live import TikTokLiveClient, EventType
async def main():
# Create client — no API key, no signing server, just a username
client = TikTokLiveClient("username_here")
# Register handlers with decorators — events carry decoded protobuf data
@client.on(EventType.chat)
def on_chat(evt):
nick = evt.data.get("user", {}).get("nickname", "?")
print(f"[chat] {nick}: {evt.data.get('content')}")
@client.on(EventType.gift)
def on_gift(evt):
nick = evt.data.get("user", {}).get("nickname", "?")
gift = evt.data.get("gift", {})
print(f"[gift] {nick} sent {gift.get('name')} x{evt.data.get('repeatCount')} ({gift.get('diamondCount', 0)} diamonds)")
@client.on(EventType.like)
def on_like(evt):
nick = evt.data.get("user", {}).get("nickname", "?")
print(f"[like] {nick} ({evt.data.get('total')} total)")
# Runs the whole session — auth, room resolution, WSS, heartbeat, reconnection.
# Returns after client.disconnect() or once max_retries consecutive attempts failed.
# Need to do other work meanwhile? asyncio.create_task(client.connect())
await client.connect()
asyncio.run(main())
Install
pip install piratetok-live-py
Requires Python >= 3.11.
Other languages
| Language | Install | Repo |
|---|---|---|
| Rust | cargo add piratetok-live-rs |
live-rs |
| Go | go get github.com/PirateTok/live-go |
live-go |
| JavaScript | npm install piratetok-live-js |
live-js |
| C# | dotnet add package PirateTok.Live |
live-cs |
| Java | com.piratetok:live |
live-java |
| Lua | luarocks install piratetok-live-lua |
live-lua |
| Elixir | {:piratetok_live, "~> 0.1"} |
live-ex |
| Dart | dart pub add piratetok_live |
live-dart |
| C | #include "piratetok.h" |
live-c |
| PowerShell | Install-Module PirateTok.Live |
live-ps1 |
| Shell | bpkg install PirateTok/live-sh |
live-sh |
Features
- Zero signing dependency — no API keys, no signing server, no external auth
- 64 decoded event types — hand-written betterproto dataclasses, no codegen
- Auto-reconnection — stale detection, exponential backoff, ttwid retry + reuse, rotation on DEVICE_BLOCKED, retry budget resets after a healthy (30 s+) session
- Proxy support —
.proxy(url)builder, HTTP/HTTPS/SOCKS5 for both HTTP and WSS - Enriched User data — badges, gifter level, moderator status, follow info, fan club
- Sub-routed convenience events —
follow,share,join,live_ended - Gift helpers —
is_combo,is_streak_over,diamond_totalon every gift event - Runtime deps —
betterproto,websockets,curl_cffi,python-socks
Configuration
client = (TikTokLiveClient("username_here")
.cdn_eu()
.timeout(15)
.max_retries(10)
.stale_timeout(90)
.heartbeat_interval(10)
.proxy("socks5://127.0.0.1:1080")
.user_agent("Mozilla/5.0 ...")
.cookies("sessionid=abc; sid_tt=abc")
.language("pt")
.region("BR")
.compress(False))
| Method | Default | Description |
|---|---|---|
.cdn_eu() / .cdn_us() / .cdn(host) |
Global CDN | WebSocket CDN endpoint |
.timeout(seconds) |
10 |
HTTP request timeout in seconds |
.max_retries(n) |
5 |
Consecutive failed reconnects before giving up (a 30 s+ session resets the count) |
.stale_timeout(seconds) |
60 |
Seconds without data before triggering a reconnect |
.heartbeat_interval(seconds) |
10 |
WSS heartbeat interval (also sent as heartbeat_duration) |
.proxy(url) |
None | HTTP/HTTPS/SOCKS5 proxy for all HTTP + WSS traffic |
.user_agent(ua) |
Random from pool | Override the user agent (rotated automatically on reconnect by default) |
.cookies(cookies) |
None | Append session cookies alongside ttwid in the WSS cookie header |
.language(lang) |
System detected | Override the language sent in WSS params (e.g. "pt", "ro") |
.region(reg) |
System detected | Override the region sent in WSS params (e.g. "BR", "RO") |
.compress(enabled) |
True |
Disable gzip compression for WSS payloads (trades bandwidth for CPU) |
Room info (optional, separate call)
from piratetok_live import check_online, fetch_room_info
result = check_online("username_here")
info = fetch_room_info(result.room_id)
# 18+ rooms
info = fetch_room_info(result.room_id, cookies="sessionid=abc; sid_tt=abc")
Viewers
The top-viewers box (usually top 3) rides the WSS feed — no cookies:
from piratetok_live import top_viewers
@client.on(EventType.room_user_seq)
def on_seq(evt):
for c in top_viewers(evt.data):
print(c["rank"], c["user"].get("nickname"), c["score"])
The full roster (the web viewer panel) is a separate HTTP call. TikTok requires session
cookies for this one call — without them it raises SessionRequiredError:
from piratetok_live import check_online, fetch_room_audience
room = check_online("username_here")
audience = fetch_room_audience(room.room_id, room.anchor_id, cookies="sessionid=abc; sid_tt=abc")
# audience.total, audience.anonymous, audience.viewers[i].username / nickname / rank / ...
Pass anchor_id=None to resolve it from room info (one extra request).
Examples
python examples/basic_chat.py <username> # connect + print chat events
python examples/online_check.py <username> # check if user is live
python examples/stream_info.py <username> # fetch room metadata + stream URLs
python examples/gift_tracker.py <username> # track gifts with diamond totals
python examples/gift_streak.py <username> # track gifts with GiftStreakTracker deltas
python examples/profile_lookup.py [username] # fetch profile via SIGI scrape with caching
python examples/audience.py <username> <cookies> # full viewer roster (needs session cookies)
Tests
pip install -e ".[test]"
pytest -m "not integration" # offline: replay, ttwid retry, reconnect loop, WSS, proxy, parsing
Replay tests read testdata/ (gitignored, captures/*.bin + manifests/*.json) or a
live-testdata checkout:
git clone https://github.com/PirateTok/live-testdata ../live-testdata
PIRATETOK_TESTDATA=../live-testdata pytest tests/test_replay.py
Missing testdata fails the replay tests — they never pass vacuously.
License
0BSD
Metadata
Release files for piratetok-live-py 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| piratetok_live_py-0.3.0.tar.gz | 54.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| piratetok_live_py-0.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 97.5 kB
Release files / piratetok_live_py-0.3.0.tar.gz
| Download URL | piratetok_live_py-0.3.0.tar.gz |
|---|---|
| Size | 54.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
038ac76268ee0f99a2e7ba2ad939cb7c80cf21a870037575bcc4f91d3ad71ec8
|
|
BLAKE2b-256 checksum How to use checksums |
59408520c3e569f277f60055648f331c90a6a3a71bae74f134560ff043e4e2d9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.7
|
Release files / piratetok_live_py-0.3.0-py3-none-any.whl
| Download URL | piratetok_live_py-0.3.0-py3-none-any.whl |
|---|---|
| Size | 42.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
171ee3f7ffb33b7b8d2b72691b9d26825d31f392c4dfebbb17b3b2772461a6c6
|
|
BLAKE2b-256 checksum How to use checksums |
68f9fe3f64526df3be5d68ca80256e9d6e50e4a21d36b3e46ca502003d98ff19
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.7
|