chzzk-python 0.10.0__tar.gz → 0.12.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 (115) hide show
  1. chzzk_python-0.12.0/.dockerignore +26 -0
  2. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/.env.example +8 -0
  3. chzzk_python-0.12.0/.github/workflows/docker.yml +157 -0
  4. chzzk_python-0.12.0/Dockerfile +54 -0
  5. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/PKG-INFO +85 -1
  6. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/README.md +84 -0
  7. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/README_KO.md +85 -1
  8. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/examples/.env.example +8 -0
  9. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/_version.py +2 -2
  10. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/cli/commands/chat.py +48 -2
  11. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/unofficial/chat/client.py +23 -5
  12. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/unofficial/chat/monitor.py +87 -2
  13. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/unofficial/client.py +52 -4
  14. chzzk_python-0.12.0/tests/unofficial/__init__.py +1 -0
  15. chzzk_python-0.12.0/tests/unofficial/test_client.py +250 -0
  16. chzzk_python-0.12.0/tests/unofficial/test_monitor.py +455 -0
  17. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/.github/workflows/build.yml +0 -0
  18. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/.github/workflows/ci.yml +0 -0
  19. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/.github/workflows/publish.yml +0 -0
  20. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/.gitignore +0 -0
  21. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/.python-version +0 -0
  22. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/LICENSE +0 -0
  23. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/chzzk.spec +0 -0
  24. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/docs/unofficial-chat-websocket-protocol.md +0 -0
  25. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/examples/oauth_server.py +0 -0
  26. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/examples/realtime_chat.py +0 -0
  27. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/examples/realtime_chat_async.py +0 -0
  28. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/examples/session_management.py +0 -0
  29. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/examples/unofficial_chat.py +0 -0
  30. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/examples/unofficial_chat_async.py +0 -0
  31. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/main.py +0 -0
  32. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/pyproject.toml +0 -0
  33. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/scripts/build.py +0 -0
  34. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/__init__.py +0 -0
  35. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/api/__init__.py +0 -0
  36. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/api/base.py +0 -0
  37. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/api/category.py +0 -0
  38. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/api/channel.py +0 -0
  39. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/api/chat.py +0 -0
  40. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/api/live.py +0 -0
  41. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/api/restriction.py +0 -0
  42. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/api/session.py +0 -0
  43. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/api/user.py +0 -0
  44. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/auth/__init__.py +0 -0
  45. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/auth/models.py +0 -0
  46. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/auth/oauth.py +0 -0
  47. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/auth/token.py +0 -0
  48. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/cli/__init__.py +0 -0
  49. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/cli/commands/__init__.py +0 -0
  50. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/cli/commands/auth.py +0 -0
  51. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/cli/commands/live.py +0 -0
  52. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/cli/config.py +0 -0
  53. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/cli/formatter.py +0 -0
  54. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/cli/logging.py +0 -0
  55. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/cli/main.py +0 -0
  56. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/cli/writers.py +0 -0
  57. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/client.py +0 -0
  58. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/constants.py +0 -0
  59. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/exceptions/__init__.py +0 -0
  60. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/exceptions/errors.py +0 -0
  61. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/http/__init__.py +0 -0
  62. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/http/_base.py +0 -0
  63. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/http/client.py +0 -0
  64. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/http/endpoints.py +0 -0
  65. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/logging.py +0 -0
  66. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/models/__init__.py +0 -0
  67. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/models/category.py +0 -0
  68. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/models/channel.py +0 -0
  69. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/models/chat.py +0 -0
  70. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/models/common.py +0 -0
  71. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/models/live.py +0 -0
  72. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/models/restriction.py +0 -0
  73. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/models/session.py +0 -0
  74. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/models/user.py +0 -0
  75. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/py.typed +0 -0
  76. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/realtime/__init__.py +0 -0
  77. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/realtime/client.py +0 -0
  78. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/unofficial/__init__.py +0 -0
  79. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/unofficial/api/__init__.py +0 -0
  80. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/unofficial/api/base.py +0 -0
  81. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/unofficial/api/chat.py +0 -0
  82. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/unofficial/api/live.py +0 -0
  83. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/unofficial/api/user.py +0 -0
  84. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/unofficial/auth/__init__.py +0 -0
  85. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/unofficial/auth/cookie.py +0 -0
  86. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/unofficial/chat/__init__.py +0 -0
  87. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/unofficial/chat/connection.py +0 -0
  88. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/unofficial/chat/handler.py +0 -0
  89. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/unofficial/http/__init__.py +0 -0
  90. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/unofficial/http/_base.py +0 -0
  91. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/unofficial/http/client.py +0 -0
  92. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/unofficial/http/endpoints.py +0 -0
  93. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/unofficial/models/__init__.py +0 -0
  94. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/unofficial/models/chat.py +0 -0
  95. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/unofficial/models/live.py +0 -0
  96. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/unofficial/models/reconnect.py +0 -0
  97. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/src/chzzk/unofficial/models/user.py +0 -0
  98. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/tests/__init__.py +0 -0
  99. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/tests/api/__init__.py +0 -0
  100. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/tests/api/test_category.py +0 -0
  101. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/tests/api/test_channel.py +0 -0
  102. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/tests/api/test_chat.py +0 -0
  103. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/tests/api/test_live.py +0 -0
  104. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/tests/api/test_restriction.py +0 -0
  105. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/tests/api/test_session.py +0 -0
  106. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/tests/api/test_user.py +0 -0
  107. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/tests/auth/__init__.py +0 -0
  108. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/tests/auth/test_oauth.py +0 -0
  109. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/tests/cli/__init__.py +0 -0
  110. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/tests/cli/test_formatter.py +0 -0
  111. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/tests/cli/test_writers.py +0 -0
  112. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/tests/realtime/__init__.py +0 -0
  113. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/tests/realtime/test_client.py +0 -0
  114. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/tests/test_client.py +0 -0
  115. {chzzk_python-0.10.0 → chzzk_python-0.12.0}/uv.lock +0 -0
@@ -0,0 +1,26 @@
1
+ .git
2
+ .gitignore
3
+ __pycache__
4
+ *.py[cod]
5
+ .venv
6
+ venv/
7
+ .pytest_cache/
8
+ .ruff_cache/
9
+ .mypy_cache/
10
+ dist/
11
+ build/
12
+ *.egg-info/
13
+ .env
14
+ .env.*
15
+ *.token.json
16
+ .chzzk_token.json
17
+ *.log
18
+ *.jsonl
19
+ docs/
20
+ .github/
21
+ .mcp.json
22
+ CLAUDE.md
23
+ .claude/
24
+ chzzk.spec
25
+ tests/
26
+ examples/
@@ -49,3 +49,11 @@ CHZZK_CHAT_OUTPUT_DIR=
49
49
 
50
50
  # Output format: jsonl, txt (default: jsonl)
51
51
  CHZZK_CHAT_OUTPUT_FORMAT=
52
+
53
+ # Chat Monitoring Configuration
54
+ # Interval for polling live status in seconds (default: 10)
55
+ CHZZK_POLL_INTERVAL=
56
+
57
+ # Enable automatic reconnection when stream restarts (default: true)
58
+ # Set to "false" or "0" to disable
59
+ CHZZK_AUTO_RECONNECT=
@@ -0,0 +1,157 @@
1
+ name: Docker Build and Push
2
+
3
+ on:
4
+ push:
5
+ tags: ["v*"]
6
+ workflow_dispatch:
7
+ inputs:
8
+ push:
9
+ description: "Push image to registry"
10
+ required: false
11
+ default: false
12
+ type: boolean
13
+
14
+ env:
15
+ REGISTRY: ghcr.io
16
+ IMAGE_NAME: ${{ github.repository }}
17
+
18
+ jobs:
19
+ ci:
20
+ uses: ./.github/workflows/ci.yml
21
+
22
+ # Stage 1: 각 아키텍처를 네이티브 러너에서 병렬 빌드
23
+ build:
24
+ needs: ci
25
+ strategy:
26
+ fail-fast: false
27
+ matrix:
28
+ include:
29
+ - platform: linux/amd64
30
+ runner: ubuntu-latest
31
+ - platform: linux/arm64
32
+ runner: ubuntu-24.04-arm # Native ARM runner (QEMU 없음!)
33
+ runs-on: ${{ matrix.runner }}
34
+ permissions:
35
+ contents: read
36
+ packages: write
37
+
38
+ steps:
39
+ - name: Checkout repository
40
+ uses: actions/checkout@v4
41
+ with:
42
+ fetch-depth: 0
43
+
44
+ - name: Set up Docker Buildx
45
+ uses: docker/setup-buildx-action@v3
46
+
47
+ - name: Log in to GitHub Container Registry
48
+ uses: docker/login-action@v3
49
+ with:
50
+ registry: ${{ env.REGISTRY }}
51
+ username: ${{ github.actor }}
52
+ password: ${{ secrets.GITHUB_TOKEN }}
53
+
54
+ - name: Extract metadata
55
+ id: meta
56
+ uses: docker/metadata-action@v5
57
+ with:
58
+ images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
59
+
60
+ - name: Get version from tag
61
+ id: version
62
+ run: |
63
+ if [[ "${{ github.ref_type }}" == "tag" ]]; then
64
+ VERSION="${{ github.ref_name }}"
65
+ VERSION="${VERSION#v}" # Remove 'v' prefix
66
+ else
67
+ VERSION="0.0.0+$(git rev-parse --short HEAD)"
68
+ fi
69
+ echo "version=$VERSION" >> "$GITHUB_OUTPUT"
70
+
71
+ - name: Build and push by digest
72
+ id: build
73
+ uses: docker/build-push-action@v6
74
+ with:
75
+ context: .
76
+ platforms: ${{ matrix.platform }}
77
+ labels: ${{ steps.meta.outputs.labels }}
78
+ build-args: |
79
+ VERSION=${{ steps.version.outputs.version }}
80
+ outputs: type=image,name=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }},push-by-digest=true,name-canonical=true,push=true
81
+ cache-from: type=gha,scope=${{ matrix.platform }}
82
+ cache-to: type=gha,scope=${{ matrix.platform }},mode=max
83
+
84
+ - name: Export digest
85
+ run: |
86
+ mkdir -p /tmp/digests
87
+ digest="${{ steps.build.outputs.digest }}"
88
+ touch "/tmp/digests/${digest#sha256:}"
89
+
90
+ - name: Upload digest
91
+ uses: actions/upload-artifact@v4
92
+ with:
93
+ name: digests-${{ matrix.platform == 'linux/amd64' && 'amd64' || 'arm64' }}
94
+ path: /tmp/digests/*
95
+ if-no-files-found: error
96
+ retention-days: 1
97
+
98
+ # Stage 2: Multi-arch manifest 병합
99
+ merge:
100
+ needs: build
101
+ runs-on: ubuntu-latest
102
+ permissions:
103
+ contents: read
104
+ packages: write
105
+ attestations: write
106
+ id-token: write
107
+
108
+ steps:
109
+ - name: Download digests
110
+ uses: actions/download-artifact@v4
111
+ with:
112
+ path: /tmp/digests
113
+ pattern: digests-*
114
+ merge-multiple: true
115
+
116
+ - name: Set up Docker Buildx
117
+ uses: docker/setup-buildx-action@v3
118
+
119
+ - name: Log in to GitHub Container Registry
120
+ uses: docker/login-action@v3
121
+ with:
122
+ registry: ${{ env.REGISTRY }}
123
+ username: ${{ github.actor }}
124
+ password: ${{ secrets.GITHUB_TOKEN }}
125
+
126
+ - name: Extract metadata
127
+ id: meta
128
+ uses: docker/metadata-action@v5
129
+ with:
130
+ images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
131
+ tags: |
132
+ type=semver,pattern={{version}}
133
+ type=semver,pattern={{major}}.{{minor}}
134
+ type=semver,pattern={{major}}
135
+ type=raw,value=latest,enable={{is_default_branch}}
136
+ type=sha,prefix=sha-
137
+ labels: |
138
+ org.opencontainers.image.title=chzzk-python
139
+ org.opencontainers.image.description=Unofficial Python SDK and CLI for Chzzk
140
+ org.opencontainers.image.vendor=hypn4
141
+
142
+ - name: Create manifest list and push
143
+ working-directory: /tmp/digests
144
+ run: |
145
+ docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
146
+ $(printf '${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@sha256:%s ' *)
147
+
148
+ - name: Inspect image
149
+ run: |
150
+ docker buildx imagetools inspect ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.meta.outputs.version }}
151
+
152
+ - name: Generate artifact attestation
153
+ uses: actions/attest-build-provenance@v2
154
+ with:
155
+ subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
156
+ subject-digest: ${{ steps.meta.outputs.version }}
157
+ push-to-registry: true
@@ -0,0 +1,54 @@
1
+ # syntax=docker/dockerfile:1
2
+
3
+ # =============================================================================
4
+ # Stage 1: Builder - uv로 의존성 설치
5
+ # =============================================================================
6
+ FROM ghcr.io/astral-sh/uv:python3.14-bookworm-slim AS builder
7
+
8
+ # 버전 정보 (hatch-vcs용 - .git 없이 빌드 지원)
9
+ ARG VERSION=0.0.0
10
+ ENV SETUPTOOLS_SCM_PRETEND_VERSION=${VERSION}
11
+
12
+ ENV UV_COMPILE_BYTECODE=1 \
13
+ UV_LINK_MODE=copy \
14
+ UV_PYTHON_DOWNLOADS=0
15
+
16
+ WORKDIR /app
17
+
18
+ # 의존성 먼저 설치 (레이어 캐싱 최적화)
19
+ RUN --mount=type=cache,target=/root/.cache/uv \
20
+ --mount=type=bind,source=uv.lock,target=uv.lock \
21
+ --mount=type=bind,source=pyproject.toml,target=pyproject.toml \
22
+ uv sync --locked --no-install-project --no-dev --all-extras
23
+
24
+ # 소스 코드 복사 및 프로젝트 설치
25
+ COPY src/ /app/src/
26
+ COPY pyproject.toml uv.lock README.md LICENSE /app/
27
+
28
+ RUN --mount=type=cache,target=/root/.cache/uv \
29
+ uv sync --locked --no-dev --all-extras --no-editable
30
+
31
+ # =============================================================================
32
+ # Stage 2: Runtime - 최소 프로덕션 이미지
33
+ # =============================================================================
34
+ FROM python:3.14-slim-bookworm AS runtime
35
+
36
+ # 보안: non-root 사용자
37
+ RUN groupadd --gid 1000 chzzk && \
38
+ useradd --uid 1000 --gid 1000 --shell /bin/bash --create-home chzzk
39
+
40
+ # 가상환경만 복사
41
+ COPY --from=builder --chown=chzzk:chzzk /app/.venv /app/.venv
42
+
43
+ ENV PATH="/app/.venv/bin:$PATH" \
44
+ PYTHONUNBUFFERED=1 \
45
+ PYTHONDONTWRITEBYTECODE=1
46
+
47
+ USER chzzk
48
+ WORKDIR /home/chzzk
49
+
50
+ HEALTHCHECK --interval=30s --timeout=5s --start-period=5s --retries=3 \
51
+ CMD chzzk --help || exit 1
52
+
53
+ ENTRYPOINT ["chzzk"]
54
+ CMD ["--help"]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: chzzk-python
3
- Version: 0.10.0
3
+ Version: 0.12.0
4
4
  Summary: Unofficial Python SDK for Chzzk (NAVER Live Streaming Platform) API
5
5
  Project-URL: Homepage, https://github.com/hypn4/chzzk-python
6
6
  Project-URL: Repository, https://github.com/hypn4/chzzk-python
@@ -39,6 +39,7 @@ Description-Content-Type: text/markdown
39
39
 
40
40
  [![Python 3.12+](https://img.shields.io/badge/python-3.12+-blue.svg)](https://www.python.org/downloads/)
41
41
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
42
+ [![Docker](https://img.shields.io/badge/docker-ghcr.io-blue.svg)](https://ghcr.io/hypn4/chzzk-python)
42
43
 
43
44
  Unofficial Python SDK for Chzzk (NAVER Live Streaming Platform) API
44
45
 
@@ -64,6 +65,31 @@ uv add "chzzk-python[cli]"
64
65
  pip install "chzzk-python[cli]"
65
66
  ```
66
67
 
68
+ ### Docker
69
+
70
+ ```bash
71
+ # Pull from GitHub Container Registry
72
+ docker pull ghcr.io/hypn4/chzzk-python:latest
73
+
74
+ # Run CLI commands
75
+ docker run --rm ghcr.io/hypn4/chzzk-python --help
76
+ docker run --rm ghcr.io/hypn4/chzzk-python auth --help
77
+
78
+ # Watch chat (with environment variables)
79
+ docker run --rm -it \
80
+ -e CHZZK_NID_AUT="your-nid-aut" \
81
+ -e CHZZK_NID_SES="your-nid-ses" \
82
+ ghcr.io/hypn4/chzzk-python chat watch CHANNEL_ID
83
+
84
+ # Interactive chat (requires -it flags)
85
+ docker run --rm -it \
86
+ -e CHZZK_NID_AUT="your-nid-aut" \
87
+ -e CHZZK_NID_SES="your-nid-ses" \
88
+ ghcr.io/hypn4/chzzk-python chat send CHANNEL_ID -i
89
+ ```
90
+
91
+ Available tags: `latest`, `X.Y.Z`, `X.Y`, `X`
92
+
67
93
  ## Quick Start
68
94
 
69
95
  ```python
@@ -357,6 +383,56 @@ async with AsyncUnofficialChatClient(
357
383
  await chat.run_forever()
358
384
  ```
359
385
 
386
+ ### Auto-Reconnection & Monitoring Options
387
+
388
+ The unofficial chat client automatically reconnects when the stream restarts or the chat channel changes. You can customize this behavior:
389
+
390
+ ```python
391
+ from chzzk.unofficial import AsyncUnofficialChatClient
392
+
393
+ chat = AsyncUnofficialChatClient(
394
+ nid_aut="...",
395
+ nid_ses="...",
396
+ # Auto-reconnect settings
397
+ auto_reconnect=True, # Enable auto-reconnection (default: True)
398
+ poll_interval=10.0, # Status polling interval in seconds (default: 10)
399
+ max_reconnect_attempts=5, # Max reconnection attempts (default: 5)
400
+ reconnect_backoff_base=1.0, # Backoff base delay in seconds (default: 1)
401
+ reconnect_backoff_max=30.0, # Max backoff delay in seconds (default: 30)
402
+ reconnect_wait_timeout=None, # Reconnection wait timeout (None = infinite)
403
+ )
404
+
405
+ # Event handlers for connection status
406
+ @chat.on_live
407
+ async def on_live(event):
408
+ print(f"Stream started: {event.live_title}")
409
+
410
+ @chat.on_offline
411
+ async def on_offline(event):
412
+ print("Stream ended, waiting for restart...")
413
+
414
+ @chat.on_reconnect
415
+ async def on_reconnect(event):
416
+ print(f"Reconnected! (attempt {event.attempt})")
417
+
418
+ @chat.on_reconnect_error
419
+ async def on_reconnect_error(error):
420
+ print(f"Reconnection failed: {error}")
421
+ ```
422
+
423
+ For long-running monitoring applications, you can configure infinite retry behavior:
424
+
425
+ ```python
426
+ from chzzk.unofficial.chat.monitor import MonitorConfig
427
+
428
+ # Create a custom monitor config
429
+ config = MonitorConfig(
430
+ poll_interval_seconds=10.0, # Poll every 10 seconds
431
+ max_consecutive_failures=10, # Trigger error callback after 10 failures
432
+ infinite_retry=True, # Continue monitoring even after failures
433
+ )
434
+ ```
435
+
360
436
  ### How to Get Naver Cookies
361
437
 
362
438
  1. Log in to Naver
@@ -431,6 +507,12 @@ chzzk chat watch CHANNEL_ID --output chat.txt --output-format txt
431
507
  # Creates: {channel_id}_{live_id}_{YYYYMMDD}.jsonl
432
508
  chzzk chat watch CHANNEL_ID --output-dir ./logs
433
509
 
510
+ # Disable auto-reconnection
511
+ chzzk chat watch CHANNEL_ID --no-auto-reconnect
512
+
513
+ # Custom poll interval (seconds)
514
+ chzzk chat watch CHANNEL_ID --poll-interval 5
515
+
434
516
  # Send a single message (requires authentication)
435
517
  chzzk chat send CHANNEL_ID "Hello!"
436
518
 
@@ -468,6 +550,8 @@ chzzk chat send CHANNEL_ID -i --offline
468
550
  | `CHZZK_CHAT_OUTPUT` | Default chat output file path |
469
551
  | `CHZZK_CHAT_OUTPUT_DIR` | Default chat output directory (auto-generates filename) |
470
552
  | `CHZZK_CHAT_OUTPUT_FORMAT` | Default chat output format (jsonl, txt) |
553
+ | `CHZZK_POLL_INTERVAL` | Live status polling interval in seconds (default: 10) |
554
+ | `CHZZK_AUTO_RECONNECT` | Enable auto-reconnection (default: true, set "false" to disable) |
471
555
 
472
556
  ## Examples
473
557
 
@@ -2,6 +2,7 @@
2
2
 
3
3
  [![Python 3.12+](https://img.shields.io/badge/python-3.12+-blue.svg)](https://www.python.org/downloads/)
4
4
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+ [![Docker](https://img.shields.io/badge/docker-ghcr.io-blue.svg)](https://ghcr.io/hypn4/chzzk-python)
5
6
 
6
7
  Unofficial Python SDK for Chzzk (NAVER Live Streaming Platform) API
7
8
 
@@ -27,6 +28,31 @@ uv add "chzzk-python[cli]"
27
28
  pip install "chzzk-python[cli]"
28
29
  ```
29
30
 
31
+ ### Docker
32
+
33
+ ```bash
34
+ # Pull from GitHub Container Registry
35
+ docker pull ghcr.io/hypn4/chzzk-python:latest
36
+
37
+ # Run CLI commands
38
+ docker run --rm ghcr.io/hypn4/chzzk-python --help
39
+ docker run --rm ghcr.io/hypn4/chzzk-python auth --help
40
+
41
+ # Watch chat (with environment variables)
42
+ docker run --rm -it \
43
+ -e CHZZK_NID_AUT="your-nid-aut" \
44
+ -e CHZZK_NID_SES="your-nid-ses" \
45
+ ghcr.io/hypn4/chzzk-python chat watch CHANNEL_ID
46
+
47
+ # Interactive chat (requires -it flags)
48
+ docker run --rm -it \
49
+ -e CHZZK_NID_AUT="your-nid-aut" \
50
+ -e CHZZK_NID_SES="your-nid-ses" \
51
+ ghcr.io/hypn4/chzzk-python chat send CHANNEL_ID -i
52
+ ```
53
+
54
+ Available tags: `latest`, `X.Y.Z`, `X.Y`, `X`
55
+
30
56
  ## Quick Start
31
57
 
32
58
  ```python
@@ -320,6 +346,56 @@ async with AsyncUnofficialChatClient(
320
346
  await chat.run_forever()
321
347
  ```
322
348
 
349
+ ### Auto-Reconnection & Monitoring Options
350
+
351
+ The unofficial chat client automatically reconnects when the stream restarts or the chat channel changes. You can customize this behavior:
352
+
353
+ ```python
354
+ from chzzk.unofficial import AsyncUnofficialChatClient
355
+
356
+ chat = AsyncUnofficialChatClient(
357
+ nid_aut="...",
358
+ nid_ses="...",
359
+ # Auto-reconnect settings
360
+ auto_reconnect=True, # Enable auto-reconnection (default: True)
361
+ poll_interval=10.0, # Status polling interval in seconds (default: 10)
362
+ max_reconnect_attempts=5, # Max reconnection attempts (default: 5)
363
+ reconnect_backoff_base=1.0, # Backoff base delay in seconds (default: 1)
364
+ reconnect_backoff_max=30.0, # Max backoff delay in seconds (default: 30)
365
+ reconnect_wait_timeout=None, # Reconnection wait timeout (None = infinite)
366
+ )
367
+
368
+ # Event handlers for connection status
369
+ @chat.on_live
370
+ async def on_live(event):
371
+ print(f"Stream started: {event.live_title}")
372
+
373
+ @chat.on_offline
374
+ async def on_offline(event):
375
+ print("Stream ended, waiting for restart...")
376
+
377
+ @chat.on_reconnect
378
+ async def on_reconnect(event):
379
+ print(f"Reconnected! (attempt {event.attempt})")
380
+
381
+ @chat.on_reconnect_error
382
+ async def on_reconnect_error(error):
383
+ print(f"Reconnection failed: {error}")
384
+ ```
385
+
386
+ For long-running monitoring applications, you can configure infinite retry behavior:
387
+
388
+ ```python
389
+ from chzzk.unofficial.chat.monitor import MonitorConfig
390
+
391
+ # Create a custom monitor config
392
+ config = MonitorConfig(
393
+ poll_interval_seconds=10.0, # Poll every 10 seconds
394
+ max_consecutive_failures=10, # Trigger error callback after 10 failures
395
+ infinite_retry=True, # Continue monitoring even after failures
396
+ )
397
+ ```
398
+
323
399
  ### How to Get Naver Cookies
324
400
 
325
401
  1. Log in to Naver
@@ -394,6 +470,12 @@ chzzk chat watch CHANNEL_ID --output chat.txt --output-format txt
394
470
  # Creates: {channel_id}_{live_id}_{YYYYMMDD}.jsonl
395
471
  chzzk chat watch CHANNEL_ID --output-dir ./logs
396
472
 
473
+ # Disable auto-reconnection
474
+ chzzk chat watch CHANNEL_ID --no-auto-reconnect
475
+
476
+ # Custom poll interval (seconds)
477
+ chzzk chat watch CHANNEL_ID --poll-interval 5
478
+
397
479
  # Send a single message (requires authentication)
398
480
  chzzk chat send CHANNEL_ID "Hello!"
399
481
 
@@ -431,6 +513,8 @@ chzzk chat send CHANNEL_ID -i --offline
431
513
  | `CHZZK_CHAT_OUTPUT` | Default chat output file path |
432
514
  | `CHZZK_CHAT_OUTPUT_DIR` | Default chat output directory (auto-generates filename) |
433
515
  | `CHZZK_CHAT_OUTPUT_FORMAT` | Default chat output format (jsonl, txt) |
516
+ | `CHZZK_POLL_INTERVAL` | Live status polling interval in seconds (default: 10) |
517
+ | `CHZZK_AUTO_RECONNECT` | Enable auto-reconnection (default: true, set "false" to disable) |
434
518
 
435
519
  ## Examples
436
520
 
@@ -1,7 +1,8 @@
1
1
  # chzzk-python
2
2
 
3
- [![Python 3.14+](https://img.shields.io/badge/python-3.14+-blue.svg)](https://www.python.org/downloads/)
3
+ [![Python 3.12+](https://img.shields.io/badge/python-3.12+-blue.svg)](https://www.python.org/downloads/)
4
4
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+ [![Docker](https://img.shields.io/badge/docker-ghcr.io-blue.svg)](https://ghcr.io/hypn4/chzzk-python)
5
6
 
6
7
  치지직(CHZZK) 스트리밍 플랫폼을 위한 비공식 Python SDK
7
8
 
@@ -27,6 +28,31 @@ uv add "chzzk-python[cli]"
27
28
  pip install "chzzk-python[cli]"
28
29
  ```
29
30
 
31
+ ### Docker
32
+
33
+ ```bash
34
+ # GitHub Container Registry에서 Pull
35
+ docker pull ghcr.io/hypn4/chzzk-python:latest
36
+
37
+ # CLI 명령어 실행
38
+ docker run --rm ghcr.io/hypn4/chzzk-python --help
39
+ docker run --rm ghcr.io/hypn4/chzzk-python auth --help
40
+
41
+ # 채팅 보기 (환경 변수 사용)
42
+ docker run --rm -it \
43
+ -e CHZZK_NID_AUT="your-nid-aut" \
44
+ -e CHZZK_NID_SES="your-nid-ses" \
45
+ ghcr.io/hypn4/chzzk-python chat watch CHANNEL_ID
46
+
47
+ # 대화형 채팅 (-it 플래그 필요)
48
+ docker run --rm -it \
49
+ -e CHZZK_NID_AUT="your-nid-aut" \
50
+ -e CHZZK_NID_SES="your-nid-ses" \
51
+ ghcr.io/hypn4/chzzk-python chat send CHANNEL_ID -i
52
+ ```
53
+
54
+ 사용 가능한 태그: `latest`, `X.Y.Z`, `X.Y`, `X`
55
+
30
56
  ## 빠른 시작
31
57
 
32
58
  ```python
@@ -320,6 +346,56 @@ async with AsyncUnofficialChatClient(
320
346
  await chat.run_forever()
321
347
  ```
322
348
 
349
+ ### 자동 재연결 및 모니터링 옵션
350
+
351
+ 비공식 채팅 클라이언트는 방송이 재시작되거나 채팅 채널이 변경될 때 자동으로 재연결됩니다. 이 동작을 커스터마이즈할 수 있습니다:
352
+
353
+ ```python
354
+ from chzzk.unofficial import AsyncUnofficialChatClient
355
+
356
+ chat = AsyncUnofficialChatClient(
357
+ nid_aut="...",
358
+ nid_ses="...",
359
+ # 자동 재연결 설정
360
+ auto_reconnect=True, # 자동 재연결 활성화 (기본값: True)
361
+ poll_interval=10.0, # 상태 폴링 간격 (초, 기본값: 10)
362
+ max_reconnect_attempts=5, # 최대 재연결 시도 횟수 (기본값: 5)
363
+ reconnect_backoff_base=1.0, # 백오프 기본 딜레이 (초, 기본값: 1)
364
+ reconnect_backoff_max=30.0, # 최대 백오프 딜레이 (초, 기본값: 30)
365
+ reconnect_wait_timeout=None, # 재연결 대기 타임아웃 (None = 무한 대기)
366
+ )
367
+
368
+ # 연결 상태 이벤트 핸들러
369
+ @chat.on_live
370
+ async def on_live(event):
371
+ print(f"방송 시작: {event.live_title}")
372
+
373
+ @chat.on_offline
374
+ async def on_offline(event):
375
+ print("방송 종료, 재시작 대기 중...")
376
+
377
+ @chat.on_reconnect
378
+ async def on_reconnect(event):
379
+ print(f"재연결 성공! (시도 {event.attempt}회)")
380
+
381
+ @chat.on_reconnect_error
382
+ async def on_reconnect_error(error):
383
+ print(f"재연결 실패: {error}")
384
+ ```
385
+
386
+ 장시간 모니터링 애플리케이션의 경우 무한 재시도 동작을 설정할 수 있습니다:
387
+
388
+ ```python
389
+ from chzzk.unofficial.chat.monitor import MonitorConfig
390
+
391
+ # 커스텀 모니터 설정 생성
392
+ config = MonitorConfig(
393
+ poll_interval_seconds=10.0, # 10초마다 폴링
394
+ max_consecutive_failures=10, # 10회 연속 실패 후 에러 콜백 호출
395
+ infinite_retry=True, # 실패 후에도 계속 모니터링
396
+ )
397
+ ```
398
+
323
399
  ### 네이버 쿠키 획득 방법
324
400
 
325
401
  1. 네이버에 로그인
@@ -394,6 +470,12 @@ chzzk chat watch CHANNEL_ID --output chat.txt --output-format txt
394
470
  # 생성 형식: {channel_id}_{live_id}_{YYYYMMDD}.jsonl
395
471
  chzzk chat watch CHANNEL_ID --output-dir ./logs
396
472
 
473
+ # 자동 재연결 비활성화
474
+ chzzk chat watch CHANNEL_ID --no-auto-reconnect
475
+
476
+ # 커스텀 폴링 간격 (초)
477
+ chzzk chat watch CHANNEL_ID --poll-interval 5
478
+
397
479
  # 단일 메시지 전송 (인증 필요)
398
480
  chzzk chat send CHANNEL_ID "안녕하세요!"
399
481
 
@@ -431,6 +513,8 @@ chzzk chat send CHANNEL_ID -i --offline
431
513
  | `CHZZK_CHAT_OUTPUT` | 기본 채팅 출력 파일 경로 |
432
514
  | `CHZZK_CHAT_OUTPUT_DIR` | 기본 채팅 출력 디렉토리 (파일명 자동 생성) |
433
515
  | `CHZZK_CHAT_OUTPUT_FORMAT` | 기본 채팅 출력 형식 (jsonl, txt) |
516
+ | `CHZZK_POLL_INTERVAL` | 라이브 상태 폴링 간격 (초, 기본값: 10) |
517
+ | `CHZZK_AUTO_RECONNECT` | 자동 재연결 활성화 (기본값: true, 비활성화: "false") |
434
518
 
435
519
  ## 예제 코드
436
520
 
@@ -18,3 +18,11 @@ CHZZK_NID_SES=your-nid-ses-cookie
18
18
  # 시청할 채널 ID (선택사항, 명령행에서도 지정 가능)
19
19
  # 채널 ID는 https://chzzk.naver.com/채널ID 형식의 URL에서 확인 가능
20
20
  CHZZK_CHANNEL_ID=
21
+
22
+ # Chat Monitoring Configuration
23
+ # Interval for polling live status in seconds (default: 10)
24
+ CHZZK_POLL_INTERVAL=
25
+
26
+ # Enable automatic reconnection when stream restarts (default: true)
27
+ # Set to "false" or "0" to disable
28
+ CHZZK_AUTO_RECONNECT=
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
28
28
  commit_id: COMMIT_ID
29
29
  __commit_id__: COMMIT_ID
30
30
 
31
- __version__ = version = '0.10.0'
32
- __version_tuple__ = version_tuple = (0, 10, 0)
31
+ __version__ = version = '0.12.0'
32
+ __version_tuple__ = version_tuple = (0, 12, 0)
33
33
 
34
34
  __commit_id__ = commit_id = None