chutils 3.2.0__tar.gz → 3.3.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 (569) hide show
  1. {chutils-3.2.0 → chutils-3.3.0}/.chutilsignore +6 -6
  2. {chutils-3.2.0 → chutils-3.3.0}/PKG-INFO +4 -1
  3. {chutils-3.2.0 → chutils-3.3.0}/ai-lint.toml +6 -2
  4. {chutils-3.2.0 → chutils-3.3.0}/api_map.md +26 -12
  5. {chutils-3.2.0/conductor/tracks → chutils-3.3.0/conductor/archive}/dev_clean_20260707/plan.md +35 -35
  6. {chutils-3.2.0/conductor/archive/audit_20260702 → chutils-3.3.0/conductor/archive/http_streaming_20260720}/index.md +1 -1
  7. chutils-3.3.0/conductor/archive/http_streaming_20260720/metadata.json +8 -0
  8. chutils-3.3.0/conductor/archive/http_streaming_20260720/plan.md +34 -0
  9. chutils-3.3.0/conductor/archive/http_streaming_20260720/spec.md +36 -0
  10. {chutils-3.2.0/conductor/archive/db_manager_20260707 → chutils-3.3.0/conductor/archive/nodriver_interactions_20260720}/index.md +1 -1
  11. chutils-3.3.0/conductor/archive/nodriver_interactions_20260720/metadata.json +8 -0
  12. chutils-3.3.0/conductor/archive/nodriver_interactions_20260720/plan.md +30 -0
  13. chutils-3.3.0/conductor/archive/nodriver_interactions_20260720/spec.md +36 -0
  14. {chutils-3.2.0/conductor/archive/bulkhead_20260702 → chutils-3.3.0/conductor/archive/profile_warmer_20260720}/index.md +1 -1
  15. chutils-3.3.0/conductor/archive/profile_warmer_20260720/metadata.json +8 -0
  16. chutils-3.3.0/conductor/archive/profile_warmer_20260720/plan.md +31 -0
  17. chutils-3.3.0/conductor/archive/profile_warmer_20260720/spec.md +39 -0
  18. {chutils-3.2.0/conductor/tracks → chutils-3.3.0/conductor/archive}/store_20260702/plan.md +25 -25
  19. {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks.md +4 -18
  20. {chutils-3.2.0 → chutils-3.3.0}/conductor/workflow.md +4 -0
  21. {chutils-3.2.0 → chutils-3.3.0}/docs/audit.md +119 -119
  22. {chutils-3.2.0 → chutils-3.3.0}/docs/cli/db.md +73 -73
  23. {chutils-3.2.0 → chutils-3.3.0}/docs/cli/dev.md +47 -0
  24. {chutils-3.2.0 → chutils-3.3.0}/docs/dependencies.md +8 -7
  25. chutils-3.3.0/docs/http.md +154 -0
  26. {chutils-3.2.0 → chutils-3.3.0}/docs/recipes.md +52 -4
  27. {chutils-3.2.0 → chutils-3.3.0}/docs/scraping.md +93 -2
  28. chutils-3.3.0/docs/store.md +98 -0
  29. {chutils-3.2.0 → chutils-3.3.0}/examples/16_cloud_secret_managers.py +76 -76
  30. {chutils-3.2.0 → chutils-3.3.0}/project_index.json +7173 -3752
  31. {chutils-3.2.0 → chutils-3.3.0}/pyproject.toml +4 -1
  32. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/__init__.py +16 -0
  33. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/__init__.pyi +135 -7
  34. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/audit/__init__.py +44 -44
  35. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/audit/_hash.py +22 -22
  36. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/audit/api.py +193 -193
  37. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/audit/backends/__init__.py +6 -6
  38. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/audit/backends/base.py +46 -46
  39. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/audit/backends/file.py +123 -123
  40. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/audit/backends/postgres.py +224 -224
  41. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/audit/backends/sqlite.py +200 -200
  42. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/audit/schema.py +116 -116
  43. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/cache/base.py +35 -3
  44. chutils-3.3.0/src/chutils/cache/decorator.py +164 -0
  45. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/cache/in_memory.py +78 -7
  46. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/commands/dev/__init__.py +88 -0
  47. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/commands/dev/ai_lint.py +37 -0
  48. chutils-3.3.0/src/chutils/commands/dev/clean.py +124 -0
  49. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/commands/dev/dashboard.py +40 -40
  50. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/commands/dev/generate_context.py +98 -0
  51. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/commands/dev/hooks.py +41 -17
  52. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/commands/dev/profile_imports.py +47 -47
  53. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/commands/dev/setup_github_actions.py +147 -147
  54. chutils-3.3.0/src/chutils/commands/init.py +366 -0
  55. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/config/custom_providers.py +1 -1
  56. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/config/dev.py +125 -1
  57. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/config/manager.py +1 -1
  58. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/config/utils.py +92 -0
  59. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/db.py +267 -267
  60. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/decorators.py +1 -1
  61. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/__init__.py +4 -1
  62. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/ai_lint.py +189 -33
  63. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/ast_indexer.py +1 -1
  64. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/changelog_parser.py +194 -194
  65. chutils-3.3.0/src/chutils/dev/cleaner.py +221 -0
  66. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/dashboard/__init__.py +20 -20
  67. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/dashboard/indexer.py +218 -218
  68. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/dashboard/input.py +146 -146
  69. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/dashboard/tui.py +593 -593
  70. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/github_actions.py +91 -91
  71. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/profile_imports.py +351 -351
  72. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/project_metadata.py +42 -4
  73. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/rules/api_map.py +28 -11
  74. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/rules/decomposition.py +63 -6
  75. chutils-3.3.0/src/chutils/dev/rules/docstring.py +292 -0
  76. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/rules/integration.py +27 -9
  77. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/rules/upgrade_check.py +116 -116
  78. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/upgrade_client.py +121 -121
  79. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/version_detector.py +114 -114
  80. chutils-3.3.0/src/chutils/di/__init__.pyi +39 -0
  81. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/di/container.py +93 -35
  82. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/events/core.py +1 -1
  83. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/exceptions/audit.py +15 -15
  84. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/http/__init__.py +63 -51
  85. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/http/api.py +167 -167
  86. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/http/client.py +678 -678
  87. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/http/fallback.py +455 -455
  88. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/http/resilience.py +402 -402
  89. chutils-3.3.0/src/chutils/http/streaming.py +529 -0
  90. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/http/tracing.py +139 -139
  91. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/lifecycle.py +1 -1
  92. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/metrics/__init__.py +1 -1
  93. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/metrics/prometheus.py +1 -1
  94. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/plugins/core.py +1 -1
  95. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/scraping/humanize/__init__.py +5 -0
  96. chutils-3.3.0/src/chutils/scraping/humanize/actions.py +438 -0
  97. chutils-3.3.0/src/chutils/scraping/humanize/antidetect.py +221 -0
  98. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/scraping/humanize/math_utils.py +1 -1
  99. chutils-3.3.0/src/chutils/scraping/humanize/warmer.py +204 -0
  100. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/secret_manager/core.py +2 -2
  101. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/secret_manager/providers/__init__.py +1 -1
  102. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/secret_manager/providers/aws.py +134 -134
  103. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/secret_manager/providers/gcp.py +168 -168
  104. chutils-3.3.0/src/chutils/store/__init__.py +10 -0
  105. chutils-3.3.0/src/chutils/store/backends/__init__.py +11 -0
  106. chutils-3.3.0/src/chutils/store/backends/base.py +131 -0
  107. chutils-3.3.0/src/chutils/store/backends/memcached.py +211 -0
  108. chutils-3.3.0/src/chutils/store/backends/memory.py +156 -0
  109. chutils-3.3.0/src/chutils/store/backends/redis.py +191 -0
  110. chutils-3.3.0/src/chutils/store/decorator.py +84 -0
  111. chutils-3.3.0/src/chutils/store/manager.py +351 -0
  112. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/tasks/__init__.pyi +49 -49
  113. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/tasks/core.py +2 -2
  114. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/time.py +1 -0
  115. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/tracing.py +1 -1
  116. {chutils-3.2.0 → chutils-3.3.0}/tests/integration/test_setup_github_actions_integration.py +35 -35
  117. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/cli/test_cli_dev_cmd.py +4 -4
  118. chutils-3.3.0/tests/unit/cli/test_cli_init_interactive.py +76 -0
  119. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/cli/test_cli_setup_github_actions.py +92 -92
  120. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/core/test_cache.py +129 -0
  121. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/dev/test_ai_lint.py +200 -0
  122. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/dev/test_changelog_parser.py +95 -95
  123. chutils-3.3.0/tests/unit/dev/test_cleaner.py +188 -0
  124. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/dev/test_setup_github_actions.py +75 -75
  125. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/dev/test_upgrade_check_rule.py +55 -55
  126. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/dev/test_upgrade_client.py +106 -106
  127. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/dev/test_version_detector.py +102 -102
  128. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/di/test_di.py +42 -0
  129. chutils-3.3.0/tests/unit/test_antidetect.py +133 -0
  130. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_audit.py +365 -365
  131. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_audit_phase2.py +363 -363
  132. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_dashboard.py +401 -401
  133. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_db_init.py +256 -256
  134. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_db_operations.py +258 -258
  135. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_decorators_bulkhead.py +269 -269
  136. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_http_api.py +213 -213
  137. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_http_client.py +344 -344
  138. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_http_fallback.py +407 -407
  139. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_http_resilience.py +330 -330
  140. chutils-3.3.0/tests/unit/test_http_streaming.py +385 -0
  141. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_http_tracing.py +226 -226
  142. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_install_hooks.py +6 -2
  143. chutils-3.3.0/tests/unit/test_nodriver_humanize.py +147 -0
  144. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_profile_imports.py +214 -214
  145. chutils-3.3.0/tests/unit/test_profile_warmer.py +132 -0
  146. chutils-3.3.0/tests/unit/test_store_backends_external.py +112 -0
  147. chutils-3.3.0/tests/unit/test_store_integrations.py +87 -0
  148. chutils-3.3.0/tests/unit/test_store_manager.py +76 -0
  149. chutils-3.3.0/tests/unit/test_store_memory.py +80 -0
  150. {chutils-3.2.0 → chutils-3.3.0}/uv.lock +126 -2
  151. chutils-3.2.0/conductor/archive/audit_20260702/metadata.json +0 -8
  152. chutils-3.2.0/conductor/archive/audit_20260702/plan.md +0 -31
  153. chutils-3.2.0/conductor/archive/audit_20260702/spec.md +0 -53
  154. chutils-3.2.0/conductor/archive/bulkhead_20260702/metadata.json +0 -8
  155. chutils-3.2.0/conductor/archive/bulkhead_20260702/plan.md +0 -25
  156. chutils-3.2.0/conductor/archive/bulkhead_20260702/spec.md +0 -46
  157. chutils-3.2.0/conductor/archive/cloud_secret_managers_20260511/index.md +0 -5
  158. chutils-3.2.0/conductor/archive/cloud_secret_managers_20260511/metadata.json +0 -8
  159. chutils-3.2.0/conductor/archive/cloud_secret_managers_20260511/plan.md +0 -36
  160. chutils-3.2.0/conductor/archive/cloud_secret_managers_20260511/spec.md +0 -42
  161. chutils-3.2.0/conductor/archive/custom_config_providers_20260714/index.md +0 -5
  162. chutils-3.2.0/conductor/archive/custom_config_providers_20260714/metadata.json +0 -8
  163. chutils-3.2.0/conductor/archive/custom_config_providers_20260714/plan.md +0 -18
  164. chutils-3.2.0/conductor/archive/custom_config_providers_20260714/spec.md +0 -24
  165. chutils-3.2.0/conductor/archive/db_manager_20260707/metadata.json +0 -8
  166. chutils-3.2.0/conductor/archive/db_manager_20260707/plan.md +0 -29
  167. chutils-3.2.0/conductor/archive/db_manager_20260707/spec.md +0 -41
  168. chutils-3.2.0/conductor/archive/db_migrations_cli_20260707/index.md +0 -5
  169. chutils-3.2.0/conductor/archive/db_migrations_cli_20260707/metadata.json +0 -8
  170. chutils-3.2.0/conductor/archive/db_migrations_cli_20260707/plan.md +0 -27
  171. chutils-3.2.0/conductor/archive/db_migrations_cli_20260707/spec.md +0 -40
  172. chutils-3.2.0/conductor/archive/dev_dashboard_20260610/index.md +0 -5
  173. chutils-3.2.0/conductor/archive/dev_dashboard_20260610/metadata.json +0 -8
  174. chutils-3.2.0/conductor/archive/dev_dashboard_20260610/plan.md +0 -39
  175. chutils-3.2.0/conductor/archive/dev_dashboard_20260610/spec.md +0 -43
  176. chutils-3.2.0/conductor/archive/http_20260702/index.md +0 -5
  177. chutils-3.2.0/conductor/archive/http_20260702/metadata.json +0 -8
  178. chutils-3.2.0/conductor/archive/http_20260702/plan.md +0 -28
  179. chutils-3.2.0/conductor/archive/http_20260702/spec.md +0 -51
  180. chutils-3.2.0/conductor/archive/profile_imports_20260610/index.md +0 -5
  181. chutils-3.2.0/conductor/archive/profile_imports_20260610/metadata.json +0 -8
  182. chutils-3.2.0/conductor/archive/profile_imports_20260610/plan.md +0 -42
  183. chutils-3.2.0/conductor/archive/profile_imports_20260610/spec.md +0 -40
  184. chutils-3.2.0/conductor/archive/setup_github_actions_20260714/index.md +0 -5
  185. chutils-3.2.0/conductor/archive/setup_github_actions_20260714/metadata.json +0 -8
  186. chutils-3.2.0/conductor/archive/setup_github_actions_20260714/plan.md +0 -28
  187. chutils-3.2.0/conductor/archive/setup_github_actions_20260714/spec.md +0 -27
  188. chutils-3.2.0/src/chutils/cache/decorator.py +0 -94
  189. chutils-3.2.0/src/chutils/commands/init.py +0 -151
  190. chutils-3.2.0/src/chutils/dev/rules/docstring.py +0 -218
  191. chutils-3.2.0/src/chutils/scraping/humanize/actions.py +0 -268
  192. chutils-3.2.0/src/chutils/scraping/humanize/antidetect.py +0 -123
  193. chutils-3.2.0/tests/unit/test_antidetect.py +0 -41
  194. {chutils-3.2.0 → chutils-3.3.0}/.gitattributes +0 -0
  195. {chutils-3.2.0 → chutils-3.3.0}/.github/workflows/ci.yml +0 -0
  196. {chutils-3.2.0 → chutils-3.3.0}/.github/workflows/publish-docs.yml +0 -0
  197. {chutils-3.2.0 → chutils-3.3.0}/.gitignore +0 -0
  198. {chutils-3.2.0 → chutils-3.3.0}/CODE_OF_CONDUCT.md +0 -0
  199. {chutils-3.2.0 → chutils-3.3.0}/CONTRIBUTING.md +0 -0
  200. {chutils-3.2.0 → chutils-3.3.0}/GEMINI.md +0 -0
  201. {chutils-3.2.0 → chutils-3.3.0}/LICENSE +0 -0
  202. {chutils-3.2.0 → chutils-3.3.0}/README.md +0 -0
  203. {chutils-3.2.0 → chutils-3.3.0}/benchmarks/cold_start.py +0 -0
  204. {chutils-3.2.0 → chutils-3.3.0}/conductor/.gitignore +0 -0
  205. {chutils-3.2.0 → chutils-3.3.0}/conductor/GEMINI.md +0 -0
  206. {chutils-3.2.0/conductor/tracks → chutils-3.3.0/conductor/archive}/cache_invalidation_20260714/index.md +0 -0
  207. {chutils-3.2.0/conductor/tracks → chutils-3.3.0/conductor/archive}/cache_invalidation_20260714/metadata.json +0 -0
  208. {chutils-3.2.0/conductor/tracks → chutils-3.3.0/conductor/archive}/cache_invalidation_20260714/plan.md +0 -0
  209. {chutils-3.2.0/conductor/tracks → chutils-3.3.0/conductor/archive}/cache_invalidation_20260714/spec.md +0 -0
  210. {chutils-3.2.0/conductor/tracks → chutils-3.3.0/conductor/archive}/dev_clean_20260707/index.md +0 -0
  211. {chutils-3.2.0/conductor/tracks → chutils-3.3.0/conductor/archive}/dev_clean_20260707/metadata.json +0 -0
  212. {chutils-3.2.0/conductor/tracks → chutils-3.3.0/conductor/archive}/dev_clean_20260707/spec.md +0 -0
  213. {chutils-3.2.0/conductor/tracks → chutils-3.3.0/conductor/archive}/store_20260702/index.md +0 -0
  214. {chutils-3.2.0/conductor/tracks → chutils-3.3.0/conductor/archive}/store_20260702/metadata.json +0 -0
  215. {chutils-3.2.0/conductor/tracks → chutils-3.3.0/conductor/archive}/store_20260702/spec.md +0 -0
  216. {chutils-3.2.0 → chutils-3.3.0}/conductor/code_styleguides/python.md +0 -0
  217. {chutils-3.2.0 → chutils-3.3.0}/conductor/index.md +0 -0
  218. {chutils-3.2.0 → chutils-3.3.0}/conductor/product-guidelines.md +0 -0
  219. {chutils-3.2.0 → chutils-3.3.0}/conductor/product.md +0 -0
  220. {chutils-3.2.0 → chutils-3.3.0}/conductor/setup_state.json +0 -0
  221. {chutils-3.2.0 → chutils-3.3.0}/conductor/tech-stack.md +0 -0
  222. {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/ai_manifests_few_shot_20260713/index.md +0 -0
  223. {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/ai_manifests_few_shot_20260713/metadata.json +0 -0
  224. {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/ai_manifests_few_shot_20260713/plan.md +0 -0
  225. {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/ai_manifests_few_shot_20260713/spec.md +0 -0
  226. {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/config_remote_push_20260702/index.md +0 -0
  227. {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/config_remote_push_20260702/metadata.json +0 -0
  228. {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/config_remote_push_20260702/plan.md +0 -0
  229. {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/config_remote_push_20260702/spec.md +0 -0
  230. {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/dev_watch_20260702/index.md +0 -0
  231. {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/dev_watch_20260702/metadata.json +0 -0
  232. {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/dev_watch_20260702/plan.md +0 -0
  233. {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/dev_watch_20260702/spec.md +0 -0
  234. {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/docstring_audit_20260521/index.md +0 -0
  235. {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/docstring_audit_20260521/metadata.json +0 -0
  236. {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/docstring_audit_20260521/plan.md +0 -0
  237. {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/docstring_audit_20260521/spec.md +0 -0
  238. {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/fallback_alias_20260707/index.md +0 -0
  239. {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/fallback_alias_20260707/metadata.json +0 -0
  240. {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/fallback_alias_20260707/plan.md +0 -0
  241. {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/fallback_alias_20260707/spec.md +0 -0
  242. {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/qt_integration_20260521/index.md +0 -0
  243. {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/qt_integration_20260521/metadata.json +0 -0
  244. {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/qt_integration_20260521/plan.md +0 -0
  245. {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/qt_integration_20260521/spec.md +0 -0
  246. {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/qt_typed_signals_20260521/index.md +0 -0
  247. {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/qt_typed_signals_20260521/metadata.json +0 -0
  248. {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/qt_typed_signals_20260521/plan.md +0 -0
  249. {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/qt_typed_signals_20260521/spec.md +0 -0
  250. {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/scraping_concurrency_20260707/index.md +0 -0
  251. {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/scraping_concurrency_20260707/metadata.json +0 -0
  252. {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/scraping_concurrency_20260707/plan.md +0 -0
  253. {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/scraping_concurrency_20260707/spec.md +0 -0
  254. {chutils-3.2.0 → chutils-3.3.0}/docs/CODE_OF_CONDUCT_RU.md +0 -0
  255. {chutils-3.2.0 → chutils-3.3.0}/docs/CONTRIBUTING_RU.md +0 -0
  256. {chutils-3.2.0 → chutils-3.3.0}/docs/INTEGRATION_AI.md +0 -0
  257. {chutils-3.2.0 → chutils-3.3.0}/docs/README_RU.md +0 -0
  258. {chutils-3.2.0 → chutils-3.3.0}/docs/ai_examples/README.md +0 -0
  259. {chutils-3.2.0 → chutils-3.3.0}/docs/ai_examples/configuration/README.md +0 -0
  260. {chutils-3.2.0 → chutils-3.3.0}/docs/ai_examples/configuration/bad_pattern.py +0 -0
  261. {chutils-3.2.0 → chutils-3.3.0}/docs/ai_examples/configuration/good_pattern.py +0 -0
  262. {chutils-3.2.0 → chutils-3.3.0}/docs/ai_examples/error_handling/README.md +0 -0
  263. {chutils-3.2.0 → chutils-3.3.0}/docs/ai_examples/error_handling/bad_pattern.py +0 -0
  264. {chutils-3.2.0 → chutils-3.3.0}/docs/ai_examples/error_handling/good_pattern.py +0 -0
  265. {chutils-3.2.0 → chutils-3.3.0}/docs/ai_examples/logging/README.md +0 -0
  266. {chutils-3.2.0 → chutils-3.3.0}/docs/ai_examples/logging/bad_pattern.py +0 -0
  267. {chutils-3.2.0 → chutils-3.3.0}/docs/ai_examples/logging/good_pattern.py +0 -0
  268. {chutils-3.2.0 → chutils-3.3.0}/docs/ai_examples/optional_deps/README.md +0 -0
  269. {chutils-3.2.0 → chutils-3.3.0}/docs/ai_examples/optional_deps/bad_pattern.py +0 -0
  270. {chutils-3.2.0 → chutils-3.3.0}/docs/ai_examples/optional_deps/good_pattern.py +0 -0
  271. {chutils-3.2.0 → chutils-3.3.0}/docs/ai_examples/secrets/README.md +0 -0
  272. {chutils-3.2.0 → chutils-3.3.0}/docs/ai_examples/secrets/bad_pattern.py +0 -0
  273. {chutils-3.2.0 → chutils-3.3.0}/docs/ai_examples/secrets/good_pattern.py +0 -0
  274. {chutils-3.2.0 → chutils-3.3.0}/docs/ai_hints.md +0 -0
  275. {chutils-3.2.0 → chutils-3.3.0}/docs/ai_lint.md +0 -0
  276. {chutils-3.2.0 → chutils-3.3.0}/docs/api.md +0 -0
  277. {chutils-3.2.0 → chutils-3.3.0}/docs/captcha.md +0 -0
  278. {chutils-3.2.0 → chutils-3.3.0}/docs/cli/config.md +0 -0
  279. {chutils-3.2.0 → chutils-3.3.0}/docs/cli/env.md +0 -0
  280. {chutils-3.2.0 → chutils-3.3.0}/docs/cli/index.md +0 -0
  281. {chutils-3.2.0 → chutils-3.3.0}/docs/cli/init.md +0 -0
  282. {chutils-3.2.0 → chutils-3.3.0}/docs/cli/pypi.md +0 -0
  283. {chutils-3.2.0 → chutils-3.3.0}/docs/cli/secrets.md +0 -0
  284. {chutils-3.2.0 → chutils-3.3.0}/docs/cli/show_paths.md +0 -0
  285. {chutils-3.2.0 → chutils-3.3.0}/docs/cli/template.md +0 -0
  286. {chutils-3.2.0 → chutils-3.3.0}/docs/cli/validate.md +0 -0
  287. {chutils-3.2.0 → chutils-3.3.0}/docs/custom_config_providers.md +0 -0
  288. {chutils-3.2.0 → chutils-3.3.0}/docs/index.md +0 -0
  289. {chutils-3.2.0 → chutils-3.3.0}/docs/migration.md +0 -0
  290. {chutils-3.2.0 → chutils-3.3.0}/docs/plugins.md +0 -0
  291. {chutils-3.2.0 → chutils-3.3.0}/docs/testing.md +0 -0
  292. {chutils-3.2.0 → chutils-3.3.0}/docs/web.md +0 -0
  293. {chutils-3.2.0 → chutils-3.3.0}/examples/.env +0 -0
  294. {chutils-3.2.0 → chutils-3.3.0}/examples/01_configuration.py +0 -0
  295. {chutils-3.2.0 → chutils-3.3.0}/examples/02_logging.py +0 -0
  296. {chutils-3.2.0 → chutils-3.3.0}/examples/03_secrets.py +0 -0
  297. {chutils-3.2.0 → chutils-3.3.0}/examples/04_full_example.py +0 -0
  298. {chutils-3.2.0 → chutils-3.3.0}/examples/05_different_log_levels.py +0 -0
  299. {chutils-3.2.0 → chutils-3.3.0}/examples/06_local_config_override.py +0 -0
  300. {chutils-3.2.0 → chutils-3.3.0}/examples/07_decorators_example.py +0 -0
  301. {chutils-3.2.0 → chutils-3.3.0}/examples/08_multiple_loggers_example.py +0 -0
  302. {chutils-3.2.0 → chutils-3.3.0}/examples/09_disable_keyring.py +0 -0
  303. {chutils-3.2.0 → chutils-3.3.0}/examples/10_universal_env_override.py +0 -0
  304. {chutils-3.2.0 → chutils-3.3.0}/examples/11_retry_decorator.py +0 -0
  305. {chutils-3.2.0 → chutils-3.3.0}/examples/12_secret_masking.py +0 -0
  306. {chutils-3.2.0 → chutils-3.3.0}/examples/13_pydantic_validation.py +0 -0
  307. {chutils-3.2.0 → chutils-3.3.0}/examples/15_context_logging.py +0 -0
  308. {chutils-3.2.0 → chutils-3.3.0}/examples/17_timeout_decorator.py +0 -0
  309. {chutils-3.2.0 → chutils-3.3.0}/examples/18_config_hot_reload.py +0 -0
  310. {chutils-3.2.0 → chutils-3.3.0}/examples/19_remote_config.py +0 -0
  311. {chutils-3.2.0 → chutils-3.3.0}/examples/20_opentelemetry_tracing.py +0 -0
  312. {chutils-3.2.0 → chutils-3.3.0}/examples/21_config_diagnostics.py +0 -0
  313. {chutils-3.2.0 → chutils-3.3.0}/examples/22_circuit_breaker_decorator.py +0 -0
  314. {chutils-3.2.0 → chutils-3.3.0}/examples/22_safe_path_resolution.py +0 -0
  315. {chutils-3.2.0 → chutils-3.3.0}/examples/23_event_bus.py +0 -0
  316. {chutils-3.2.0 → chutils-3.3.0}/examples/24_task_scheduler.py +0 -0
  317. {chutils-3.2.0 → chutils-3.3.0}/examples/25_testing_fixtures_example.py +0 -0
  318. {chutils-3.2.0 → chutils-3.3.0}/examples/26_metrics_prometheus.py +0 -0
  319. {chutils-3.2.0 → chutils-3.3.0}/examples/27_rate_limiting.py +0 -0
  320. {chutils-3.2.0 → chutils-3.3.0}/examples/28_dependency_injection.py +0 -0
  321. {chutils-3.2.0 → chutils-3.3.0}/examples/captcha_solvers_usage.py +0 -0
  322. {chutils-3.2.0 → chutils-3.3.0}/examples/config.yml +0 -0
  323. {chutils-3.2.0 → chutils-3.3.0}/examples/scraping_humanize_usage.py +0 -0
  324. {chutils-3.2.0 → chutils-3.3.0}/examples/web_client_usage.py +0 -0
  325. {chutils-3.2.0 → chutils-3.3.0}/mkdocs.yml +0 -0
  326. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/__main__.py +0 -0
  327. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/antigravity.md +0 -0
  328. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/cache/__init__.py +0 -0
  329. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/cache/utils.py +0 -0
  330. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/cli.py +0 -0
  331. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/cli_booster.py +0 -0
  332. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/cli_utils.py +0 -0
  333. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/commands/__init__.py +0 -0
  334. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/commands/base.py +0 -0
  335. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/commands/config.py +0 -0
  336. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/commands/db.py +0 -0
  337. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/commands/dev/base.py +0 -0
  338. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/commands/dev/chat_context.py +0 -0
  339. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/commands/dev/diagnostics.py +0 -0
  340. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/commands/dev/few_shot.py +0 -0
  341. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/commands/dev/mock.py +0 -0
  342. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/commands/dev/scaffold.py +0 -0
  343. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/commands/dev/sync_env.py +0 -0
  344. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/commands/env.py +0 -0
  345. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/commands/paths.py +0 -0
  346. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/commands/pypi.py +0 -0
  347. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/commands/secrets.py +0 -0
  348. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/commands/template.py +0 -0
  349. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/commands/utils.py +0 -0
  350. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/commands/validate.py +0 -0
  351. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/config/GEMINI.md +0 -0
  352. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/config/__init__.py +0 -0
  353. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/config/ast_fallback_parser.py +0 -0
  354. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/config/core.py +0 -0
  355. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/config/diagnostics.py +0 -0
  356. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/config/generator.py +0 -0
  357. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/config/getters.py +0 -0
  358. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/config/providers.py +0 -0
  359. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/config/schema.py +0 -0
  360. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/config/watcher.py +0 -0
  361. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/context.py +0 -0
  362. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/crypto.py +0 -0
  363. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/chat_context.py +0 -0
  364. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/constants.py +0 -0
  365. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/env_parser.py +0 -0
  366. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/env_sync.py +0 -0
  367. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/few_shot/__init__.py +0 -0
  368. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/few_shot/detector.py +0 -0
  369. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/few_shot/models.py +0 -0
  370. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/few_shot/renderer.py +0 -0
  371. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/few_shot/writer.py +0 -0
  372. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/mock_server.py +0 -0
  373. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/models/__init__.py +0 -0
  374. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/models/base.py +0 -0
  375. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/models/index.py +0 -0
  376. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/models/node.py +0 -0
  377. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/models/symbol.py +0 -0
  378. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/rules/__init__.py +0 -0
  379. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/rules/dependency_sync.py +0 -0
  380. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/rules/env.py +0 -0
  381. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/rules/linter_coverage.py +0 -0
  382. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/rules/manifest.py +0 -0
  383. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/rules/security.py +0 -0
  384. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/scaffold.py +0 -0
  385. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/di/__init__.py +0 -0
  386. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/diagnostics/__init__.py +0 -0
  387. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/diagnostics/manager.py +0 -0
  388. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/diagnostics/models.py +0 -0
  389. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/diagnostics/web.py +0 -0
  390. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/env.py +0 -0
  391. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/env.pyi +0 -0
  392. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/events/__init__.py +0 -0
  393. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/exceptions/__init__.py +0 -0
  394. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/exceptions/base.py +0 -0
  395. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/exceptions/cache.py +0 -0
  396. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/exceptions/config.py +0 -0
  397. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/exceptions/di.py +0 -0
  398. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/exceptions/events.py +0 -0
  399. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/exceptions/logger.py +0 -0
  400. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/exceptions/resilience.py +0 -0
  401. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/exceptions/secrets.py +0 -0
  402. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/exceptions/system.py +0 -0
  403. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/exceptions/validation.py +0 -0
  404. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/exceptions/watcher.py +0 -0
  405. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/features.py +0 -0
  406. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/fs.py +0 -0
  407. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/logger/GEMINI.md +0 -0
  408. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/logger/__init__.py +0 -0
  409. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/logger/core.py +0 -0
  410. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/logger/formatters.py +0 -0
  411. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/logger/handlers.py +0 -0
  412. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/logger/internal/builder.py +0 -0
  413. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/logger/internal/levels.py +0 -0
  414. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/logger/internal/utils.py +0 -0
  415. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/logger/masking.py +0 -0
  416. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/metrics/base.py +0 -0
  417. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/metrics/in_memory.py +0 -0
  418. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/metrics/timer.py +0 -0
  419. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/plugins/__init__.py +0 -0
  420. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/plugins/interfaces.py +0 -0
  421. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/scraping/__init__.py +0 -0
  422. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/scraping/captcha/__init__.py +0 -0
  423. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/scraping/captcha/anticaptcha.py +0 -0
  424. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/scraping/captcha/base.py +0 -0
  425. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/scraping/captcha/capmonster.py +0 -0
  426. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/scraping/captcha/exceptions.py +0 -0
  427. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/scraping/captcha/rucaptcha.py +0 -0
  428. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/secret_manager/GEMINI.md +0 -0
  429. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/secret_manager/__init__.py +0 -0
  430. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/secret_manager/providers/base.py +0 -0
  431. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/secret_manager/providers/dotenv.py +0 -0
  432. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/secret_manager/providers/env.py +0 -0
  433. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/secret_manager/providers/keyring_provider.py +0 -0
  434. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/tasks/__init__.py +0 -0
  435. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/testing/__init__.py +0 -0
  436. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/testing/fixtures.py +0 -0
  437. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/text.py +0 -0
  438. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/typing.py +0 -0
  439. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/validation.py +0 -0
  440. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/validation.pyi +0 -0
  441. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/web/__init__.py +0 -0
  442. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/web/client.py +0 -0
  443. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/web/proxy_pool.py +0 -0
  444. {chutils-3.2.0 → chutils-3.3.0}/src/chutils/web/user_agent.py +0 -0
  445. {chutils-3.2.0 → chutils-3.3.0}/tests/conftest.py +0 -0
  446. {chutils-3.2.0 → chutils-3.3.0}/tests/integration/__init__.py +0 -0
  447. {chutils-3.2.0 → chutils-3.3.0}/tests/integration/test_ai_lint_integration.py +0 -0
  448. {chutils-3.2.0 → chutils-3.3.0}/tests/integration/test_cli_e2e.py +0 -0
  449. {chutils-3.2.0 → chutils-3.3.0}/tests/integration/test_db_migrations.py +0 -0
  450. {chutils-3.2.0 → chutils-3.3.0}/tests/integration/test_event_loops.py +0 -0
  451. {chutils-3.2.0 → chutils-3.3.0}/tests/integration/test_examples.py +0 -0
  452. {chutils-3.2.0 → chutils-3.3.0}/tests/integration/test_hooks_integration.py +0 -0
  453. {chutils-3.2.0 → chutils-3.3.0}/tests/integration/test_masking_integration.py +0 -0
  454. {chutils-3.2.0 → chutils-3.3.0}/tests/integration/test_otel_tracing.py +0 -0
  455. {chutils-3.2.0 → chutils-3.3.0}/tests/integration/test_remote_config_integration.py +0 -0
  456. {chutils-3.2.0 → chutils-3.3.0}/tests/manual/manual_test_cli_booster.py +0 -0
  457. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/cli/conftest.py +0 -0
  458. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/cli/test_cli.py +0 -0
  459. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/cli/test_cli_booster.py +0 -0
  460. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/cli/test_cli_config.py +0 -0
  461. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/cli/test_cli_config_cmd.py +0 -0
  462. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/cli/test_cli_config_schema.py +0 -0
  463. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/cli/test_cli_dev.py +0 -0
  464. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/cli/test_cli_dev_tree.py +0 -0
  465. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/cli/test_cli_diagnostics.py +0 -0
  466. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/cli/test_cli_extras_suggestion.py +0 -0
  467. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/cli/test_cli_init.py +0 -0
  468. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/cli/test_cli_paths.py +0 -0
  469. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/cli/test_cli_pypi.py +0 -0
  470. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/cli/test_cli_rich.py +0 -0
  471. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/cli/test_cli_rich_width.py +0 -0
  472. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/cli/test_cli_secrets.py +0 -0
  473. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/cli/test_cli_template.py +0 -0
  474. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/cli/test_cli_utils_internal.py +0 -0
  475. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/cli/test_cli_validate.py +0 -0
  476. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/config/test_config.py +0 -0
  477. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/config/test_config_ast_parser.py +0 -0
  478. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/config/test_config_dev.py +0 -0
  479. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/config/test_config_diagnostics.py +0 -0
  480. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/config/test_config_env.py +0 -0
  481. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/config/test_config_env_loading.py +0 -0
  482. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/config/test_config_generator.py +0 -0
  483. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/config/test_config_json.py +0 -0
  484. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/config/test_config_pydantic.py +0 -0
  485. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/config/test_config_required.py +0 -0
  486. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/config/test_config_schema.py +0 -0
  487. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/config/test_config_tracing.py +0 -0
  488. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/config/test_config_universal_env.py +0 -0
  489. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/config/test_config_utils.py +0 -0
  490. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/config/test_config_validation_group.py +0 -0
  491. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/config/test_config_watcher.py +0 -0
  492. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/config/test_custom_config_providers.py +0 -0
  493. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/config/test_priority_unification.py +0 -0
  494. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/config/test_remote_config.py +0 -0
  495. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/core/test_ast_indexer.py +0 -0
  496. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/core/test_ast_indexer_abstract.py +0 -0
  497. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/core/test_ast_indexer_graph.py +0 -0
  498. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/core/test_ast_indexer_layers.py +0 -0
  499. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/core/test_ast_indexer_metadata.py +0 -0
  500. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/core/test_dev_models.py +0 -0
  501. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/core/test_exceptions.py +0 -0
  502. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/core/test_features.py +0 -0
  503. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/core/test_fs.py +0 -0
  504. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/core/test_lifecycle.py +0 -0
  505. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/core/test_thread_safety.py +0 -0
  506. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/core/test_time.py +0 -0
  507. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/decorators/test_decorator_circuit_breaker.py +0 -0
  508. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/decorators/test_decorator_retry.py +0 -0
  509. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/decorators/test_decorator_timeout.py +0 -0
  510. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/decorators/test_decorators.py +0 -0
  511. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/decorators/test_rate_limit.py +0 -0
  512. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/dev/test_ai_lint_staged.py +0 -0
  513. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/dev/test_chat_context.py +0 -0
  514. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/dev/test_env_parser.py +0 -0
  515. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/dev/test_env_sync.py +0 -0
  516. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/dev/test_generate_few_shot.py +0 -0
  517. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/dev/test_linter_coverage_rule.py +0 -0
  518. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/dev/test_mock_server.py +0 -0
  519. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/dev/test_scaffold.py +0 -0
  520. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/events/test_event_bus.py +0 -0
  521. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/logger/conftest.py +0 -0
  522. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/logger/test_basics.py +0 -0
  523. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/logger/test_compression.py +0 -0
  524. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/logger/test_config_sections.py +0 -0
  525. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/logger/test_configuration.py +0 -0
  526. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/logger/test_context.py +0 -0
  527. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/logger/test_env_control.py +0 -0
  528. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/logger/test_files.py +0 -0
  529. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/logger/test_json_format.py +0 -0
  530. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/logger/test_logger_rich_width.py +0 -0
  531. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/logger/test_masking.py +0 -0
  532. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/logger/test_performance_security.py +0 -0
  533. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/logger/test_rich.py +0 -0
  534. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/logger/test_rotation.py +0 -0
  535. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/metrics/test_metrics.py +0 -0
  536. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/plugins/test_integration.py +0 -0
  537. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/plugins/test_interfaces.py +0 -0
  538. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/plugins/test_plugins.py +0 -0
  539. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/secret_manager/test_secret_manager.py +0 -0
  540. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/secret_manager/test_secret_manager_env.py +0 -0
  541. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/secret_manager/test_secret_manager_providers.py +0 -0
  542. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/secret_manager/test_secrets_required.py +0 -0
  543. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/tasks/test_scheduler.py +0 -0
  544. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_ai_lint_ignore.py +0 -0
  545. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_anticaptcha.py +0 -0
  546. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_async_web_client.py +0 -0
  547. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_capmonster.py +0 -0
  548. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_captcha_base.py +0 -0
  549. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_captcha_imports.py +0 -0
  550. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_cli_db.py +0 -0
  551. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_crypto.py +0 -0
  552. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_crypto_dependencies.py +0 -0
  553. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_diagnostics.py +0 -0
  554. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_env.py +0 -0
  555. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_events_exception_group.py +0 -0
  556. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_humanize_math.py +0 -0
  557. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_minimal_imports.py +0 -0
  558. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_playwright_humanize.py +0 -0
  559. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_proxy_pool.py +0 -0
  560. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_rucaptcha.py +0 -0
  561. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_scraping_imports.py +0 -0
  562. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_selenium_humanize.py +0 -0
  563. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_text.py +0 -0
  564. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_text_dependencies.py +0 -0
  565. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_user_agent.py +0 -0
  566. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_validation.py +0 -0
  567. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_web_client.py +0 -0
  568. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_web_imports.py +0 -0
  569. {chutils-3.2.0 → chutils-3.3.0}/tests/unit/testing/test_fixtures.py +0 -0
@@ -1,6 +1,6 @@
1
- .idea/
2
- .pytest_cache/
3
- .venv/
4
- dist/
5
- build/
6
- *.egg-info/
1
+ .idea/
2
+ .pytest_cache/
3
+ .venv/
4
+ dist/
5
+ build/
6
+ *.egg-info/
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: chutils
3
- Version: 3.2.0
3
+ Version: 3.3.0
4
4
  Summary: Набор простых и удобных утилит для Python, который избавляет от рутины при работе с конфигурацией и логированием в новых проектах.
5
5
  Author-email: Chu4hel <sergeiivanov636@gmail.com>
6
6
  License-Expression: MIT
@@ -41,6 +41,7 @@ Requires-Dist: rapidfuzz>=3.9.0; extra == 'full'
41
41
  Requires-Dist: rich>=15.0.0; extra == 'full'
42
42
  Requires-Dist: selenium>=4.27.0; extra == 'full'
43
43
  Requires-Dist: watchdog>=6.0.0; extra == 'full'
44
+ Requires-Dist: websockets>=14.0.0; extra == 'full'
44
45
  Provides-Extra: gcp
45
46
  Requires-Dist: google-cloud-secret-manager>=2.20.0; extra == 'gcp'
46
47
  Provides-Extra: json
@@ -68,6 +69,8 @@ Provides-Extra: watch
68
69
  Requires-Dist: watchdog>=6.0.0; extra == 'watch'
69
70
  Provides-Extra: web
70
71
  Requires-Dist: httpx>=0.27.0; extra == 'web'
72
+ Provides-Extra: websockets
73
+ Requires-Dist: websockets>=14.0.0; extra == 'websockets'
71
74
  Description-Content-Type: text/markdown
72
75
 
73
76
  [Русская версия](docs/README_RU.md)
@@ -26,11 +26,13 @@
26
26
  "src/chutils/secret_manager/**/*.py" = ["docs/api.md"]
27
27
 
28
28
  # ---------------------------------------------------------------------------
29
- # Модуль cache
29
+ # Модуль cache и store
30
30
  # ---------------------------------------------------------------------------
31
31
 
32
32
  # Изменения кэша влияют на API и рецепты (там есть примеры использования)
33
33
  "src/chutils/cache/**/*.py" = ["docs/api.md", "docs/recipes.md"]
34
+ "src/chutils/store/**/*.py" = ["docs/store.md", "docs/api.md"]
35
+ "new:src/chutils/store/**/*.py" = ["docs/store.md"]
34
36
 
35
37
  # ---------------------------------------------------------------------------
36
38
  # Модуль events (шина событий)
@@ -144,9 +146,11 @@
144
146
  "src/chutils/testing/**/*.py" = ["docs/testing.md"]
145
147
 
146
148
  # ---------------------------------------------------------------------------
147
- # HTTP-клиент
149
+ # HTTP-клиент и Стриминг
148
150
  # ---------------------------------------------------------------------------
149
151
 
152
+ "src/chutils/http/**/*.py" = ["docs/http.md", "docs/api.md"]
153
+ "new:src/chutils/http/streaming.py" = ["docs/http.md"]
150
154
  "src/chutils/web/**/*.py" = ["docs/web.md"]
151
155
 
152
156
  # ---------------------------------------------------------------------------
@@ -1,9 +1,9 @@
1
1
  ---
2
- chutils_version: 3.2.0
3
- project_version: 3.2.0
4
- git_commit: df4bab5ad64a0fd8617cc805dec1a1fdfaa615ad (dirty)
5
- generated_at: 2026-07-19T14:47:50.845857+00:00
6
- project_hash: 704110b7047bfa0bbeef1cd6e2634805e0b6c46407c51127b776578cdc198935
2
+ chutils_version: 3.3.0
3
+ project_version: 3.3.0
4
+ git_commit: dd510da8a0f5b6bd6e074a0384bb569842a8941c (dirty)
5
+ generated_at: 2026-07-21T19:47:11.423472+00:00
6
+ project_hash: e737166afdd52264741ea61fe6205395550770bf482892941e0198a52a01b61f
7
7
  ---
8
8
 
9
9
  # Public API Map: chutils
@@ -13,9 +13,11 @@ project_hash: 704110b7047bfa0bbeef1cd6e2634805e0b6c46407c51127b776578cdc198935
13
13
  | `AntiCaptchaSolver` | class | `(self, api_key: str \| None = None, host: str = 'https://api.anti-captcha.com') -> None` | Синхронный клиент для Anti-Captcha. |
14
14
  | `AsyncAntiCaptchaSolver` | class | `(self, api_key: str \| None = None, host: str = 'https://api.anti-captcha.com') -> None` | Асинхронный клиент для Anti-Captcha. |
15
15
  | `AsyncCapMonsterSolver` | class | `(self, api_key: str \| None = None, host: str = 'https://api.capmonster.cloud') -> None` | Асинхронный клиент для CapMonster Cloud. |
16
+ | `AsyncEventStreamClient` | class | `(self, url: 'str', headers: 'dict[str, str] \| None' = None, timeout: 'float \| None' = None, filter_heartbeats: 'bool' = True, reconnect_strategy: 'Iterable[float] \| Callable[[], Iterable[float]] \| None' = None) -> 'None'` | Асинхронный клиент для HTTP Streaming и SSE. |
16
17
  | `AsyncHttpClient` | class | `(self, *, base_url: 'str' = '', default_headers: 'dict[str, str] \| None' = None, timeout: 'float \| None' = 30.0, policy: 'ResiliencePolicy \| None' = None, sensitive_headers: 'set[str] \| None' = None) -> 'None'` | Асинхронный HTTP-клиент на базе httpx.AsyncClient. |
17
18
  | `AsyncRuCaptchaSolver` | class | `(self, api_key: str \| None = None, host: str = 'https://rucaptcha.com') -> None` | Асинхронный клиент для RuCaptcha / 2Captcha. |
18
19
  | `AsyncWebClient` | class | `(self, *args: Any, user_agent_rotator: chutils.web.user_agent.UserAgentRotator \| None = None, proxy_pool: chutils.web.proxy_pool.ProxyPool \| None = None, rotate_ua: bool = True, rotate_proxy: bool = True, retries: int = 0, retry_delay: float = 1.0, retry_backoff: float = 2.0, retry_on_5xx: bool = True, rate_limit_calls: int \| None = None, rate_limit_period: float = 1.0, rate_limit_strategy: str = 'token_bucket', rate_limit_wait: bool = False, cache_ttl: int \| None = None, cache_backend: typing.Any \| None = None, **kwargs: Any) -> None` | Асинхронный HTTP-клиент с поддержкой ротации User-Agent, прокси-пулов, |
20
+ | `AsyncWebSocketClient` | class | `(self, url: 'str', headers: 'dict[str, str] \| None' = None, filter_heartbeats: 'bool' = True, reconnect_strategy: 'Iterable[float] \| Callable[[], Iterable[float]] \| None' = None) -> 'None'` | Асинхронный клиент для WebSockets. |
19
21
  | `AuditError` | class | `(self, message: str, hint: str \| None = None, **context: Any) -> None` | Базовый класс ошибок модуля audit. |
20
22
  | `AuditEvent` | class | `(self, /, **data: 'Any') -> 'None'` | Pydantic-модель единой записи журнала аудита. |
21
23
  | `AuditIntegrityError` | class | `(self, message: str, hint: str \| None = None, **context: Any) -> None` | Ошибка целостности журнала аудита. |
@@ -23,6 +25,7 @@ project_hash: 704110b7047bfa0bbeef1cd6e2634805e0b6c46407c51127b776578cdc198935
23
25
  | `BaseCacheBackend` | class | `(self, /, *args, **kwargs)` | Базовый абстрактный класс для всех бэкендов кэширования. |
24
26
  | `BaseConfigProvider` | class | `(self, /, *args, **kwargs)` | Абстрактный базовый класс для кастомного динамического провайдера конфигурации. |
25
27
  | `BaseEnvManifest` | class | `(self, /, **data: 'Any') -> 'None'` | Базовый манифест переменных окружения на базе Pydantic. |
28
+ | `BaseStoreBackend` | class | `(self, /, *args, **kwargs)` | Абстрактный базовый класс для всех бэкендов Key-Value хранилищ. |
26
29
  | `BezierCurveGenerator` | class | `(self, /, *args, **kwargs)` | Генератор траекторий перемещения на основе кривых Безье. |
27
30
  | `BulkheadLimitExceeded` | class | `(self, message: str, hint: str \| None = None, **context: Any) -> None` | Ошибка: превышен предел параллельных запросов Bulkhead. |
28
31
  | `CacheError` | class | `(self, message: str, hint: str \| None = None, **context: Any) -> None` | Общая ошибка кэширования. |
@@ -55,6 +58,7 @@ project_hash: 704110b7047bfa0bbeef1cd6e2634805e0b6c46407c51127b776578cdc198935
55
58
  | `EventBus` | class | `(self, error_strategy: chutils.events.core.ErrorStrategy = <ErrorStrategy.IGNORE: 'ignore'>) -> None` | Внутренняя шина событий (In-Memory Event Bus). |
56
59
  | `EventBusError` | class | `(self, message: str, hint: str \| None = None, **context: Any) -> None` | Общая ошибка шины событий. |
57
60
  | `EventBusExceptionGroup` | class | `(self, message: str, exceptions: list[Exception], **context: Any) -> None` | Группа ошибок, возникших при параллельном или последовательном выполнении |
61
+ | `EventStreamClient` | class | `(self, url: 'str', headers: 'dict[str, str] \| None' = None, timeout: 'float \| None' = None, filter_heartbeats: 'bool' = True, reconnect_strategy: 'Iterable[float] \| Callable[[], Iterable[float]] \| None' = None) -> 'None'` | Синхронный клиент-обертка для HTTP Streaming и SSE. |
58
62
  | `FileBackend` | class | `(self, path: 'str \| Path') -> 'None'` | Бэкенд хранения событий аудита в JSONL-файле. |
59
63
  | `HttpClient` | class | `(self, *, base_url: 'str' = '', default_headers: 'dict[str, str] \| None' = None, timeout: 'float \| None' = 30.0, policy: 'ResiliencePolicy \| None' = None, sensitive_headers: 'set[str] \| None' = None) -> 'None'` | Синхронный HTTP-клиент с батареями (httpx + fallback на urllib). |
60
64
  | `HttpClientError` | class | `(self, message: str, hint: str \| None = None, **context: Any) -> None` | Базовая ошибка HTTP-клиента chutils. |
@@ -68,6 +72,8 @@ project_hash: 704110b7047bfa0bbeef1cd6e2634805e0b6c46407c51127b776578cdc198935
68
72
  | `LogLevel` | class | `(self, *args, **kwds)` | Перечисление для поддерживаемых уровней логирования. |
69
73
  | `LoggerConfigurationError` | class | `(self, message: str, hint: str \| None = None, **context: Any) -> None` | Ошибка конфигурации логгера. |
70
74
  | `MEDIUMDEBUG_LEVEL_NUM` | constant | | |
75
+ | `MemcachedStore` | class | `(self, host: 'str' = '127.0.0.1', port: 'int' = 11211, **kwargs: 'Any') -> 'None'` | Бэкенд хранилища на базе Memcached (требует опционального пакета pymemcache). |
76
+ | `MemoryStore` | class | `(self) -> 'None'` | Потокобезопасный in-memory бэкенд хранилища с поддержкой TTL. |
71
77
  | `MockServerRunner` | class | `(self, port: 'int' = 8888, routes_path: 'str' = 'mocks.yml', proxy_fallback: 'str \| None' = None) -> 'None'` | Управляющий класс для мок-сервера. |
72
78
  | `OTEL_AVAILABLE` | constant | | |
73
79
  | `OptionalDependencyError` | class | `(self, message: str, hint: str \| None = None, **context: Any) -> None` | Ошибка: отсутствует опциональная зависимость (например, watchdog). |
@@ -75,6 +81,7 @@ project_hash: 704110b7047bfa0bbeef1cd6e2634805e0b6c46407c51127b776578cdc198935
75
81
  | `PostgresBackend` | class | `(self, connection: '_DBAPIConnection') -> 'None'` | Бэкенд хранения событий аудита в PostgreSQL. |
76
82
  | `RICH_AVAILABLE` | constant | | |
77
83
  | `RateLimitExceededError` | class | `(self, message: str, hint: str \| None = None, **context: Any) -> None` | Ошибка: превышен лимит частоты вызовов (Rate Limit Exceeded). |
84
+ | `RedisStore` | class | `(self, url: 'str' = 'redis://localhost:6379/0', **kwargs: 'Any') -> 'None'` | Бэкенд хранилища на базе Redis (требует опционального пакета redis). |
78
85
  | `ResiliencePolicy` | class | `(self, *, retries: 'int' = 3, retry_delay: 'float' = 0.5, retry_backoff: 'float' = 2.0, retry_jitter: 'bool' = False, retry_exceptions: 'tuple[type[Exception], ...]' = (<class 'Exception'>,), retry_on_status_codes: 'tuple[int, ...]' = (429, 500, 502, 503, 504), timeout: 'float \| None' = None, max_concurrency: 'int \| None' = None, cb_failure_threshold: 'int' = 5, cb_recovery_timeout: 'float' = 30.0) -> 'None'` | Политика отказоустойчивости: retry, timeout, semaphore, circuit breaker. |
79
86
  | `RuCaptchaSolver` | class | `(self, api_key: str \| None = None, host: str = 'https://rucaptcha.com') -> None` | Синхронный клиент для RuCaptcha / 2Captcha. |
80
87
  | `SafeTimedRotatingFileHandler` | class | `(self, filename, when='h', interval=1, backupCount=0, encoding=None, delay=False, utc=False, atTime=None, errors=None)` | Надежный обработчик ротации логов, адаптированный для Windows. |
@@ -84,28 +91,32 @@ project_hash: 704110b7047bfa0bbeef1cd6e2634805e0b6c46407c51127b776578cdc198935
84
91
  | `SecretMaskingFilter` | class | `(self, name='')` | Фильтр для автоматического маскирования секретов в сообщениях логов. |
85
92
  | `SecretNotFoundError` | class | `(self, message: str, hint: str \| None = None, **context: Any) -> None` | Ошибка: секрет не найден. |
86
93
  | `SecretProviderError` | class | `(self, message: str, hint: str \| None = None, **context: Any) -> None` | Ошибка конкретного провайдера секретов (например, сбой keyring). |
94
+ | `ServerSentEvent` | class | `(self, id: 'str \| None' = None, event: 'str \| None' = None, data: 'str' = '', retry: 'int \| None' = None, raw: 'str' = '') -> None` | Представляет собой отдельное событие Server-Sent Events (SSE). |
87
95
  | `SqliteBackend` | class | `(self, path: 'str \| Path') -> 'None'` | Бэкенд хранения событий аудита в таблице SQLite. |
96
+ | `StoreManager` | class | `(self, backend: 'BaseStoreBackend \| None' = None, serializer: 'str \| Any' = 'json', prefix: 'str' = '') -> 'None'` | Центральный менеджер Key-Value хранилища. |
88
97
  | `UrllibFallbackClient` | class | `(self, *, base_url: 'str' = '', default_headers: 'dict[str, str] \| None' = None, timeout: 'float \| None' = 30.0, policy: 'ResiliencePolicy \| None' = None, sensitive_headers: 'set[str] \| None' = None) -> 'None'` | Синхронный HTTP-клиент на базе urllib.request. |
89
98
  | `WATCHDOG_AVAILABLE` | constant | | |
90
99
  | `WatcherInitializationError` | class | `(self, message: str, hint: str \| None = None, **context: Any) -> None` | Ошибка инициализации наблюдателя (watcher) за файлами. |
91
100
  | `WebClient` | class | `(self, *args: Any, user_agent_rotator: chutils.web.user_agent.UserAgentRotator \| None = None, proxy_pool: chutils.web.proxy_pool.ProxyPool \| None = None, rotate_ua: bool = True, rotate_proxy: bool = True, retries: int = 0, retry_delay: float = 1.0, retry_backoff: float = 2.0, retry_on_5xx: bool = True, rate_limit_calls: int \| None = None, rate_limit_period: float = 1.0, rate_limit_strategy: str = 'token_bucket', rate_limit_wait: bool = False, cache_ttl: int \| None = None, cache_backend: typing.Any \| None = None, **kwargs: Any) -> None` | Синхронный HTTP-клиент с поддержкой ротации User-Agent, прокси-пулов, |
101
+ | `WebSocketClient` | class | `(self, url: 'str', headers: 'dict[str, str] \| None' = None, filter_heartbeats: 'bool' = True, reconnect_strategy: 'Iterable[float] \| Callable[[], Iterable[float]] \| None' = None) -> 'None'` | Синхронный клиент-обертка для WebSockets. |
92
102
  | `aget_config` | function | `(model: 'type[T] \| None' = None) -> 'JSONDict \| T'` | Асинхронная версия get_config. |
93
103
  | `aget_config_value` | function | `(section: 'str', key: 'str', fallback: 'Any' = None, config: 'JSONDict \| None' = None, required: 'bool' = False) -> 'Any'` | Асинхронно получает произвольное значение из конфигурации. |
94
- | `apply_antidetect_playwright` | function | `(context: Any) -> None` | Применяет JS-инъекции анти-детекта к контексту Playwright. |
95
- | `apply_antidetect_selenium` | function | `(driver: Any) -> None` | Применяет JS-инъекции анти-детекта к сессии Selenium. |
104
+ | `apply_antidetect_nodriver` | function | `(tab: Any, *, webgl_vendor: str = 'Google Inc. (NVIDIA)', webgl_renderer: str = 'ANGLE (NVIDIA, NVIDIA GeForce RTX 3060 Direct3D11 vs_5_0 ps_5_0, D3D11)', hardware_concurrency: int = 8, device_memory: int = 8) -> None` | Применяет JS-инъекции анти-детекта к вкладке (Tab) nodriver. |
105
+ | `apply_antidetect_playwright` | function | `(context: Any, *, webgl_vendor: str = 'Google Inc. (NVIDIA)', webgl_renderer: str = 'ANGLE (NVIDIA, NVIDIA GeForce RTX 3060 Direct3D11 vs_5_0 ps_5_0, D3D11)', hardware_concurrency: int = 8, device_memory: int = 8) -> None` | Применяет JS-инъекции анти-детекта к контексту Playwright. |
106
+ | `apply_antidetect_selenium` | function | `(driver: Any, *, webgl_vendor: str = 'Google Inc. (NVIDIA)', webgl_renderer: str = 'ANGLE (NVIDIA, NVIDIA GeForce RTX 3060 Direct3D11 vs_5_0 ps_5_0, D3D11)', hardware_concurrency: int = 8, device_memory: int = 8) -> None` | Применяет JS-инъекции анти-детекта к сессии Selenium. |
96
107
  | `are_paths_initialized` | function | `() -> bool` | Проверяет, были ли инициализированы пути к проекту и файлам конфигурации. |
97
108
  | `asave_config_value` | function | `(section: 'str', key: 'str', value: 'Any', cfg_file: 'str \| None' = None, save_to_local: 'bool' = False, notify: 'bool' = True) -> 'bool'` | Асинхронно сохраняет одно значение в конфигурационном файле. |
98
109
  | `async_human_sleep` | function | `(min_seconds: float, max_seconds: float) -> None` | Асинхронно задерживает выполнение на случайное время, имитируя поведение человека. |
99
- | `async_move_mouse` | function | `(page: Any, x: int, y: int, start: tuple[int, int] \| None = None, steps: int = 30, delay_between_steps: float = 0.01) -> None` | Имитирует плавное перемещение мыши Playwright. |
100
- | `async_scroll_to` | function | `(page: Any, x: int, y: int, selector: str \| None = None, steps: int = 10, delay_between_steps: float = 0.01) -> None` | Имитирует плавный скроллинг Playwright. |
101
- | `async_type_text` | function | `(page: Any, selector: str, text: str, error_rate: float = 0.05, speed_wpm: float = 40.0) -> None` | Имитирует ввод текста с опечатками Playwright. |
110
+ | `async_move_mouse` | function | `(page: Any, x: int, y: int, start: tuple[int, int] \| None = None, steps: int = 30, delay_between_steps: float = 0.01) -> None` | Имитирует плавное перемещение мыши Playwright или nodriver. |
111
+ | `async_scroll_to` | function | `(page: Any, x: int, y: int, selector: str \| None = None, steps: int = 10, delay_between_steps: float = 0.01) -> None` | Имитирует плавный скроллинг Playwright или nodriver. |
112
+ | `async_type_text` | function | `(page: Any, selector: str, text: str, error_rate: float = 0.05, speed_wpm: float = 40.0) -> None` | Имитирует ввод текста с опечатками Playwright или nodriver. |
102
113
  | `audit` | module | | chutils.audit — Неизменяемый журнал событий аудита. |
103
114
  | `audit_context` | function | `(action: 'str', actor: 'str', *, target: 'str \| None' = None, backend: 'object') -> 'Generator[_AuditContextState, None, None]'` | Контекстный менеджер для регистрации события аудита в блоке кода. |
104
115
  | `audit_event` | function | `(action: 'str', actor: '_ActorOrCallable' = 'system', *, target: '_TargetOrCallable' = None, backend: 'object') -> 'Callable'` | Декоратор для автоматической регистрации события аудита при вызове функции. |
105
116
  | `bind_context` | function | `(**kwargs: 'Any') -> 'contextvars.Token[dict[str, Any]]'` | Привязывает значения к текущему контексту. |
106
117
  | `bulkhead` | function | `(max_concurrent: int, max_waiting: int = 0, timeout: Optional[float] = None, fallback: Any = <object object>, key: Optional[collections.abc.Callable[..., Any]] = None) -> collections.abc.Callable[[collections.abc.Callable[~P, ~R]], collections.abc.Callable[~P, ~R]]` | Декоратор для изоляции ресурсов (Bulkhead). |
107
118
  | `cache` | module | | |
108
- | `cache_with_ttl` | function | `(ttl: int = 60, key_prefix: str = '', sliding: bool = True, backend: Optional[chutils.cache.in_memory.InMemoryCacheBackend[Any]] = None) -> collections.abc.Callable[..., typing.Any]` | Декоратор для кэширования результатов выполнения функций с поддержкой TTL. |
119
+ | `cache_with_ttl` | function | `(ttl: int = 60, key_prefix: str = '', sliding: bool = True, backend: Optional[chutils.cache.in_memory.InMemoryCacheBackend[Any]] = None, tags: list[str] \| collections.abc.Callable[..., list[str] \| str] \| None = None) -> collections.abc.Callable[..., typing.Any]` | Декоратор для кэширования результатов выполнения функций с поддержкой TTL. |
109
120
  | `circuit_breaker` | function | `(failure_threshold: int = 5, recovery_timeout: float = 60.0, exceptions: tuple[type[Exception], ...] = (<class 'Exception'>,)) -> collections.abc.Callable[[collections.abc.Callable[~P, ~R]], collections.abc.Callable[~P, ~R]]` | Декоратор Circuit Breaker (Предохранитель) для защиты от каскадных сбоев. |
110
121
  | `cleanup_paths` | function | `(*paths: 'str \| Path', retries: 'int' = 3, delay: 'float' = 0.1, on_locked: "Literal['raise', 'rename_orphan', 'warn']" = 'warn', orphan_collision: "Literal['raise', 'overwrite', 'unique']" = 'raise') -> 'None'` | Пакетное удаление нескольких путей. |
111
122
  | `clear_context` | function | `() -> 'None'` | Полностью очищает текущий контекст. |
@@ -120,6 +131,7 @@ project_hash: 704110b7047bfa0bbeef1cd6e2634805e0b6c46407c51127b776578cdc198935
120
131
  | `decorators` | module | | Модуль с полезными декораторами для автоматизации задач. |
121
132
  | `decrypt_file` | function | `(file_path: str \| pathlib._local.Path, seed: str, output_path: str \| pathlib._local.Path \| None = None) -> bool` | Дешифрует содержимое файла и сохраняет результат. |
122
133
  | `decrypt_portable` | function | `(encrypted_data: str, seed: str) -> str \| None` | Дешифрует строку с использованием детерминированного ключа, полученного из seed. |
134
+ | `default_container` | constant | | Легковесный IoC/DI контейнер. |
123
135
  | `dev` | module | | Инструменты разработчика для анализа кодовой базы и генерации контекста. |
124
136
  | `di` | module | | |
125
137
  | `diagnostics` | module | | |
@@ -153,7 +165,7 @@ project_hash: 704110b7047bfa0bbeef1cd6e2634805e0b6c46407c51127b776578cdc198935
153
165
  | `human_sleep` | function | `(min_seconds: float, max_seconds: float) -> None` | Синхронно задерживает выполнение на случайное время, имитируя поведение человека. |
154
166
  | `humanize_timedelta` | function | `(dt: 'datetime', locale: 'str' = 'ru', custom_locales: 'dict[str, Any] \| None' = None) -> 'str'` | Превращает дату в человекочитаемую строку относительно текущего времени. |
155
167
  | `init` | function | `(base_dir: str) -> None` | Ручная инициализация пакета с указанием базовой директории проекта. |
156
- | `inject` | function | `(container: chutils.di.container.Container \| None = None) -> collections.abc.Callable[[collections.abc.Callable[..., typing.Any]], collections.abc.Callable[..., typing.Any]]` | Декоратор для автоматического внедрения зависимостей в аргументы функции. |
168
+ | `inject` | function | `(func_or_container: collections.abc.Callable[..., typing.Any] \| chutils.di.container.Container \| None = None, *, container: chutils.di.container.Container \| None = None) -> Any` | Декоратор для автоматического внедрения зависимостей в аргументы функции. |
157
169
  | `inject_trace_headers` | function | `(headers: 'dict[str, str]') -> 'dict[str, str]'` | Инжектирует W3C Trace Context заголовки в словарь заголовков запроса. |
158
170
  | `is_config_loaded` | function | `() -> bool` | Проверяет, была ли конфигурация уже загружена в память. |
159
171
  | `is_feature_enabled` | function | `(feature_name: 'str', context: 'dict[str, Any] \| None' = None) -> 'bool'` | Проверяет, включена ли указанная фича. |
@@ -198,6 +210,8 @@ project_hash: 704110b7047bfa0bbeef1cd6e2634805e0b6c46407c51127b776578cdc198935
198
210
  | `start_scheduler` | function | `() -> 'None'` | Запускает глобальный планировщик фоновых задач в текущем Event Loop. |
199
211
  | `stop_config_watcher` | function | `() -> 'None'` | Останавливает процесс отслеживания изменений конфигурации. |
200
212
  | `stop_scheduler` | function | `() -> 'None'` | Останавливает глобальный планировщик фоновых задач. |
213
+ | `store` | module | | Модуль chutils.store — Абстракция Key-Value хранилища. |
214
+ | `store_cache` | function | `(store: 'StoreManager \| None' = None, ttl: 'int \| float' = 60, key_prefix: 'str' = 'cache:') -> 'Callable[..., Any]'` | Декоратор для кэширования результатов вызова функций через StoreManager. |
201
215
  | `subscribe` | function | `(event_name: str) -> collections.abc.Callable[[collections.abc.Callable[..., typing.Any]], collections.abc.Callable[..., typing.Any]]` | Декоратор для подписки на событие в глобальной шине. |
202
216
  | `tasks` | module | | Модуль планировщика фоновых задач. |
203
217
  | `testing` | module | | |
@@ -1,44 +1,44 @@
1
1
  # Plan: Уборка мусора разработки (chutils dev clean)
2
2
 
3
3
  ## Phase 1: Проектирование и подготовка инфраструктуры
4
- - [ ] Task: Добавить описание конфигурации для модуля очистки в `chutils.config`
5
- - [ ] Описать структуру параметров `clean` (например, `extra_clean_targets`, `default_excludes`) в Pydantic моделях конфигурации (если используются)
6
- - [ ] Task: Создать заготовку для логики очистки в `src/chutils/dev/cleaner.py`
7
- - [ ] Task: Conductor - User Manual Verification 'Phase 1: Проектирование и подготовка инфраструктуры' (Protocol in workflow.md)
4
+ - [x] Task: Добавить описание конфигурации для модуля очистки в `chutils.config`
5
+ - [x] Описать структуру параметров `clean` (например, `extra_clean_targets`, `default_excludes`) в Pydantic моделях конфигурации (если используются)
6
+ - [x] Task: Создать заготовку для логики очистки в `src/chutils/dev/cleaner.py`
7
+ - [x] Task: Conductor - User Manual Verification 'Phase 1: Проектирование и подготовка инфраструктуры' (Protocol in workflow.md)
8
8
 
9
9
  ## Phase 2: Реализация ядра очистки (Cleaner Engine)
10
- - [ ] Task: Реализовать функцию сканирования проекта `scan_project`
11
- - [ ] Функция должна обходить дерево проекта рекурсивно
12
- - [ ] Пропускать сканирование исключенных папок (`.git`, `.venv` и др.) для оптимизации скорости
13
- - [ ] Находить файлы и папки по стандартным маскам (`__pycache__`, `.pytest_cache`, `.mypy_cache`, `.ruff_cache`, `.coverage`, `build/`, `dist/`, `.egg-info` и др.)
14
- - [ ] Поддерживать дополнительные цели из аргументов и конфигурации
15
- - [ ] Возвращать список путей и их размеры
16
- - [ ] Task: Реализовать функцию очистки `execute_clean`
17
- - [ ] Безопасно удалять файлы и папки с использованием `chutils.fs`
18
- - [ ] Подсчитывать суммарный объем освобожденного места
19
- - [ ] Обрабатывать ошибки доступа при удалении (пропускать и логировать предупреждения)
20
- - [ ] Task: Интеграция с конфигурацией `pyproject.toml` / `config.yml`
21
- - [ ] Чтение настроек очистки из конфигурации проекта
22
- - [ ] Task: Conductor - User Manual Verification 'Phase 2: Реализация ядра очистки (Cleaner Engine)' (Protocol in workflow.md)
10
+ - [x] Task: Реализовать функцию сканирования проекта `scan_project`
11
+ - [x] Функция должна обходить дерево проекта рекурсивно
12
+ - [x] Пропускать сканирование исключенных папок (`.git`, `.venv` и др.) для оптимизации скорости
13
+ - [x] Находить файлы и папки по стандартным маскам (`__pycache__`, `.pytest_cache`, `.mypy_cache`, `.ruff_cache`, `.coverage`, `build/`, `dist/`, `.egg-info` и др.)
14
+ - [x] Поддерживать дополнительные цели из аргументов и конфигурации
15
+ - [x] Возвращать список путей и их размеры
16
+ - [x] Task: Реализовать функцию очистки `execute_clean`
17
+ - [x] Безопасно удалять файлы и папки с использованием `chutils.fs`
18
+ - [x] Подсчитывать суммарный объем освобожденного места
19
+ - [x] Обрабатывать ошибки доступа при удалении (пропускать и логировать предупреждения)
20
+ - [x] Task: Интеграция с конфигурацией `pyproject.toml` / `config.yml`
21
+ - [x] Чтение настроек очистки из конфигурации проекта
22
+ - [x] Task: Conductor - User Manual Verification 'Phase 2: Реализация ядра очистки (Cleaner Engine)' (Protocol in workflow.md)
23
23
 
24
24
  ## Phase 3: CLI команда chutils dev clean
25
- - [ ] Task: Зарегистрировать подкоманду `clean` в `DevCommand` в `src/chutils/commands/dev.py`
26
- - [ ] Добавить аргументы `--dry-run`, `--yes`/`-y`/`--force`, `--exclude`, `--include`
27
- - [ ] Task: Реализовать обработчик `handle_clean` в `DevCommand`
28
- - [ ] Сбор настроек из аргументов CLI и файла конфигурации
29
- - [ ] Вызов `scan_project`
30
- - [ ] Вывод списка файлов и размеров в таблице (с `rich` или простым текстом)
31
- - [ ] Запрос подтверждения у пользователя (если не передан `--yes` / `--force`)
32
- - [ ] Вызов `execute_clean` (если подтверждено/форсировано) и вывод результатов
33
- - [ ] Task: Conductor - User Manual Verification 'Phase 3: CLI команда chutils dev clean' (Protocol in workflow.md)
25
+ - [x] Task: Зарегистрировать подкоманду `clean` в `DevCommand` в `src/chutils/commands/dev.py`
26
+ - [x] Добавить аргументы `--dry-run`, `--yes`/`-y`/`--force`, `--exclude`, `--include`
27
+ - [x] Task: Реализовать обработчик `handle_clean` в `DevCommand`
28
+ - [x] Сбор настроек из аргументов CLI и файла конфигурации
29
+ - [x] Вызов `scan_project`
30
+ - [x] Вывод списка файлов и размеров в таблице (с `rich` или простым текстом)
31
+ - [x] Запрос подтверждения у пользователя (если не передан `--yes` / `--force`)
32
+ - [x] Вызов `execute_clean` (если подтверждено/форсировано) и вывод результатов
33
+ - [x] Task: Conductor - User Manual Verification 'Phase 3: CLI команда chutils dev clean' (Protocol in workflow.md)
34
34
 
35
35
  ## Phase 4: Тестирование и документация
36
- - [ ] Task: Написать модульные тесты для Cleaner Engine и CLI-команды в `tests/unit/`
37
- - [ ] Протестировать сканирование временных файлов (через фикстуры временных папок)
38
- - [ ] Протестировать `--dry-run` флаг
39
- - [ ] Протестировать `--yes`/`--force` и интерактивный режимы
40
- - [ ] Протестировать исключения и включения
41
- - [ ] Добиться покрытия тестов > 90%
42
- - [ ] Task: Обновить документацию проекта
43
- - [ ] Добавить описание команды в `README.md` или `docs/`
44
- - [ ] Task: Conductor - User Manual Verification 'Phase 4: Тестирование и документация' (Protocol in workflow.md)
36
+ - [x] Task: Написать модульные тесты для Cleaner Engine и CLI-команды в `tests/unit/`
37
+ - [x] Протестировать сканирование временных файлов (через фикстуры временных папок)
38
+ - [x] Протестировать `--dry-run` флаг
39
+ - [x] Протестировать `--yes`/`--force` и интерактивный режимы
40
+ - [x] Протестировать исключения и включения
41
+ - [x] Добиться покрытия тестов > 90%
42
+ - [x] Task: Обновить документацию проекта
43
+ - [x] Добавить описание команды в `README.md` или `docs/`
44
+ - [x] Task: Conductor - User Manual Verification 'Phase 4: Тестирование и документация' (Protocol in workflow.md)
@@ -1,4 +1,4 @@
1
- # Track audit_20260702 Context
1
+ # Track http_streaming_20260720 Context
2
2
 
3
3
  - [Specification](./spec.md)
4
4
  - [Implementation Plan](./plan.md)
@@ -0,0 +1,8 @@
1
+ {
2
+ "track_id": "http_streaming_20260720",
3
+ "type": "feature",
4
+ "status": "new",
5
+ "created_at": "2026-07-20T21:56:00Z",
6
+ "updated_at": "2026-07-20T21:56:00Z",
7
+ "description": "Реализовать поддержку HTTP-стриминга (SSE/Chunked) и WebSockets в chutils.http.streaming (WebSockets через extras)"
8
+ }
@@ -0,0 +1,34 @@
1
+ # Implementation Plan: Реализация HTTP-стриминга (SSE/Chunked) и WebSockets в chutils.http.streaming
2
+
3
+ ## Phase 1: Написание тестов и TDD подготовка
4
+ - [ ] Task: Создание тестов для EventStream (SSE)
5
+ - [ ] Написать тесты для AsyncEventStreamClient (проверка стриминга, автореконнекта, фильтрации пингов)
6
+ - [ ] Написать тесты для EventStreamClient (синхронная обертка)
7
+ - [ ] Task: Создание тестов для WebSocketClient
8
+ - [ ] Написать тесты для AsyncWebSocketClient (проверка соединения, отправки/получения сообщений, автореконнекта)
9
+ - [ ] Написать тесты для WebSocketClient (синхронная обертка)
10
+ - [ ] Написать тесты на выброс OptionalDependencyError при отсутствии библиотеки `websockets`
11
+ - [ ] Task: Conductor - User Manual Verification 'Phase 1: Написание тестов и TDD подготовка' (Protocol in workflow.md)
12
+
13
+ ## Phase 2: Реализация клиентов стриминга
14
+ - [ ] Task: Реализация HTTP-стриминга и SSE
15
+ - [ ] Создать файл `src/chutils/http/streaming.py`
16
+ - [ ] Реализовать AsyncEventStreamClient на базе `httpx.AsyncClient`
17
+ - [ ] Реализовать EventStreamClient (синхронная обертка)
18
+ - [ ] Реализовать логику фильтрации пингов и комментариев по умолчанию
19
+ - [ ] Task: Реализация WebSocket клиентов
20
+ - [ ] Реализовать логику ленивой проверки и импорта `websockets`
21
+ - [ ] Реализовать AsyncWebSocketClient
22
+ - [ ] Реализовать WebSocketClient (синхронная обертка)
23
+ - [ ] Task: Реализация алгоритмов автоматического переподключения (backoff + jitter)
24
+ - [ ] Написать встроенный генератор задержек с экспоненциальным затуханием и джиттером
25
+ - [ ] Интегрировать автореконнект в SSE и WebSocket клиенты с поддержкой кастомных стратегий
26
+ - [ ] Task: Conductor - User Manual Verification 'Phase 2: Реализация клиентов стриминга' (Protocol in workflow.md)
27
+
28
+ ## Phase 3: Тестирование, документирование и финализация
29
+ - [ ] Task: Прогон тестов и доработка до >90% покрытия
30
+ - [ ] Запустить pytest для проверки новых тестов и общего регресса
31
+ - [ ] Task: Документирование и обновление контекста
32
+ - [ ] Создать или обновить `docs/http.md` с примерами использования SSE и WebSockets
33
+ - [ ] Перегенерировать `api_map.md` и `project_index.json`
34
+ - [ ] Task: Conductor - User Manual Verification 'Phase 3: Тестирование, документирование и финализация' (Protocol in workflow.md)
@@ -0,0 +1,36 @@
1
+ # Specification: Реализация HTTP-стриминга (SSE/Chunked) и WebSockets в chutils.http.streaming
2
+
3
+ ## 1. Overview (Обзор)
4
+ Целью данного трека является добавление в `chutils` (в подмодуль `chutils.http.streaming`) готовых инструментов для работы с долгоживущими соединениями:
5
+ 1. **HTTP Streaming / SSE (Server-Sent Events)** на базе существующего `httpx`.
6
+ 2. **WebSockets** на базе легковесной библиотеки `websockets` (выносится в опциональные зависимости `chutils[websockets]`).
7
+
8
+ Инструменты должны автоматизировать рутину поддержания сессии: автоматическое переподключение (auto-reconnect) с экспоненциальной задержкой и джиттером, а также фильтрацию служебных pings/heartbeats. Должны быть предоставлены как асинхронные, так и синхронные версии клиентов.
9
+
10
+ ## 2. Functional Requirements (Функциональные требования)
11
+ - **Универсальные клиенты:**
12
+ - `AsyncEventStreamClient` (асинхронный SSE/HTTP-стриминг) и `EventStreamClient` (синхронный обертка-клиент).
13
+ - `AsyncWebSocketClient` (асинхронный сокет-клиент) и `WebSocketClient` (синхронный сокет-клиент).
14
+ - **Поддержка опциональных зависимостей (WebSockets):**
15
+ - Поддержка WebSockets требует установки `chutils[websockets]` (пакет `websockets`). При отсутствии зависимости выбрасывается `OptionalDependencyError`.
16
+ - SSE работает на стандартных зависимостях `httpx`.
17
+ - **Автоматическая фильтрация Keep-Alive/Heartbeats:**
18
+ - По умолчанию отфильтровываются пустые строки, сообщения-комментарии (например, `: keepalive` в SSE).
19
+ - Должен быть параметр `filter_heartbeats: bool = True` при инициализации. При значении `False` клиенты возвращают «сырые» (raw) сообщения/кадры.
20
+ - **Авто-реконнект и экспоненциальная задержка:**
21
+ - При обрыве соединения клиенты автоматически переподключаются.
22
+ - По умолчанию задержка рассчитывается как экспоненциальная с добавлением случайного джиттера (шума).
23
+ - Должна быть возможность передать кастомную функцию/генератор задержек `reconnect_strategy`.
24
+
25
+ ## 3. Non-Functional Requirements (Нефункциональные требования)
26
+ - **Покрытие тестами:**
27
+ - Юнит-тесты на соединение, стриминг, фильтрацию пингов и реконнект (с использованием моков `httpx` и `websockets`) с покрытием >90%.
28
+ - **Документирование:**
29
+ - Добавить руководство по использованию в `docs/http.md`.
30
+
31
+ ## 4. Acceptance Criteria (Критерии приемки)
32
+ 1. Реализован и протестирован асинхронный и синхронный стриминг событий SSE.
33
+ 2. Реализован асинхронный и синхронный WebSocket клиент с поддержкой `chutils[websockets]`.
34
+ 3. Реализована логика автоматического переподключения (backoff + jitter) с возможностью кастомизации.
35
+ 4. По умолчанию пустые пинги и строки фильтруются, но при выключенном флаге отдаются как сырые данные.
36
+ 5. Написаны тесты, покрывающие логику реконнекта и фильтрации для обеих технологий.
@@ -1,4 +1,4 @@
1
- # Track db_manager_20260707 Context
1
+ # Track nodriver_interactions_20260720 Context
2
2
 
3
3
  - [Specification](./spec.md)
4
4
  - [Implementation Plan](./plan.md)
@@ -0,0 +1,8 @@
1
+ {
2
+ "track_id": "nodriver_interactions_20260720",
3
+ "type": "feature",
4
+ "status": "new",
5
+ "created_at": "2026-07-20T03:22:00Z",
6
+ "updated_at": "2026-07-20T03:22:00Z",
7
+ "description": "Реализовать поддержку nodriver в функциях взаимодействия (async_move_mouse, async_scroll_to, async_type_text)"
8
+ }
@@ -0,0 +1,30 @@
1
+ # Implementation Plan: Поддержка nodriver в функциях взаимодействия scraping.humanize
2
+
3
+ ## Phase 1: Подготовка окружения и написание тестов (TDD)
4
+ - [ ] Task: Создание тестов для проверки автоопределения и работы функций взаимодействия с nodriver
5
+ - [ ] Написать юнит-тесты для async_move_mouse с nodriver (проверка вызовов CDP)
6
+ - [ ] Написать юнит-тесты для async_scroll_to с nodriver (проверка вызовов evaluate)
7
+ - [ ] Написать юнит-тесты для async_type_text с nodriver (проверка CDP key events и Backspace)
8
+ - [ ] Написать тесты для проверки автоопределения и выброса исключений при неизвестных типах
9
+ - [ ] Task: Conductor - User Manual Verification 'Phase 1: Подготовка окружения и написание тестов (TDD)' (Protocol in workflow.md)
10
+
11
+ ## Phase 2: Реализация поддержки nodriver в действиях взаимодействия
12
+ - [ ] Task: Доработка логики автоопределения и проверок зависимостей
13
+ - [ ] Реализовать _ensure_nodriver() в actions.py для контроля зависимости
14
+ - [ ] Реализовать функцию-хелпер автоопределения типа переданного объекта (Playwright vs nodriver)
15
+ - [ ] Task: Реализация плавного перемещения мыши для nodriver
16
+ - [ ] Обновить async_move_mouse для поддержки nodriver через Input.dispatchMouseEvent
17
+ - [ ] Task: Реализация плавного скролла для nodriver
18
+ - [ ] Обновить async_scroll_to для поддержки nodriver через evaluate
19
+ - [ ] Task: Реализация человекоподобного ввода текста для nodriver
20
+ - [ ] Обновить async_type_text для поддержки nodriver с посимвольной отправкой CDP-событий клавиш
21
+ - [ ] Task: Conductor - User Manual Verification 'Phase 2: Реализация поддержки nodriver в действиях взаимодействия' (Protocol in workflow.md)
22
+
23
+ ## Phase 3: Тестирование, документирование и финализация
24
+ - [ ] Task: Запуск тестов и исправление дефектов
25
+ - [ ] Запустить pytest для проверки новых тестов и общего регресса
26
+ - [ ] Добиться покрытия тестов для новой логики >90%
27
+ - [ ] Task: Обновление документации и файлов контекста
28
+ - [ ] Добавить в docs/scraping.md разделы с примерами использования функций взаимодействия с nodriver
29
+ - [ ] Перегенерировать api_map.md и project_index.json с помощью generate-context
30
+ - [ ] Task: Conductor - User Manual Verification 'Phase 3: Тестирование, документирование и финализация' (Protocol in workflow.md)