chzzk-python 0.1.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.
Files changed (66) hide show
  1. chzzk_python-0.1.0/.github/workflows/ci.yml +58 -0
  2. chzzk_python-0.1.0/.github/workflows/publish.yml +69 -0
  3. chzzk_python-0.1.0/.github/workflows/release.yml +32 -0
  4. chzzk_python-0.1.0/.gitignore +41 -0
  5. chzzk_python-0.1.0/.python-version +1 -0
  6. chzzk_python-0.1.0/CHANGELOG.md +62 -0
  7. chzzk_python-0.1.0/LICENSE +21 -0
  8. chzzk_python-0.1.0/PKG-INFO +314 -0
  9. chzzk_python-0.1.0/README.md +284 -0
  10. chzzk_python-0.1.0/README_KO.md +284 -0
  11. chzzk_python-0.1.0/cliff.toml +49 -0
  12. chzzk_python-0.1.0/examples/.env.example +8 -0
  13. chzzk_python-0.1.0/examples/oauth_server.py +474 -0
  14. chzzk_python-0.1.0/examples/realtime_chat.py +127 -0
  15. chzzk_python-0.1.0/examples/realtime_chat_async.py +124 -0
  16. chzzk_python-0.1.0/examples/session_management.py +126 -0
  17. chzzk_python-0.1.0/main.py +6 -0
  18. chzzk_python-0.1.0/pyproject.toml +86 -0
  19. chzzk_python-0.1.0/src/chzzk/__init__.py +175 -0
  20. chzzk_python-0.1.0/src/chzzk/_version.py +34 -0
  21. chzzk_python-0.1.0/src/chzzk/api/__init__.py +29 -0
  22. chzzk_python-0.1.0/src/chzzk/api/base.py +147 -0
  23. chzzk_python-0.1.0/src/chzzk/api/category.py +65 -0
  24. chzzk_python-0.1.0/src/chzzk/api/channel.py +218 -0
  25. chzzk_python-0.1.0/src/chzzk/api/chat.py +239 -0
  26. chzzk_python-0.1.0/src/chzzk/api/live.py +212 -0
  27. chzzk_python-0.1.0/src/chzzk/api/restriction.py +147 -0
  28. chzzk_python-0.1.0/src/chzzk/api/session.py +389 -0
  29. chzzk_python-0.1.0/src/chzzk/api/user.py +47 -0
  30. chzzk_python-0.1.0/src/chzzk/auth/__init__.py +34 -0
  31. chzzk_python-0.1.0/src/chzzk/auth/models.py +115 -0
  32. chzzk_python-0.1.0/src/chzzk/auth/oauth.py +452 -0
  33. chzzk_python-0.1.0/src/chzzk/auth/token.py +119 -0
  34. chzzk_python-0.1.0/src/chzzk/client.py +515 -0
  35. chzzk_python-0.1.0/src/chzzk/exceptions/__init__.py +37 -0
  36. chzzk_python-0.1.0/src/chzzk/exceptions/errors.py +130 -0
  37. chzzk_python-0.1.0/src/chzzk/http/__init__.py +68 -0
  38. chzzk_python-0.1.0/src/chzzk/http/client.py +310 -0
  39. chzzk_python-0.1.0/src/chzzk/http/endpoints.py +52 -0
  40. chzzk_python-0.1.0/src/chzzk/models/__init__.py +86 -0
  41. chzzk_python-0.1.0/src/chzzk/models/category.py +18 -0
  42. chzzk_python-0.1.0/src/chzzk/models/channel.py +69 -0
  43. chzzk_python-0.1.0/src/chzzk/models/chat.py +63 -0
  44. chzzk_python-0.1.0/src/chzzk/models/common.py +23 -0
  45. chzzk_python-0.1.0/src/chzzk/models/live.py +78 -0
  46. chzzk_python-0.1.0/src/chzzk/models/restriction.py +18 -0
  47. chzzk_python-0.1.0/src/chzzk/models/session.py +161 -0
  48. chzzk_python-0.1.0/src/chzzk/models/user.py +14 -0
  49. chzzk_python-0.1.0/src/chzzk/py.typed +0 -0
  50. chzzk_python-0.1.0/src/chzzk/realtime/__init__.py +8 -0
  51. chzzk_python-0.1.0/src/chzzk/realtime/client.py +635 -0
  52. chzzk_python-0.1.0/tests/__init__.py +1 -0
  53. chzzk_python-0.1.0/tests/api/__init__.py +1 -0
  54. chzzk_python-0.1.0/tests/api/test_category.py +146 -0
  55. chzzk_python-0.1.0/tests/api/test_channel.py +214 -0
  56. chzzk_python-0.1.0/tests/api/test_chat.py +199 -0
  57. chzzk_python-0.1.0/tests/api/test_live.py +199 -0
  58. chzzk_python-0.1.0/tests/api/test_restriction.py +177 -0
  59. chzzk_python-0.1.0/tests/api/test_session.py +368 -0
  60. chzzk_python-0.1.0/tests/api/test_user.py +112 -0
  61. chzzk_python-0.1.0/tests/auth/__init__.py +1 -0
  62. chzzk_python-0.1.0/tests/auth/test_oauth.py +475 -0
  63. chzzk_python-0.1.0/tests/realtime/__init__.py +1 -0
  64. chzzk_python-0.1.0/tests/realtime/test_client.py +312 -0
  65. chzzk_python-0.1.0/tests/test_client.py +428 -0
  66. chzzk_python-0.1.0/uv.lock +1057 -0
@@ -0,0 +1,58 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ lint:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - uses: actions/checkout@v6
14
+
15
+ - name: Install uv
16
+ uses: astral-sh/setup-uv@v7
17
+ with:
18
+ version: "latest"
19
+
20
+ - name: Set up Python
21
+ uses: actions/setup-python@v6
22
+ with:
23
+ python-version: "3.12"
24
+
25
+ - name: Install dependencies
26
+ run: uv sync --dev
27
+
28
+ - name: Run ruff format check
29
+ run: uv run ruff format --check .
30
+
31
+ - name: Run ruff lint
32
+ run: uv run ruff check .
33
+
34
+ test:
35
+ runs-on: ubuntu-latest
36
+ strategy:
37
+ fail-fast: false
38
+ matrix:
39
+ python-version: ["3.12", "3.13"]
40
+
41
+ steps:
42
+ - uses: actions/checkout@v6
43
+
44
+ - name: Install uv
45
+ uses: astral-sh/setup-uv@v7
46
+ with:
47
+ version: "latest"
48
+
49
+ - name: Set up Python ${{ matrix.python-version }}
50
+ uses: actions/setup-python@v6
51
+ with:
52
+ python-version: ${{ matrix.python-version }}
53
+
54
+ - name: Install dependencies
55
+ run: uv sync --dev
56
+
57
+ - name: Run tests
58
+ run: uv run pytest -v
@@ -0,0 +1,69 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - 'v*'
7
+
8
+ jobs:
9
+ build:
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - uses: actions/checkout@v6
13
+
14
+ - name: Install uv
15
+ uses: astral-sh/setup-uv@v7
16
+ with:
17
+ version: "latest"
18
+
19
+ - name: Set up Python
20
+ uses: actions/setup-python@v6
21
+ with:
22
+ python-version: "3.12"
23
+
24
+ - name: Build package
25
+ run: uv build
26
+
27
+ - name: Upload artifacts
28
+ uses: actions/upload-artifact@v4
29
+ with:
30
+ name: dist
31
+ path: dist/
32
+
33
+ publish-testpypi:
34
+ needs: build
35
+ runs-on: ubuntu-latest
36
+ environment:
37
+ name: testpypi
38
+ url: https://test.pypi.org/p/chzzk-python
39
+ permissions:
40
+ id-token: write
41
+ steps:
42
+ - name: Download artifacts
43
+ uses: actions/download-artifact@v4
44
+ with:
45
+ name: dist
46
+ path: dist/
47
+
48
+ - name: Publish to TestPyPI
49
+ uses: pypa/gh-action-pypi-publish@release/v1
50
+ with:
51
+ repository-url: https://test.pypi.org/legacy/
52
+
53
+ publish-pypi:
54
+ needs: publish-testpypi
55
+ runs-on: ubuntu-latest
56
+ environment:
57
+ name: pypi
58
+ url: https://pypi.org/p/chzzk-python
59
+ permissions:
60
+ id-token: write
61
+ steps:
62
+ - name: Download artifacts
63
+ uses: actions/download-artifact@v4
64
+ with:
65
+ name: dist
66
+ path: dist/
67
+
68
+ - name: Publish to PyPI
69
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,32 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - 'v*'
7
+
8
+ permissions:
9
+ contents: write
10
+
11
+ jobs:
12
+ release:
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - uses: actions/checkout@v6
16
+ with:
17
+ fetch-depth: 0
18
+
19
+ - name: Generate changelog
20
+ uses: orhun/git-cliff-action@v4
21
+ id: cliff
22
+ with:
23
+ config: cliff.toml
24
+ args: --current --strip header
25
+ env:
26
+ OUTPUT: CHANGES.md
27
+
28
+ - name: Create GitHub Release
29
+ uses: softprops/action-gh-release@v2
30
+ with:
31
+ body_path: CHANGES.md
32
+ generate_release_notes: false
@@ -0,0 +1,41 @@
1
+ # Python-generated files
2
+ __pycache__/
3
+ *.py[oc]
4
+ build/
5
+ dist/
6
+ wheels/
7
+ *.egg-info
8
+
9
+ # Version file (auto-generated by hatch-vcs)
10
+ src/chzzk/_version.py
11
+
12
+ # Virtual environments
13
+ .venv
14
+
15
+ # Environment variables (keep .env.example)
16
+ .env
17
+ examples/.env
18
+
19
+ # Token storage
20
+ .chzzk_token.json
21
+ *_token.json
22
+
23
+ # Testing & Linting
24
+ .pytest_cache/
25
+ .ruff_cache/
26
+ .coverage
27
+ htmlcov/
28
+
29
+ # IDE
30
+ .idea/
31
+ .vscode/
32
+ *.swp
33
+ *.swo
34
+
35
+ # OS
36
+ .DS_Store
37
+
38
+ # AI tooling
39
+ .mcp.json
40
+ CLAUDE.md
41
+ .claude/
@@ -0,0 +1 @@
1
+ 3.14
@@ -0,0 +1,62 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ### Added
11
+
12
+ - **exceptions**: Add custom exception classes for Chzzk SDK
13
+ - **http**: Add HTTP client wrapper for Chzzk API
14
+ - **auth**: Add OAuth authentication models
15
+ - **auth**: Add token storage implementations
16
+ - **auth**: Add OAuth client implementations
17
+ - **examples**: Add OAuth authorization code flow example
18
+ - **examples**: Enhance OAuth server with ChzzkClient and API demos
19
+ - **http**: Add PUT, PATCH, and DELETE methods to HTTP clients
20
+ - **http**: Add Open API endpoint constants
21
+ - **models**: Add Pydantic models for Chzzk API responses
22
+ - **api**: Implement service layer for Chzzk Open API
23
+ - **client**: Add unified Chzzk API client
24
+ - Export client, services, and models from package root
25
+ - **http**: Add params support to POST methods
26
+ - **models**: Add session and realtime event models
27
+ - **http**: Add session API endpoints
28
+ - **exceptions**: Add session-related exceptions
29
+ - **api**: Implement session service for WebSocket management
30
+ - **realtime**: Add Socket.IO client for realtime events
31
+ - **client**: Integrate session service and event client
32
+ - Export session, realtime, and related components
33
+ - **examples**: Add session list endpoint to OAuth server
34
+ - **examples**: Add realtime and session management examples
35
+
36
+ ### Build
37
+
38
+ - Add python-socketio dependency for realtime events
39
+ - Add websocket-client dependency
40
+ - Exclude AI tooling files from git and distribution
41
+
42
+ ### Changed
43
+
44
+ - **auth**: Remove get_access_token method from OAuth classes
45
+
46
+ ### Documentation
47
+
48
+ - Add comprehensive SDK documentation
49
+
50
+ ### Fixed
51
+
52
+ - **http**: Extract content field from Chzzk API response wrapper
53
+ - **realtime**: Handle string and dict event data from Socket.IO
54
+ - **models**: Make user_role_code optional in ChatEvent
55
+
56
+ ### Testing
57
+
58
+ - **auth**: Add comprehensive OAuth test suite
59
+ - Add comprehensive test suite for API services and client
60
+ - Add tests for session service and realtime client
61
+
62
+ [Unreleased]: https://github.com/hypn4/chzzk-python/compare/...HEAD
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 hypn4
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,314 @@
1
+ Metadata-Version: 2.4
2
+ Name: chzzk-python
3
+ Version: 0.1.0
4
+ Summary: Unofficial Python SDK for Chzzk (NAVER Live Streaming Platform) API
5
+ Project-URL: Homepage, https://github.com/hypn4/chzzk-python
6
+ Project-URL: Repository, https://github.com/hypn4/chzzk-python
7
+ Project-URL: Documentation, https://github.com/hypn4/chzzk-python#readme
8
+ Project-URL: Bug Tracker, https://github.com/hypn4/chzzk-python/issues
9
+ Project-URL: Changelog, https://github.com/hypn4/chzzk-python/blob/main/CHANGELOG.md
10
+ Author: hypn4
11
+ License: MIT
12
+ License-File: LICENSE
13
+ Keywords: api,chat,chzzk,korean,live-streaming,naver,sdk,streaming,websocket
14
+ Classifier: Development Status :: 4 - Beta
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.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.12
25
+ Requires-Dist: httpx>=0.28.0
26
+ Requires-Dist: pydantic>=2.10.0
27
+ Requires-Dist: python-socketio[asyncio-client]<5.0.0,>=4.6.0
28
+ Requires-Dist: websocket-client>=1.9.0
29
+ Description-Content-Type: text/markdown
30
+
31
+ # chzzk-python
32
+
33
+ [![Python 3.12+](https://img.shields.io/badge/python-3.12+-blue.svg)](https://www.python.org/downloads/)
34
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
35
+
36
+ Unofficial Python SDK for Chzzk (NAVER Live Streaming Platform) API
37
+
38
+ [한국어](README_KO.md)
39
+
40
+ ## Installation
41
+
42
+ ```bash
43
+ # Using uv (recommended)
44
+ uv add chzzk-python
45
+
46
+ # Using pip
47
+ pip install chzzk-python
48
+ ```
49
+
50
+ ## Quick Start
51
+
52
+ ```python
53
+ from chzzk import ChzzkClient, FileTokenStorage
54
+
55
+ # Create client with OAuth support
56
+ client = ChzzkClient(
57
+ client_id="your-client-id",
58
+ client_secret="your-client-secret",
59
+ redirect_uri="http://localhost:8080/callback",
60
+ token_storage=FileTokenStorage("token.json"),
61
+ )
62
+
63
+ # Generate authorization URL
64
+ auth_url, state = client.get_authorization_url()
65
+ # User visits auth_url and authorizes the app
66
+
67
+ # Exchange code for token (after OAuth callback)
68
+ token = client.authenticate(code="auth-code", state=state)
69
+
70
+ # Use the API
71
+ user = client.user.get_me()
72
+ print(f"Channel: {user.channel_name}")
73
+ ```
74
+
75
+ ## API Categories & Implementation Status
76
+
77
+ | Category | Status | Description |
78
+ |----------|--------|-------------|
79
+ | **Authorization** | ✅ Implemented | OAuth 2.0, Token issue/refresh/revoke |
80
+ | **User** | ✅ Implemented | Get logged-in user info |
81
+ | **Channel** | ✅ Implemented | Channel info, managers, followers, subscribers |
82
+ | **Category** | ✅ Implemented | Category search |
83
+ | **Live** | ✅ Implemented | Live list, stream key, broadcast settings |
84
+ | **Chat** | ✅ Implemented | Send messages, announcements, chat settings |
85
+ | **Session** | ✅ Implemented | Session create/list, event subscription |
86
+ | **Restriction** | ✅ Implemented | Activity restriction list management |
87
+ | **Drops** | ❌ Not Implemented | - |
88
+ | **Webhook Event** | ❌ Not Implemented | - |
89
+
90
+ ## Features
91
+
92
+ ### Sync/Async Support
93
+
94
+ Both synchronous and asynchronous clients are available:
95
+
96
+ ```python
97
+ # Synchronous
98
+ from chzzk import ChzzkClient
99
+
100
+ with ChzzkClient(client_id="...", client_secret="...") as client:
101
+ user = client.user.get_me()
102
+
103
+ # Asynchronous
104
+ from chzzk import AsyncChzzkClient
105
+
106
+ async with AsyncChzzkClient(client_id="...", client_secret="...") as client:
107
+ user = await client.user.get_me()
108
+ ```
109
+
110
+ ### Token Storage
111
+
112
+ Multiple token storage options:
113
+
114
+ ```python
115
+ from chzzk import InMemoryTokenStorage, FileTokenStorage, CallbackTokenStorage
116
+
117
+ # In-memory (default)
118
+ storage = InMemoryTokenStorage()
119
+
120
+ # File-based persistence
121
+ storage = FileTokenStorage("token.json")
122
+
123
+ # Custom callback
124
+ storage = CallbackTokenStorage(
125
+ get_callback=lambda: load_from_db(),
126
+ save_callback=lambda token: save_to_db(token),
127
+ delete_callback=lambda: delete_from_db(),
128
+ )
129
+ ```
130
+
131
+ ### Realtime Events
132
+
133
+ Receive chat, donation, and subscription events in realtime:
134
+
135
+ ```python
136
+ from chzzk import ChzzkClient, ChatEvent, DonationEvent, SubscriptionEvent
137
+
138
+ client = ChzzkClient(...)
139
+ event_client = client.create_event_client()
140
+
141
+ @event_client.on_chat
142
+ def on_chat(event: ChatEvent):
143
+ print(f"{event.profile.nickname}: {event.content}")
144
+
145
+ @event_client.on_donation
146
+ def on_donation(event: DonationEvent):
147
+ print(f"{event.donator_nickname} donated {event.pay_amount}won")
148
+
149
+ @event_client.on_subscription
150
+ def on_subscription(event: SubscriptionEvent):
151
+ print(f"{event.subscriber_nickname} subscribed!")
152
+
153
+ # Connect and subscribe
154
+ event_client.connect()
155
+ event_client.subscribe_chat()
156
+ event_client.subscribe_donation()
157
+ event_client.subscribe_subscription()
158
+ event_client.run_forever()
159
+ ```
160
+
161
+ ## Usage Examples
162
+
163
+ ### OAuth Authentication Flow
164
+
165
+ ```python
166
+ from chzzk import ChzzkClient, FileTokenStorage
167
+
168
+ client = ChzzkClient(
169
+ client_id="your-client-id",
170
+ client_secret="your-client-secret",
171
+ redirect_uri="http://localhost:8080/callback",
172
+ token_storage=FileTokenStorage("token.json"),
173
+ auto_refresh=True, # Automatically refresh expired tokens
174
+ )
175
+
176
+ # 1. Generate authorization URL
177
+ auth_url, state = client.get_authorization_url()
178
+ print(f"Visit: {auth_url}")
179
+
180
+ # 2. After user authorizes, exchange code for token
181
+ token = client.authenticate(code="received-code", state=state)
182
+
183
+ # 3. Refresh token manually if needed
184
+ new_token = client.refresh_token()
185
+
186
+ # 4. Revoke token on logout
187
+ client.revoke_token()
188
+ ```
189
+
190
+ ### Channel & Live Information
191
+
192
+ ```python
193
+ # Get channel info
194
+ channel = client.channel.get_channel("channel-id")
195
+ print(f"Channel: {channel.channel_name}")
196
+ print(f"Description: {channel.channel_description}")
197
+
198
+ # Get followers
199
+ followers = client.channel.get_followers(size=20)
200
+ for follower in followers.data:
201
+ print(f"Follower: {follower.nickname}")
202
+
203
+ # Get live broadcasts
204
+ lives = client.live.get_lives(size=10)
205
+ for live in lives.data:
206
+ print(f"{live.channel_name}: {live.live_title} ({live.concurrent_user_count} viewers)")
207
+
208
+ # Get/Update live settings
209
+ setting = client.live.get_setting()
210
+ client.live.update_setting(default_live_title="My Stream Title")
211
+ ```
212
+
213
+ ### Chat Messages
214
+
215
+ ```python
216
+ # Send chat message
217
+ client.chat.send_message(channel_id="channel-id", message="Hello!")
218
+
219
+ # Set chat announcement
220
+ client.chat.set_notice(
221
+ channel_id="channel-id",
222
+ message="Welcome to the stream!",
223
+ )
224
+
225
+ # Get/Update chat settings
226
+ settings = client.chat.get_settings(channel_id="channel-id")
227
+ client.chat.update_settings(
228
+ channel_id="channel-id",
229
+ chat_available_group="FOLLOWER",
230
+ )
231
+ ```
232
+
233
+ ### Async Example
234
+
235
+ ```python
236
+ import asyncio
237
+ from chzzk import AsyncChzzkClient, FileTokenStorage
238
+
239
+ async def main():
240
+ async with AsyncChzzkClient(
241
+ client_id="your-client-id",
242
+ client_secret="your-client-secret",
243
+ redirect_uri="http://localhost:8080/callback",
244
+ token_storage=FileTokenStorage("token.json"),
245
+ ) as client:
246
+ # Get user info
247
+ user = await client.user.get_me()
248
+ print(f"Channel: {user.channel_name}")
249
+
250
+ # Get live broadcasts
251
+ lives = await client.live.get_lives(size=10)
252
+ for live in lives.data:
253
+ print(f"{live.channel_name}: {live.live_title}")
254
+
255
+ asyncio.run(main())
256
+ ```
257
+
258
+ ## Exception Handling
259
+
260
+ ```python
261
+ from chzzk import (
262
+ ChzzkError, # Base exception
263
+ ChzzkAPIError, # API error response
264
+ AuthenticationError, # 401 errors
265
+ InvalidTokenError, # Invalid/expired token
266
+ InvalidClientError, # Invalid client credentials
267
+ ForbiddenError, # 403 errors
268
+ NotFoundError, # 404 errors
269
+ RateLimitError, # 429 errors
270
+ ServerError, # 5xx errors
271
+ TokenExpiredError, # Token expired, need re-auth
272
+ InvalidStateError, # OAuth state mismatch
273
+ SessionError, # Session-related errors
274
+ SessionConnectionError, # Socket.IO connection failed
275
+ SessionLimitExceededError, # Max session limit exceeded
276
+ EventSubscriptionError, # Event subscription failed
277
+ )
278
+
279
+ try:
280
+ user = client.user.get_me()
281
+ except InvalidTokenError:
282
+ # Token is invalid or expired
283
+ token = client.refresh_token()
284
+ except RateLimitError:
285
+ # Rate limit exceeded, wait and retry
286
+ time.sleep(60)
287
+ except ChzzkAPIError as e:
288
+ print(f"API Error: [{e.status_code}] {e.error_code}: {e.message}")
289
+ ```
290
+
291
+ ## Examples
292
+
293
+ See the [examples](examples/) directory for complete working examples:
294
+
295
+ - `oauth_server.py` - OAuth authentication with Flask
296
+ - `realtime_chat.py` - Realtime chat/donation/subscription events (sync)
297
+ - `realtime_chat_async.py` - Realtime events (async)
298
+ - `session_management.py` - Session management example
299
+
300
+ ## API Reference
301
+
302
+ For detailed API documentation, see the [Official Chzzk API Documentation](https://chzzk.gitbook.io/chzzk).
303
+
304
+ ## License
305
+
306
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
307
+
308
+ ## Contributing
309
+
310
+ Contributions are welcome! Please feel free to submit a Pull Request.
311
+
312
+ ## Disclaimer
313
+
314
+ This is an unofficial SDK and is not affiliated with NAVER or Chzzk. Use at your own risk.