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

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 -

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}")

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.3.1.tar.gz (127.2 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.3.1-py3-none-any.whl (56.9 kB view details)

Uploaded Python 3

File details

Details for the file chzzk_python-0.3.1.tar.gz.

File metadata

  • Download URL: chzzk_python-0.3.1.tar.gz
  • Upload date:
  • Size: 127.2 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.3.1.tar.gz
Algorithm Hash digest
SHA256 ee67895d2da87b579f97cb510d5323f37e769f1242c5292452c0d9ca4962237e
MD5 c46d35264fa4aa7aabd36fd3bb183dea
BLAKE2b-256 73020d4c7a947c2a5b73b847f328d3df8d191fb7808b3c99649af1efefa943f6

See more details on using hashes here.

Provenance

The following attestation bundles were made for chzzk_python-0.3.1.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.3.1-py3-none-any.whl.

File metadata

  • Download URL: chzzk_python-0.3.1-py3-none-any.whl
  • Upload date:
  • Size: 56.9 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.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 a7937a5cd9d5ebcce502a84e9fd1bd0226cc783e1aeafbefaf91cc47dbe0f369
MD5 eacf3103e497fad1d8709308a8729a21
BLAKE2b-256 0d015b85e55535139cc78db1fae6f6699685f87387c1c350190c8f68bb366e03

See more details on using hashes here.

Provenance

The following attestation bundles were made for chzzk_python-0.3.1-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