chzzk-python 0.14.1__tar.gz → 0.14.2__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 (117) hide show
  1. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/PKG-INFO +1 -1
  2. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/_version.py +2 -2
  3. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/cli/commands/chat.py +144 -2
  4. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/.dockerignore +0 -0
  5. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/.env.example +0 -0
  6. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/.github/workflows/build.yml +0 -0
  7. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/.github/workflows/ci.yml +0 -0
  8. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/.github/workflows/docker.yml +0 -0
  9. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/.github/workflows/publish.yml +0 -0
  10. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/.gitignore +0 -0
  11. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/.python-version +0 -0
  12. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/Dockerfile +0 -0
  13. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/LICENSE +0 -0
  14. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/README.md +0 -0
  15. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/README_KO.md +0 -0
  16. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/chzzk.spec +0 -0
  17. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/docker-compose.yml +0 -0
  18. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/docs/unofficial-chat-websocket-protocol.md +0 -0
  19. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/examples/.env.example +0 -0
  20. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/examples/oauth_server.py +0 -0
  21. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/examples/realtime_chat.py +0 -0
  22. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/examples/realtime_chat_async.py +0 -0
  23. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/examples/session_management.py +0 -0
  24. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/examples/unofficial_chat.py +0 -0
  25. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/examples/unofficial_chat_async.py +0 -0
  26. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/main.py +0 -0
  27. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/pyproject.toml +0 -0
  28. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/scripts/build.py +0 -0
  29. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/__init__.py +0 -0
  30. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/api/__init__.py +0 -0
  31. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/api/base.py +0 -0
  32. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/api/category.py +0 -0
  33. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/api/channel.py +0 -0
  34. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/api/chat.py +0 -0
  35. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/api/live.py +0 -0
  36. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/api/restriction.py +0 -0
  37. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/api/session.py +0 -0
  38. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/api/user.py +0 -0
  39. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/auth/__init__.py +0 -0
  40. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/auth/models.py +0 -0
  41. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/auth/oauth.py +0 -0
  42. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/auth/token.py +0 -0
  43. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/cli/__init__.py +0 -0
  44. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/cli/commands/__init__.py +0 -0
  45. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/cli/commands/auth.py +0 -0
  46. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/cli/commands/live.py +0 -0
  47. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/cli/config.py +0 -0
  48. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/cli/formatter.py +0 -0
  49. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/cli/logging.py +0 -0
  50. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/cli/main.py +0 -0
  51. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/cli/timezone.py +0 -0
  52. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/cli/writers.py +0 -0
  53. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/client.py +0 -0
  54. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/constants.py +0 -0
  55. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/exceptions/__init__.py +0 -0
  56. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/exceptions/errors.py +0 -0
  57. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/http/__init__.py +0 -0
  58. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/http/_base.py +0 -0
  59. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/http/client.py +0 -0
  60. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/http/endpoints.py +0 -0
  61. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/logging.py +0 -0
  62. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/models/__init__.py +0 -0
  63. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/models/category.py +0 -0
  64. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/models/channel.py +0 -0
  65. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/models/chat.py +0 -0
  66. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/models/common.py +0 -0
  67. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/models/live.py +0 -0
  68. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/models/restriction.py +0 -0
  69. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/models/session.py +0 -0
  70. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/models/user.py +0 -0
  71. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/py.typed +0 -0
  72. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/realtime/__init__.py +0 -0
  73. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/realtime/client.py +0 -0
  74. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/unofficial/__init__.py +0 -0
  75. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/unofficial/api/__init__.py +0 -0
  76. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/unofficial/api/base.py +0 -0
  77. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/unofficial/api/chat.py +0 -0
  78. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/unofficial/api/live.py +0 -0
  79. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/unofficial/api/user.py +0 -0
  80. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/unofficial/auth/__init__.py +0 -0
  81. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/unofficial/auth/cookie.py +0 -0
  82. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/unofficial/chat/__init__.py +0 -0
  83. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/unofficial/chat/client.py +0 -0
  84. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/unofficial/chat/connection.py +0 -0
  85. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/unofficial/chat/handler.py +0 -0
  86. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/unofficial/chat/monitor.py +0 -0
  87. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/unofficial/client.py +0 -0
  88. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/unofficial/http/__init__.py +0 -0
  89. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/unofficial/http/_base.py +0 -0
  90. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/unofficial/http/client.py +0 -0
  91. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/unofficial/http/endpoints.py +0 -0
  92. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/unofficial/models/__init__.py +0 -0
  93. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/unofficial/models/chat.py +0 -0
  94. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/unofficial/models/live.py +0 -0
  95. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/unofficial/models/reconnect.py +0 -0
  96. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/src/chzzk/unofficial/models/user.py +0 -0
  97. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/tests/__init__.py +0 -0
  98. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/tests/api/__init__.py +0 -0
  99. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/tests/api/test_category.py +0 -0
  100. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/tests/api/test_channel.py +0 -0
  101. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/tests/api/test_chat.py +0 -0
  102. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/tests/api/test_live.py +0 -0
  103. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/tests/api/test_restriction.py +0 -0
  104. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/tests/api/test_session.py +0 -0
  105. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/tests/api/test_user.py +0 -0
  106. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/tests/auth/__init__.py +0 -0
  107. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/tests/auth/test_oauth.py +0 -0
  108. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/tests/cli/__init__.py +0 -0
  109. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/tests/cli/test_formatter.py +0 -0
  110. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/tests/cli/test_writers.py +0 -0
  111. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/tests/realtime/__init__.py +0 -0
  112. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/tests/realtime/test_client.py +0 -0
  113. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/tests/test_client.py +0 -0
  114. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/tests/unofficial/__init__.py +0 -0
  115. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/tests/unofficial/test_client.py +0 -0
  116. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/tests/unofficial/test_monitor.py +0 -0
  117. {chzzk_python-0.14.1 → chzzk_python-0.14.2}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: chzzk-python
3
- Version: 0.14.1
3
+ Version: 0.14.2
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
@@ -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.14.1'
32
- __version_tuple__ = version_tuple = (0, 14, 1)
31
+ __version__ = version = '0.14.2'
32
+ __version_tuple__ = version_tuple = (0, 14, 2)
33
33
 
34
34
  __commit_id__ = commit_id = None
@@ -254,7 +254,7 @@ def _run_watch_console(
254
254
  nonlocal writer, output_dir_writer, current_live_id
255
255
 
256
256
  # Rotate log file when live_id changes in output_dir mode
257
- if output_dir and event.live_id != current_live_id:
257
+ if output_dir and event.live_id is not None and event.live_id != current_live_id:
258
258
  try:
259
259
  open_date: str | None = None
260
260
  try:
@@ -310,6 +310,40 @@ def _run_watch_console(
310
310
 
311
311
  @chat.on_offline
312
312
  async def handle_offline(event: StatusChangeEvent) -> None:
313
+ nonlocal writer, output_dir_writer, current_live_id
314
+
315
+ # Rotate log file to offline file when stream ends
316
+ if output_dir and current_live_id is not None:
317
+ try:
318
+ new_writer, new_path = rotate_writer(
319
+ old_writer=output_dir_writer,
320
+ output_dir=output_dir,
321
+ channel_id=channel_id,
322
+ new_live_id=None,
323
+ open_date=None,
324
+ output_format=output_format,
325
+ )
326
+ output_dir_writer = new_writer
327
+ writer = new_writer
328
+ current_live_id = None
329
+
330
+ if json_output:
331
+ console.print(
332
+ json.dumps(
333
+ {
334
+ "event": "log_rotated",
335
+ "new_file": str(new_path),
336
+ "live_id": None,
337
+ }
338
+ )
339
+ )
340
+ else:
341
+ console.print(f"[dim]Log rotated: {new_path}[/dim]")
342
+ except OSError as e:
343
+ logger.warning(f"Failed to rotate log file on offline: {e}")
344
+ if not json_output:
345
+ console.print(f"[yellow]Warning:[/yellow] Log rotation failed: {e}")
346
+
313
347
  if json_output:
314
348
  console.print(
315
349
  json.dumps(
@@ -328,6 +362,43 @@ def _run_watch_console(
328
362
 
329
363
  @chat.on_reconnect
330
364
  async def handle_reconnect(event: ReconnectEvent) -> None:
365
+ nonlocal writer, output_dir_writer, current_live_id
366
+
367
+ # Compensate for on_live rotation miss (e.g. live_id was None at status change)
368
+ if output_dir and event.reason == ReconnectReason.STREAM_RESTARTED:
369
+ try:
370
+ new_live_detail = await client.live.get_live_detail(channel_id)
371
+ if (
372
+ new_live_detail.live_id is not None
373
+ and new_live_detail.live_id != current_live_id
374
+ ):
375
+ new_writer, new_path = rotate_writer(
376
+ old_writer=output_dir_writer,
377
+ output_dir=output_dir,
378
+ channel_id=channel_id,
379
+ new_live_id=new_live_detail.live_id,
380
+ open_date=new_live_detail.open_date,
381
+ output_format=output_format,
382
+ )
383
+ output_dir_writer = new_writer
384
+ writer = new_writer
385
+ current_live_id = new_live_detail.live_id
386
+
387
+ if json_output:
388
+ console.print(
389
+ json.dumps(
390
+ {
391
+ "event": "log_rotated",
392
+ "new_file": str(new_path),
393
+ "live_id": new_live_detail.live_id,
394
+ }
395
+ )
396
+ )
397
+ else:
398
+ console.print(f"[dim]Log rotated: {new_path}[/dim]")
399
+ except Exception:
400
+ logger.warning("Failed to rotate log on reconnect")
401
+
331
402
  if json_output:
332
403
  console.print(
333
404
  json.dumps(
@@ -735,7 +806,7 @@ def _run_interactive_chat_console(
735
806
  nonlocal writer, output_dir_writer, current_live_id
736
807
 
737
808
  # Rotate log file when live_id changes in output_dir mode
738
- if output_dir and event.live_id != current_live_id:
809
+ if output_dir and event.live_id is not None and event.live_id != current_live_id:
739
810
  try:
740
811
  open_date: str | None = None
741
812
  try:
@@ -791,6 +862,40 @@ def _run_interactive_chat_console(
791
862
 
792
863
  @chat.on_offline
793
864
  async def handle_offline(event: StatusChangeEvent) -> None:
865
+ nonlocal writer, output_dir_writer, current_live_id
866
+
867
+ # Rotate log file to offline file when stream ends
868
+ if output_dir and current_live_id is not None:
869
+ try:
870
+ new_writer, new_path = rotate_writer(
871
+ old_writer=output_dir_writer,
872
+ output_dir=output_dir,
873
+ channel_id=channel_id,
874
+ new_live_id=None,
875
+ open_date=None,
876
+ output_format=output_format,
877
+ )
878
+ output_dir_writer = new_writer
879
+ writer = new_writer
880
+ current_live_id = None
881
+
882
+ if json_output:
883
+ console.print(
884
+ json.dumps(
885
+ {
886
+ "event": "log_rotated",
887
+ "new_file": str(new_path),
888
+ "live_id": None,
889
+ }
890
+ )
891
+ )
892
+ else:
893
+ console.print(f"[dim]Log rotated: {new_path}[/dim]")
894
+ except OSError as e:
895
+ logger.warning(f"Failed to rotate log file on offline: {e}")
896
+ if not json_output:
897
+ console.print(f"[yellow]Warning:[/yellow] Log rotation failed: {e}")
898
+
794
899
  if json_output:
795
900
  console.print(
796
901
  json.dumps(
@@ -809,6 +914,43 @@ def _run_interactive_chat_console(
809
914
 
810
915
  @chat.on_reconnect
811
916
  async def handle_reconnect(event: ReconnectEvent) -> None:
917
+ nonlocal writer, output_dir_writer, current_live_id
918
+
919
+ # Compensate for on_live rotation miss (e.g. live_id was None at status change)
920
+ if output_dir and event.reason == ReconnectReason.STREAM_RESTARTED:
921
+ try:
922
+ new_live_detail = await client.live.get_live_detail(channel_id)
923
+ if (
924
+ new_live_detail.live_id is not None
925
+ and new_live_detail.live_id != current_live_id
926
+ ):
927
+ new_writer, new_path = rotate_writer(
928
+ old_writer=output_dir_writer,
929
+ output_dir=output_dir,
930
+ channel_id=channel_id,
931
+ new_live_id=new_live_detail.live_id,
932
+ open_date=new_live_detail.open_date,
933
+ output_format=output_format,
934
+ )
935
+ output_dir_writer = new_writer
936
+ writer = new_writer
937
+ current_live_id = new_live_detail.live_id
938
+
939
+ if json_output:
940
+ console.print(
941
+ json.dumps(
942
+ {
943
+ "event": "log_rotated",
944
+ "new_file": str(new_path),
945
+ "live_id": new_live_detail.live_id,
946
+ }
947
+ )
948
+ )
949
+ else:
950
+ console.print(f"[dim]Log rotated: {new_path}[/dim]")
951
+ except Exception:
952
+ logger.warning("Failed to rotate log on reconnect")
953
+
812
954
  if json_output:
813
955
  console.print(
814
956
  json.dumps(
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes