Unofficial Python SDK for Chzzk (NAVER Live Streaming Platform) API
Project description
chzzk-python
Unofficial Python SDK for Chzzk (NAVER Live Streaming Platform) API
Installation
# Using uv (recommended)
uv add chzzk-python
# Using pip
pip install chzzk-python
CLI Installation
# Using uv (recommended)
uv add "chzzk-python[cli]"
# Using pip
pip install "chzzk-python[cli]"
Quick Start
from chzzk import ChzzkClient, FileTokenStorage
# Create client with OAuth support
client = ChzzkClient(
client_id="your-client-id",
client_secret="your-client-secret",
redirect_uri="http://localhost:8080/callback",
token_storage=FileTokenStorage("token.json"),
)
# Generate authorization URL
auth_url, state = client.get_authorization_url()
# User visits auth_url and authorizes the app
# Exchange code for token (after OAuth callback)
token = client.authenticate(code="auth-code", state=state)
# Use the API
user = client.user.get_me()
print(f"Channel: {user.channel_name}")
API Categories & Implementation Status
| Category | Status | Description |
|---|---|---|
| Authorization | ✅ Implemented | OAuth 2.0, Token issue/refresh/revoke |
| User | ✅ Implemented | Get logged-in user info |
| Channel | ✅ Implemented | Channel info, managers, followers, subscribers |
| Category | ✅ Implemented | Category search |
| Live | ✅ Implemented | Live list, stream key, broadcast settings |
| Chat | ✅ Implemented | Send messages, announcements, chat settings |
| Session | ✅ Implemented | Session create/list, event subscription |
| Restriction | ✅ Implemented | Activity restriction list management |
| Drops | ❌ Not Implemented | - |
| Webhook Event | ❌ Not Implemented | - |
A CLI is also available for quick terminal access.
Features
Sync/Async Support
Both synchronous and asynchronous clients are available:
# Synchronous
from chzzk import ChzzkClient
with ChzzkClient(client_id="...", client_secret="...") as client:
user = client.user.get_me()
# Asynchronous
from chzzk import AsyncChzzkClient
async with AsyncChzzkClient(client_id="...", client_secret="...") as client:
user = await client.user.get_me()
Token Storage
Multiple token storage options:
from chzzk import InMemoryTokenStorage, FileTokenStorage, CallbackTokenStorage
# In-memory (default)
storage = InMemoryTokenStorage()
# File-based persistence
storage = FileTokenStorage("token.json")
# Custom callback
storage = CallbackTokenStorage(
get_callback=lambda: load_from_db(),
save_callback=lambda token: save_to_db(token),
delete_callback=lambda: delete_from_db(),
)
Realtime Events
Receive chat, donation, and subscription events in realtime:
from chzzk import ChzzkClient, ChatEvent, DonationEvent, SubscriptionEvent
client = ChzzkClient(...)
event_client = client.create_event_client()
@event_client.on_chat
def on_chat(event: ChatEvent):
print(f"{event.profile.nickname}: {event.content}")
@event_client.on_donation
def on_donation(event: DonationEvent):
print(f"{event.donator_nickname} donated {event.pay_amount}won")
@event_client.on_subscription
def on_subscription(event: SubscriptionEvent):
print(f"{event.subscriber_nickname} subscribed!")
# Connect and subscribe
event_client.connect()
event_client.subscribe_chat()
event_client.subscribe_donation()
event_client.subscribe_subscription()
event_client.run_forever()
Usage Examples
OAuth Authentication Flow
from chzzk import ChzzkClient, FileTokenStorage
client = ChzzkClient(
client_id="your-client-id",
client_secret="your-client-secret",
redirect_uri="http://localhost:8080/callback",
token_storage=FileTokenStorage("token.json"),
auto_refresh=True, # Automatically refresh expired tokens
)
# 1. Generate authorization URL
auth_url, state = client.get_authorization_url()
print(f"Visit: {auth_url}")
# 2. After user authorizes, exchange code for token
token = client.authenticate(code="received-code", state=state)
# 3. Refresh token manually if needed
new_token = client.refresh_token()
# 4. Revoke token on logout
client.revoke_token()
Channel & Live Information
# Get channel info
channel = client.channel.get_channel("channel-id")
print(f"Channel: {channel.channel_name}")
print(f"Description: {channel.channel_description}")
# Get followers
followers = client.channel.get_followers(size=20)
for follower in followers.data:
print(f"Follower: {follower.nickname}")
# Get live broadcasts
lives = client.live.get_lives(size=10)
for live in lives.data:
print(f"{live.channel_name}: {live.live_title} ({live.concurrent_user_count} viewers)")
# Get/Update live settings
setting = client.live.get_setting()
client.live.update_setting(default_live_title="My Stream Title")
Chat Messages
# Send chat message
client.chat.send_message(channel_id="channel-id", message="Hello!")
# Set chat announcement
client.chat.set_notice(
channel_id="channel-id",
message="Welcome to the stream!",
)
# Get/Update chat settings
settings = client.chat.get_settings(channel_id="channel-id")
client.chat.update_settings(
channel_id="channel-id",
chat_available_group="FOLLOWER",
)
Async Example
import asyncio
from chzzk import AsyncChzzkClient, FileTokenStorage
async def main():
async with AsyncChzzkClient(
client_id="your-client-id",
client_secret="your-client-secret",
redirect_uri="http://localhost:8080/callback",
token_storage=FileTokenStorage("token.json"),
) as client:
# Get user info
user = await client.user.get_me()
print(f"Channel: {user.channel_name}")
# Get live broadcasts
lives = await client.live.get_lives(size=10)
for live in lives.data:
print(f"{live.channel_name}: {live.live_title}")
asyncio.run(main())
Exception Handling
from chzzk import (
ChzzkError, # Base exception
ChzzkAPIError, # API error response
AuthenticationError, # 401 errors
InvalidTokenError, # Invalid/expired token
InvalidClientError, # Invalid client credentials
ForbiddenError, # 403 errors
NotFoundError, # 404 errors
RateLimitError, # 429 errors
ServerError, # 5xx errors
TokenExpiredError, # Token expired, need re-auth
InvalidStateError, # OAuth state mismatch
SessionError, # Session-related errors
SessionConnectionError, # Socket.IO connection failed
SessionLimitExceededError, # Max session limit exceeded
EventSubscriptionError, # Event subscription failed
)
try:
user = client.user.get_me()
except InvalidTokenError:
# Token is invalid or expired
token = client.refresh_token()
except RateLimitError:
# Rate limit exceeded, wait and retry
time.sleep(60)
except ChzzkAPIError as e:
print(f"API Error: [{e.status_code}] {e.error_code}: {e.message}")
Unofficial API
In addition to the official API, we provide an unofficial API using Naver cookie authentication. This enables real-time chat receiving/sending functionality.
⚠️ The unofficial API may change at any time and is not officially supported.
Unofficial Chat Client
Synchronous version:
from chzzk.unofficial import UnofficialChatClient, ChatMessage
chat = UnofficialChatClient(
nid_aut="your-nid-aut-cookie",
nid_ses="your-nid-ses-cookie",
)
@chat.on_chat
def on_chat(msg: ChatMessage):
print(f"{msg.nickname}: {msg.content}")
@chat.on_donation
def on_donation(msg):
print(f"{msg.nickname} donated {msg.pay_amount}won")
chat.connect("channel-id")
chat.send_message("Hello!")
chat.run_forever()
Asynchronous version:
from chzzk.unofficial import AsyncUnofficialChatClient, ChatMessage
async with AsyncUnofficialChatClient(
nid_aut="your-nid-aut-cookie",
nid_ses="your-nid-ses-cookie",
) as chat:
@chat.on_chat
async def on_chat(msg: ChatMessage):
print(f"{msg.nickname}: {msg.content}")
await chat.connect("channel-id")
await chat.send_message("Hello!")
await chat.run_forever()
How to Get Naver Cookies
- Log in to Naver
- Browser Developer Tools (F12) → Application → Cookies
- Copy
NID_AUTandNID_SEScookie values
Unofficial API Exception Handling
from chzzk import ChatConnectionError, ChatNotLiveError
try:
chat.connect("channel-id")
except ChatNotLiveError:
print("Channel is not currently live")
except ChatConnectionError as e:
print(f"Connection failed: {e}")
Command Line Interface
A CLI is available for quick access to the unofficial API features.
Authentication
# Login via Naver QR code (recommended)
chzzk auth qr
# Login via Naver QR code with custom timeout
chzzk auth qr --timeout 60
# Save your Naver cookies manually (interactive)
chzzk auth login
# Check authentication status
chzzk auth status
# Remove stored cookies
chzzk auth logout
Cookies are stored in ~/.chzzk/cookies.json.
Live Status
# Get detailed live information
chzzk live info CHANNEL_ID
# Get simple LIVE/OFFLINE status
chzzk live status CHANNEL_ID
# JSON output
chzzk --json live info CHANNEL_ID
Chat
# Watch real-time chat
chzzk chat watch CHANNEL_ID
# Watch chat even when offline
chzzk chat watch CHANNEL_ID --offline
# Save chat to file
chzzk chat watch CHANNEL_ID --output chat.jsonl
chzzk chat watch CHANNEL_ID --output chat.txt --output-format txt
# Auto-generate filename based on stream info (recommended)
# Creates: {channel_id}_{live_id}_{YYYYMMDD}.jsonl
chzzk chat watch CHANNEL_ID --output-dir ./logs
# Send a single message (requires authentication)
chzzk chat send CHANNEL_ID "Hello!"
# Send to offline channel
chzzk chat send CHANNEL_ID "Hello!" --offline
# Interactive mode: send and receive messages
chzzk chat send CHANNEL_ID --interactive
# or
chzzk chat send CHANNEL_ID -i
# Interactive mode with chat logging
chzzk chat send CHANNEL_ID -i --output-dir ./logs
# Interactive mode with offline channel
chzzk chat send CHANNEL_ID -i --offline
Global Options
--nid-aut TEXT # Override NID_AUT cookie (env: CHZZK_NID_AUT)
--nid-ses TEXT # Override NID_SES cookie (env: CHZZK_NID_SES)
--json # Output in JSON format
--log-level LEVEL # Set log level (DEBUG, INFO, WARNING, ERROR)
Environment Variables
| Variable | Description |
|---|---|
CHZZK_NID_AUT |
NID_AUT cookie value |
CHZZK_NID_SES |
NID_SES cookie value |
CHZZK_LOG_LEVEL |
Default log level |
CHZZK_CHAT_OUTPUT |
Default chat output file path |
CHZZK_CHAT_OUTPUT_DIR |
Default chat output directory (auto-generates filename) |
CHZZK_CHAT_OUTPUT_FORMAT |
Default chat output format (jsonl, txt) |
Examples
See the examples directory for complete working examples:
oauth_server.py- OAuth authentication with Flaskrealtime_chat.py- Realtime chat/donation/subscription events (sync)realtime_chat_async.py- Realtime events (async)session_management.py- Session management exampleunofficial_chat.py- Unofficial chat client (sync)unofficial_chat_async.py- Unofficial chat client (async)
API Reference
For detailed API documentation, see the Official Chzzk API Documentation.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Disclaimer
This is an unofficial SDK and is not affiliated with NAVER or Chzzk. Use at your own risk.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file chzzk_python-0.10.0.tar.gz.
File metadata
- Download URL: chzzk_python-0.10.0.tar.gz
- Upload date:
- Size: 172.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
779475604a7c088b4f9cdbf63a4e3be0e3b37460b4cefed245c9b82d86e1f593
|
|
| MD5 |
ced160df59425011a8f8a568e4e0ccbd
|
|
| BLAKE2b-256 |
702ee41f3332e3fc4a992706a648645708beafe6452201a93a536ecf75402817
|
Provenance
The following attestation bundles were made for chzzk_python-0.10.0.tar.gz:
Publisher:
publish.yml on hypn4/chzzk-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
chzzk_python-0.10.0.tar.gz -
Subject digest:
779475604a7c088b4f9cdbf63a4e3be0e3b37460b4cefed245c9b82d86e1f593 - Sigstore transparency entry: 867502898
- Sigstore integration time:
-
Permalink:
hypn4/chzzk-python@cfade6168e573da056060dfadd20ecd39c26694e -
Branch / Tag:
refs/tags/v0.10.0 - Owner: https://github.com/hypn4
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@cfade6168e573da056060dfadd20ecd39c26694e -
Trigger Event:
push
-
Statement type:
File details
Details for the file chzzk_python-0.10.0-py3-none-any.whl.
File metadata
- Download URL: chzzk_python-0.10.0-py3-none-any.whl
- Upload date:
- Size: 90.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
792fc3dce9e90225edb62f511473fc814eec4ad1d5ad8247228a80f45b6fbbe3
|
|
| MD5 |
e7b723e15eec065728636d87e081adbd
|
|
| BLAKE2b-256 |
1e6274b02b5498871acd9a2edf34b197875938258772923fe3fb5adb8215c70f
|
Provenance
The following attestation bundles were made for chzzk_python-0.10.0-py3-none-any.whl:
Publisher:
publish.yml on hypn4/chzzk-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
chzzk_python-0.10.0-py3-none-any.whl -
Subject digest:
792fc3dce9e90225edb62f511473fc814eec4ad1d5ad8247228a80f45b6fbbe3 - Sigstore transparency entry: 867502899
- Sigstore integration time:
-
Permalink:
hypn4/chzzk-python@cfade6168e573da056060dfadd20ecd39c26694e -
Branch / Tag:
refs/tags/v0.10.0 - Owner: https://github.com/hypn4
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@cfade6168e573da056060dfadd20ecd39c26694e -
Trigger Event:
push
-
Statement type: