Skip to main content

Unofficial Python SDK for Chzzk (NAVER Live Streaming Platform) API

Project description

chzzk-python

Python 3.12+ License: MIT

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

  1. Log in to Naver
  2. Browser Developer Tools (F12) → Application → Cookies
  3. Copy NID_AUT and NID_SES cookie 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 Flask
  • realtime_chat.py - Realtime chat/donation/subscription events (sync)
  • realtime_chat_async.py - Realtime events (async)
  • session_management.py - Session management example
  • unofficial_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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

chzzk_python-0.10.0.tar.gz (172.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

chzzk_python-0.10.0-py3-none-any.whl (90.1 kB view details)

Uploaded Python 3

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

Hashes for chzzk_python-0.10.0.tar.gz
Algorithm Hash digest
SHA256 779475604a7c088b4f9cdbf63a4e3be0e3b37460b4cefed245c9b82d86e1f593
MD5 ced160df59425011a8f8a568e4e0ccbd
BLAKE2b-256 702ee41f3332e3fc4a992706a648645708beafe6452201a93a536ecf75402817

See more details on using hashes here.

Provenance

The following attestation bundles were made for chzzk_python-0.10.0.tar.gz:

Publisher: publish.yml on hypn4/chzzk-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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

Hashes for chzzk_python-0.10.0-py3-none-any.whl
Algorithm Hash digest
SHA256 792fc3dce9e90225edb62f511473fc814eec4ad1d5ad8247228a80f45b6fbbe3
MD5 e7b723e15eec065728636d87e081adbd
BLAKE2b-256 1e6274b02b5498871acd9a2edf34b197875938258772923fe3fb5adb8215c70f

See more details on using hashes here.

Provenance

The following attestation bundles were made for chzzk_python-0.10.0-py3-none-any.whl:

Publisher: publish.yml on hypn4/chzzk-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page