tiksync 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.
tiksync-1.0.0/PKG-INFO ADDED
@@ -0,0 +1,125 @@
1
+ Metadata-Version: 2.4
2
+ Name: tiksync
3
+ Version: 1.0.0
4
+ Summary: TikSync — TikTok Live SDK for Python. Real-time chat, gifts, likes & viewer events.
5
+ Home-page: https://tiksync.com
6
+ Author: SyncLive
7
+ Author-email: contact@synclive.fr
8
+ License: MIT
9
+ Project-URL: Documentation, https://tiksync.com/docs
10
+ Project-URL: Source, https://github.com/tiksync/tiksync-python
11
+ Keywords: tiktok,tiktok-live,websocket,api,sdk,gifts,chat
12
+ Classifier: Development Status :: 5 - Production/Stable
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.8
17
+ Classifier: Programming Language :: Python :: 3.9
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Topic :: Software Development :: Libraries
22
+ Requires-Python: >=3.8
23
+ Description-Content-Type: text/markdown
24
+ Requires-Dist: aiohttp>=3.8
25
+ Dynamic: author
26
+ Dynamic: author-email
27
+ Dynamic: classifier
28
+ Dynamic: description
29
+ Dynamic: description-content-type
30
+ Dynamic: home-page
31
+ Dynamic: keywords
32
+ Dynamic: license
33
+ Dynamic: project-url
34
+ Dynamic: requires-dist
35
+ Dynamic: requires-python
36
+ Dynamic: summary
37
+
38
+ # TikSync Python SDK
39
+
40
+ **TikTok Live SDK for Python** — Real-time chat, gifts, likes, follows & viewer events.
41
+
42
+ [![PyPI](https://img.shields.io/pypi/v/tiksync.svg)](https://pypi.org/project/tiksync/)
43
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
44
+
45
+ ```python
46
+ from tiksync import TikSync
47
+
48
+ client = TikSync("username", api_key="your_api_key")
49
+
50
+ @client.on("chat")
51
+ async def on_chat(data):
52
+ print(f"[{data['uniqueId']}] {data['comment']}")
53
+
54
+ @client.on("gift")
55
+ async def on_gift(data):
56
+ print(f"{data['uniqueId']} sent {data['giftName']} x{data['repeatCount']}")
57
+
58
+ await client.connect()
59
+ ```
60
+
61
+ ## Installation
62
+
63
+ ```bash
64
+ pip install tiksync
65
+ ```
66
+
67
+ ## Quick Start
68
+
69
+ ```python
70
+ import asyncio
71
+ from tiksync import TikSync
72
+
73
+ async def main():
74
+ client = TikSync("charlidamelio", api_key="your_api_key")
75
+
76
+ client.on("chat", lambda data: print(f"[{data['uniqueId']}] {data['comment']}"))
77
+ client.on("gift", lambda data: print(f"{data['uniqueId']} sent {data['giftName']}"))
78
+ client.on("like", lambda data: print(f"{data['uniqueId']} liked ({data['totalLikeCount']} total)"))
79
+ client.on("follow", lambda data: print(f"{data['uniqueId']} followed"))
80
+ client.on("member", lambda data: print(f"{data['uniqueId']} joined"))
81
+
82
+ await client.connect()
83
+
84
+ asyncio.run(main())
85
+ ```
86
+
87
+ ## REST API
88
+
89
+ ```python
90
+ from tiksync import TikSyncAPI
91
+
92
+ api = TikSyncAPI(api_key="your_api_key")
93
+ health = await api.health()
94
+ usage = await api.usage()
95
+ signed = await api.sign("username")
96
+ ```
97
+
98
+ ## Events
99
+
100
+ | Event | Description |
101
+ |-------|-------------|
102
+ | `chat` | Chat messages |
103
+ | `gift` | Gift events with diamond values |
104
+ | `like` | Like events |
105
+ | `follow` | New followers |
106
+ | `share` | Stream shares |
107
+ | `member` | User joins |
108
+ | `roomUser` | Viewer count updates |
109
+ | `subscribe` | Subscriptions |
110
+ | `streamEnd` | Stream ended |
111
+ | `connected` | Connected to stream |
112
+ | `disconnected` | Disconnected |
113
+ | `error` | Connection error |
114
+
115
+ ## Get an API Key
116
+
117
+ 1. Go to [tiksync.com](https://tiksync.com)
118
+ 2. Create a free account
119
+ 3. Copy your API key
120
+
121
+ Free tier includes 1,000 requests/day and 10 concurrent WebSocket connections.
122
+
123
+ ## License
124
+
125
+ MIT — built by [SyncLive](https://synclive.fr) | [tiksync.com](https://tiksync.com)
@@ -0,0 +1,88 @@
1
+ # TikSync Python SDK
2
+
3
+ **TikTok Live SDK for Python** — Real-time chat, gifts, likes, follows & viewer events.
4
+
5
+ [![PyPI](https://img.shields.io/pypi/v/tiksync.svg)](https://pypi.org/project/tiksync/)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+
8
+ ```python
9
+ from tiksync import TikSync
10
+
11
+ client = TikSync("username", api_key="your_api_key")
12
+
13
+ @client.on("chat")
14
+ async def on_chat(data):
15
+ print(f"[{data['uniqueId']}] {data['comment']}")
16
+
17
+ @client.on("gift")
18
+ async def on_gift(data):
19
+ print(f"{data['uniqueId']} sent {data['giftName']} x{data['repeatCount']}")
20
+
21
+ await client.connect()
22
+ ```
23
+
24
+ ## Installation
25
+
26
+ ```bash
27
+ pip install tiksync
28
+ ```
29
+
30
+ ## Quick Start
31
+
32
+ ```python
33
+ import asyncio
34
+ from tiksync import TikSync
35
+
36
+ async def main():
37
+ client = TikSync("charlidamelio", api_key="your_api_key")
38
+
39
+ client.on("chat", lambda data: print(f"[{data['uniqueId']}] {data['comment']}"))
40
+ client.on("gift", lambda data: print(f"{data['uniqueId']} sent {data['giftName']}"))
41
+ client.on("like", lambda data: print(f"{data['uniqueId']} liked ({data['totalLikeCount']} total)"))
42
+ client.on("follow", lambda data: print(f"{data['uniqueId']} followed"))
43
+ client.on("member", lambda data: print(f"{data['uniqueId']} joined"))
44
+
45
+ await client.connect()
46
+
47
+ asyncio.run(main())
48
+ ```
49
+
50
+ ## REST API
51
+
52
+ ```python
53
+ from tiksync import TikSyncAPI
54
+
55
+ api = TikSyncAPI(api_key="your_api_key")
56
+ health = await api.health()
57
+ usage = await api.usage()
58
+ signed = await api.sign("username")
59
+ ```
60
+
61
+ ## Events
62
+
63
+ | Event | Description |
64
+ |-------|-------------|
65
+ | `chat` | Chat messages |
66
+ | `gift` | Gift events with diamond values |
67
+ | `like` | Like events |
68
+ | `follow` | New followers |
69
+ | `share` | Stream shares |
70
+ | `member` | User joins |
71
+ | `roomUser` | Viewer count updates |
72
+ | `subscribe` | Subscriptions |
73
+ | `streamEnd` | Stream ended |
74
+ | `connected` | Connected to stream |
75
+ | `disconnected` | Disconnected |
76
+ | `error` | Connection error |
77
+
78
+ ## Get an API Key
79
+
80
+ 1. Go to [tiksync.com](https://tiksync.com)
81
+ 2. Create a free account
82
+ 3. Copy your API key
83
+
84
+ Free tier includes 1,000 requests/day and 10 concurrent WebSocket connections.
85
+
86
+ ## License
87
+
88
+ MIT — built by [SyncLive](https://synclive.fr) | [tiksync.com](https://tiksync.com)
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
tiksync-1.0.0/setup.py ADDED
@@ -0,0 +1,33 @@
1
+ from setuptools import setup, find_packages
2
+
3
+ setup(
4
+ name="tiksync",
5
+ version="1.0.0",
6
+ description="TikSync — TikTok Live SDK for Python. Real-time chat, gifts, likes & viewer events.",
7
+ long_description=open("README.md").read(),
8
+ long_description_content_type="text/markdown",
9
+ author="SyncLive",
10
+ author_email="contact@synclive.fr",
11
+ url="https://tiksync.com",
12
+ project_urls={
13
+ "Documentation": "https://tiksync.com/docs",
14
+ "Source": "https://github.com/tiksync/tiksync-python",
15
+ },
16
+ packages=find_packages(),
17
+ python_requires=">=3.8",
18
+ install_requires=["aiohttp>=3.8"],
19
+ classifiers=[
20
+ "Development Status :: 5 - Production/Stable",
21
+ "Intended Audience :: Developers",
22
+ "License :: OSI Approved :: MIT License",
23
+ "Programming Language :: Python :: 3",
24
+ "Programming Language :: Python :: 3.8",
25
+ "Programming Language :: Python :: 3.9",
26
+ "Programming Language :: Python :: 3.10",
27
+ "Programming Language :: Python :: 3.11",
28
+ "Programming Language :: Python :: 3.12",
29
+ "Topic :: Software Development :: Libraries",
30
+ ],
31
+ keywords=["tiktok", "tiktok-live", "websocket", "api", "sdk", "gifts", "chat"],
32
+ license="MIT",
33
+ )
@@ -0,0 +1,10 @@
1
+ from .client import TikSync, TikSyncAPI
2
+
3
+ __version__ = "1.0.0"
4
+ __all__ = ["TikSync", "TikSyncAPI"]
5
+
6
+ _native = None
7
+ try:
8
+ import tiksync_native as _native
9
+ except ImportError:
10
+ pass
@@ -0,0 +1,159 @@
1
+ import asyncio
2
+ import json
3
+ import logging
4
+ from typing import Callable, Optional
5
+ from urllib.parse import urlencode
6
+
7
+ import aiohttp
8
+
9
+ logger = logging.getLogger("tiksync")
10
+
11
+ API_URL = "https://api.tiksync.com"
12
+
13
+
14
+ class TikSyncAPI:
15
+ def __init__(self, api_key: str, api_url: str = API_URL):
16
+ self.api_key = api_key
17
+ self.api_url = api_url.rstrip("/")
18
+ self._session: Optional[aiohttp.ClientSession] = None
19
+
20
+ async def _get_session(self) -> aiohttp.ClientSession:
21
+ if self._session is None or self._session.closed:
22
+ self._session = aiohttp.ClientSession(
23
+ headers={"x-api-key": self.api_key}
24
+ )
25
+ return self._session
26
+
27
+ async def sign(self, unique_id: str) -> dict:
28
+ session = await self._get_session()
29
+ async with session.post(
30
+ f"{self.api_url}/v1/sign",
31
+ json={"uniqueId": unique_id},
32
+ ) as resp:
33
+ return await resp.json()
34
+
35
+ async def health(self) -> dict:
36
+ session = await self._get_session()
37
+ async with session.get(f"{self.api_url}/v1/health") as resp:
38
+ return await resp.json()
39
+
40
+ async def usage(self) -> dict:
41
+ session = await self._get_session()
42
+ async with session.get(
43
+ f"{self.api_url}/v1/usage",
44
+ ) as resp:
45
+ return await resp.json()
46
+
47
+ async def close(self):
48
+ if self._session and not self._session.closed:
49
+ await self._session.close()
50
+
51
+
52
+ class TikSync:
53
+ def __init__(
54
+ self,
55
+ unique_id: str,
56
+ api_key: str,
57
+ api_url: str = API_URL,
58
+ max_reconnect_attempts: int = 3,
59
+ reconnect_delay: float = 5.0,
60
+ ):
61
+ self.unique_id = unique_id
62
+ self.api_key = api_key
63
+ self.api_url = api_url.rstrip("/")
64
+ self.max_reconnect_attempts = max_reconnect_attempts
65
+ self.reconnect_delay = reconnect_delay
66
+ self._listeners: dict[str, list[Callable]] = {}
67
+ self._ws: Optional[aiohttp.ClientWebSocketResponse] = None
68
+ self._session: Optional[aiohttp.ClientSession] = None
69
+ self._running = False
70
+ self._reconnect_count = 0
71
+ self._native = None
72
+
73
+ try:
74
+ from tiksync import _native
75
+ if _native:
76
+ _native.init(api_key)
77
+ self._native = _native
78
+ except Exception:
79
+ pass
80
+
81
+ def on(self, event: str, callback: Callable):
82
+ self._listeners.setdefault(event, []).append(callback)
83
+ return self
84
+
85
+ def _emit(self, event: str, data=None):
86
+ for cb in self._listeners.get(event, []):
87
+ if asyncio.iscoroutinefunction(cb):
88
+ asyncio.ensure_future(cb(data))
89
+ else:
90
+ cb(data)
91
+
92
+ async def connect(self):
93
+ self._running = True
94
+ self._reconnect_count = 0
95
+ await self._connect_ws()
96
+
97
+ async def _connect_ws(self):
98
+ params = urlencode({"uniqueId": self.unique_id})
99
+ ws_url = self.api_url.replace("https://", "wss://").replace("http://", "ws://")
100
+ url = f"{ws_url}/v1/connect?{params}"
101
+
102
+ headers = {}
103
+ if self.api_key:
104
+ headers["x-api-key"] = self.api_key
105
+ if self._native:
106
+ try:
107
+ sec_headers = self._native.get_connect_headers()
108
+ headers.update(sec_headers)
109
+ except Exception:
110
+ pass
111
+
112
+ self._session = aiohttp.ClientSession()
113
+ try:
114
+ self._ws = await self._session.ws_connect(url, headers=headers)
115
+ self._reconnect_count = 0
116
+ logger.info("Connected to %s", self.unique_id)
117
+ self._emit("connected", {"uniqueId": self.unique_id})
118
+
119
+ async for msg in self._ws:
120
+ if msg.type == aiohttp.WSMsgType.TEXT:
121
+ try:
122
+ event = json.loads(msg.data)
123
+ event_type = event.get("type", "unknown")
124
+ self._emit(event_type, event.get("data", event))
125
+ except json.JSONDecodeError:
126
+ logger.warning("Invalid JSON: %s", msg.data[:100])
127
+ elif msg.type in (aiohttp.WSMsgType.CLOSED, aiohttp.WSMsgType.ERROR):
128
+ break
129
+
130
+ except Exception as e:
131
+ logger.error("Connection error: %s", e)
132
+ self._emit("error", e)
133
+
134
+ finally:
135
+ if self._session and not self._session.closed:
136
+ await self._session.close()
137
+
138
+ if self._running:
139
+ await self._try_reconnect()
140
+
141
+ async def _try_reconnect(self):
142
+ if self._reconnect_count >= self.max_reconnect_attempts:
143
+ logger.error("Max reconnection attempts reached")
144
+ self._emit("disconnected", {"reason": "max_reconnect"})
145
+ return
146
+
147
+ self._reconnect_count += 1
148
+ delay = self.reconnect_delay * self._reconnect_count
149
+ logger.info("Reconnecting in %.1fs (attempt %d/%d)", delay, self._reconnect_count, self.max_reconnect_attempts)
150
+ await asyncio.sleep(delay)
151
+ await self._connect_ws()
152
+
153
+ async def disconnect(self):
154
+ self._running = False
155
+ if self._ws and not self._ws.closed:
156
+ await self._ws.close()
157
+ if self._session and not self._session.closed:
158
+ await self._session.close()
159
+ self._emit("disconnected", {"reason": "manual"})
@@ -0,0 +1,125 @@
1
+ Metadata-Version: 2.4
2
+ Name: tiksync
3
+ Version: 1.0.0
4
+ Summary: TikSync — TikTok Live SDK for Python. Real-time chat, gifts, likes & viewer events.
5
+ Home-page: https://tiksync.com
6
+ Author: SyncLive
7
+ Author-email: contact@synclive.fr
8
+ License: MIT
9
+ Project-URL: Documentation, https://tiksync.com/docs
10
+ Project-URL: Source, https://github.com/tiksync/tiksync-python
11
+ Keywords: tiktok,tiktok-live,websocket,api,sdk,gifts,chat
12
+ Classifier: Development Status :: 5 - Production/Stable
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.8
17
+ Classifier: Programming Language :: Python :: 3.9
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Topic :: Software Development :: Libraries
22
+ Requires-Python: >=3.8
23
+ Description-Content-Type: text/markdown
24
+ Requires-Dist: aiohttp>=3.8
25
+ Dynamic: author
26
+ Dynamic: author-email
27
+ Dynamic: classifier
28
+ Dynamic: description
29
+ Dynamic: description-content-type
30
+ Dynamic: home-page
31
+ Dynamic: keywords
32
+ Dynamic: license
33
+ Dynamic: project-url
34
+ Dynamic: requires-dist
35
+ Dynamic: requires-python
36
+ Dynamic: summary
37
+
38
+ # TikSync Python SDK
39
+
40
+ **TikTok Live SDK for Python** — Real-time chat, gifts, likes, follows & viewer events.
41
+
42
+ [![PyPI](https://img.shields.io/pypi/v/tiksync.svg)](https://pypi.org/project/tiksync/)
43
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
44
+
45
+ ```python
46
+ from tiksync import TikSync
47
+
48
+ client = TikSync("username", api_key="your_api_key")
49
+
50
+ @client.on("chat")
51
+ async def on_chat(data):
52
+ print(f"[{data['uniqueId']}] {data['comment']}")
53
+
54
+ @client.on("gift")
55
+ async def on_gift(data):
56
+ print(f"{data['uniqueId']} sent {data['giftName']} x{data['repeatCount']}")
57
+
58
+ await client.connect()
59
+ ```
60
+
61
+ ## Installation
62
+
63
+ ```bash
64
+ pip install tiksync
65
+ ```
66
+
67
+ ## Quick Start
68
+
69
+ ```python
70
+ import asyncio
71
+ from tiksync import TikSync
72
+
73
+ async def main():
74
+ client = TikSync("charlidamelio", api_key="your_api_key")
75
+
76
+ client.on("chat", lambda data: print(f"[{data['uniqueId']}] {data['comment']}"))
77
+ client.on("gift", lambda data: print(f"{data['uniqueId']} sent {data['giftName']}"))
78
+ client.on("like", lambda data: print(f"{data['uniqueId']} liked ({data['totalLikeCount']} total)"))
79
+ client.on("follow", lambda data: print(f"{data['uniqueId']} followed"))
80
+ client.on("member", lambda data: print(f"{data['uniqueId']} joined"))
81
+
82
+ await client.connect()
83
+
84
+ asyncio.run(main())
85
+ ```
86
+
87
+ ## REST API
88
+
89
+ ```python
90
+ from tiksync import TikSyncAPI
91
+
92
+ api = TikSyncAPI(api_key="your_api_key")
93
+ health = await api.health()
94
+ usage = await api.usage()
95
+ signed = await api.sign("username")
96
+ ```
97
+
98
+ ## Events
99
+
100
+ | Event | Description |
101
+ |-------|-------------|
102
+ | `chat` | Chat messages |
103
+ | `gift` | Gift events with diamond values |
104
+ | `like` | Like events |
105
+ | `follow` | New followers |
106
+ | `share` | Stream shares |
107
+ | `member` | User joins |
108
+ | `roomUser` | Viewer count updates |
109
+ | `subscribe` | Subscriptions |
110
+ | `streamEnd` | Stream ended |
111
+ | `connected` | Connected to stream |
112
+ | `disconnected` | Disconnected |
113
+ | `error` | Connection error |
114
+
115
+ ## Get an API Key
116
+
117
+ 1. Go to [tiksync.com](https://tiksync.com)
118
+ 2. Create a free account
119
+ 3. Copy your API key
120
+
121
+ Free tier includes 1,000 requests/day and 10 concurrent WebSocket connections.
122
+
123
+ ## License
124
+
125
+ MIT — built by [SyncLive](https://synclive.fr) | [tiksync.com](https://tiksync.com)
@@ -0,0 +1,9 @@
1
+ README.md
2
+ setup.py
3
+ tiksync/__init__.py
4
+ tiksync/client.py
5
+ tiksync.egg-info/PKG-INFO
6
+ tiksync.egg-info/SOURCES.txt
7
+ tiksync.egg-info/dependency_links.txt
8
+ tiksync.egg-info/requires.txt
9
+ tiksync.egg-info/top_level.txt
@@ -0,0 +1 @@
1
+ aiohttp>=3.8
@@ -0,0 +1 @@
1
+ tiksync