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.
- {chutils-3.2.0 → chutils-3.3.0}/.chutilsignore +6 -6
- {chutils-3.2.0 → chutils-3.3.0}/PKG-INFO +4 -1
- {chutils-3.2.0 → chutils-3.3.0}/ai-lint.toml +6 -2
- {chutils-3.2.0 → chutils-3.3.0}/api_map.md +26 -12
- {chutils-3.2.0/conductor/tracks → chutils-3.3.0/conductor/archive}/dev_clean_20260707/plan.md +35 -35
- {chutils-3.2.0/conductor/archive/audit_20260702 → chutils-3.3.0/conductor/archive/http_streaming_20260720}/index.md +1 -1
- chutils-3.3.0/conductor/archive/http_streaming_20260720/metadata.json +8 -0
- chutils-3.3.0/conductor/archive/http_streaming_20260720/plan.md +34 -0
- chutils-3.3.0/conductor/archive/http_streaming_20260720/spec.md +36 -0
- {chutils-3.2.0/conductor/archive/db_manager_20260707 → chutils-3.3.0/conductor/archive/nodriver_interactions_20260720}/index.md +1 -1
- chutils-3.3.0/conductor/archive/nodriver_interactions_20260720/metadata.json +8 -0
- chutils-3.3.0/conductor/archive/nodriver_interactions_20260720/plan.md +30 -0
- chutils-3.3.0/conductor/archive/nodriver_interactions_20260720/spec.md +36 -0
- {chutils-3.2.0/conductor/archive/bulkhead_20260702 → chutils-3.3.0/conductor/archive/profile_warmer_20260720}/index.md +1 -1
- chutils-3.3.0/conductor/archive/profile_warmer_20260720/metadata.json +8 -0
- chutils-3.3.0/conductor/archive/profile_warmer_20260720/plan.md +31 -0
- chutils-3.3.0/conductor/archive/profile_warmer_20260720/spec.md +39 -0
- {chutils-3.2.0/conductor/tracks → chutils-3.3.0/conductor/archive}/store_20260702/plan.md +25 -25
- {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks.md +4 -18
- {chutils-3.2.0 → chutils-3.3.0}/conductor/workflow.md +4 -0
- {chutils-3.2.0 → chutils-3.3.0}/docs/audit.md +119 -119
- {chutils-3.2.0 → chutils-3.3.0}/docs/cli/db.md +73 -73
- {chutils-3.2.0 → chutils-3.3.0}/docs/cli/dev.md +47 -0
- {chutils-3.2.0 → chutils-3.3.0}/docs/dependencies.md +8 -7
- chutils-3.3.0/docs/http.md +154 -0
- {chutils-3.2.0 → chutils-3.3.0}/docs/recipes.md +52 -4
- {chutils-3.2.0 → chutils-3.3.0}/docs/scraping.md +93 -2
- chutils-3.3.0/docs/store.md +98 -0
- {chutils-3.2.0 → chutils-3.3.0}/examples/16_cloud_secret_managers.py +76 -76
- {chutils-3.2.0 → chutils-3.3.0}/project_index.json +7173 -3752
- {chutils-3.2.0 → chutils-3.3.0}/pyproject.toml +4 -1
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/__init__.py +16 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/__init__.pyi +135 -7
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/audit/__init__.py +44 -44
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/audit/_hash.py +22 -22
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/audit/api.py +193 -193
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/audit/backends/__init__.py +6 -6
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/audit/backends/base.py +46 -46
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/audit/backends/file.py +123 -123
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/audit/backends/postgres.py +224 -224
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/audit/backends/sqlite.py +200 -200
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/audit/schema.py +116 -116
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/cache/base.py +35 -3
- chutils-3.3.0/src/chutils/cache/decorator.py +164 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/cache/in_memory.py +78 -7
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/commands/dev/__init__.py +88 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/commands/dev/ai_lint.py +37 -0
- chutils-3.3.0/src/chutils/commands/dev/clean.py +124 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/commands/dev/dashboard.py +40 -40
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/commands/dev/generate_context.py +98 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/commands/dev/hooks.py +41 -17
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/commands/dev/profile_imports.py +47 -47
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/commands/dev/setup_github_actions.py +147 -147
- chutils-3.3.0/src/chutils/commands/init.py +366 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/config/custom_providers.py +1 -1
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/config/dev.py +125 -1
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/config/manager.py +1 -1
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/config/utils.py +92 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/db.py +267 -267
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/decorators.py +1 -1
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/__init__.py +4 -1
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/ai_lint.py +189 -33
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/ast_indexer.py +1 -1
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/changelog_parser.py +194 -194
- chutils-3.3.0/src/chutils/dev/cleaner.py +221 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/dashboard/__init__.py +20 -20
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/dashboard/indexer.py +218 -218
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/dashboard/input.py +146 -146
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/dashboard/tui.py +593 -593
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/github_actions.py +91 -91
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/profile_imports.py +351 -351
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/project_metadata.py +42 -4
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/rules/api_map.py +28 -11
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/rules/decomposition.py +63 -6
- chutils-3.3.0/src/chutils/dev/rules/docstring.py +292 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/rules/integration.py +27 -9
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/rules/upgrade_check.py +116 -116
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/upgrade_client.py +121 -121
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/version_detector.py +114 -114
- chutils-3.3.0/src/chutils/di/__init__.pyi +39 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/di/container.py +93 -35
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/events/core.py +1 -1
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/exceptions/audit.py +15 -15
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/http/__init__.py +63 -51
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/http/api.py +167 -167
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/http/client.py +678 -678
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/http/fallback.py +455 -455
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/http/resilience.py +402 -402
- chutils-3.3.0/src/chutils/http/streaming.py +529 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/http/tracing.py +139 -139
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/lifecycle.py +1 -1
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/metrics/__init__.py +1 -1
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/metrics/prometheus.py +1 -1
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/plugins/core.py +1 -1
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/scraping/humanize/__init__.py +5 -0
- chutils-3.3.0/src/chutils/scraping/humanize/actions.py +438 -0
- chutils-3.3.0/src/chutils/scraping/humanize/antidetect.py +221 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/scraping/humanize/math_utils.py +1 -1
- chutils-3.3.0/src/chutils/scraping/humanize/warmer.py +204 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/secret_manager/core.py +2 -2
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/secret_manager/providers/__init__.py +1 -1
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/secret_manager/providers/aws.py +134 -134
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/secret_manager/providers/gcp.py +168 -168
- chutils-3.3.0/src/chutils/store/__init__.py +10 -0
- chutils-3.3.0/src/chutils/store/backends/__init__.py +11 -0
- chutils-3.3.0/src/chutils/store/backends/base.py +131 -0
- chutils-3.3.0/src/chutils/store/backends/memcached.py +211 -0
- chutils-3.3.0/src/chutils/store/backends/memory.py +156 -0
- chutils-3.3.0/src/chutils/store/backends/redis.py +191 -0
- chutils-3.3.0/src/chutils/store/decorator.py +84 -0
- chutils-3.3.0/src/chutils/store/manager.py +351 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/tasks/__init__.pyi +49 -49
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/tasks/core.py +2 -2
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/time.py +1 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/tracing.py +1 -1
- {chutils-3.2.0 → chutils-3.3.0}/tests/integration/test_setup_github_actions_integration.py +35 -35
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/cli/test_cli_dev_cmd.py +4 -4
- chutils-3.3.0/tests/unit/cli/test_cli_init_interactive.py +76 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/cli/test_cli_setup_github_actions.py +92 -92
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/core/test_cache.py +129 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/dev/test_ai_lint.py +200 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/dev/test_changelog_parser.py +95 -95
- chutils-3.3.0/tests/unit/dev/test_cleaner.py +188 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/dev/test_setup_github_actions.py +75 -75
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/dev/test_upgrade_check_rule.py +55 -55
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/dev/test_upgrade_client.py +106 -106
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/dev/test_version_detector.py +102 -102
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/di/test_di.py +42 -0
- chutils-3.3.0/tests/unit/test_antidetect.py +133 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_audit.py +365 -365
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_audit_phase2.py +363 -363
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_dashboard.py +401 -401
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_db_init.py +256 -256
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_db_operations.py +258 -258
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_decorators_bulkhead.py +269 -269
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_http_api.py +213 -213
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_http_client.py +344 -344
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_http_fallback.py +407 -407
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_http_resilience.py +330 -330
- chutils-3.3.0/tests/unit/test_http_streaming.py +385 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_http_tracing.py +226 -226
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_install_hooks.py +6 -2
- chutils-3.3.0/tests/unit/test_nodriver_humanize.py +147 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_profile_imports.py +214 -214
- chutils-3.3.0/tests/unit/test_profile_warmer.py +132 -0
- chutils-3.3.0/tests/unit/test_store_backends_external.py +112 -0
- chutils-3.3.0/tests/unit/test_store_integrations.py +87 -0
- chutils-3.3.0/tests/unit/test_store_manager.py +76 -0
- chutils-3.3.0/tests/unit/test_store_memory.py +80 -0
- {chutils-3.2.0 → chutils-3.3.0}/uv.lock +126 -2
- chutils-3.2.0/conductor/archive/audit_20260702/metadata.json +0 -8
- chutils-3.2.0/conductor/archive/audit_20260702/plan.md +0 -31
- chutils-3.2.0/conductor/archive/audit_20260702/spec.md +0 -53
- chutils-3.2.0/conductor/archive/bulkhead_20260702/metadata.json +0 -8
- chutils-3.2.0/conductor/archive/bulkhead_20260702/plan.md +0 -25
- chutils-3.2.0/conductor/archive/bulkhead_20260702/spec.md +0 -46
- chutils-3.2.0/conductor/archive/cloud_secret_managers_20260511/index.md +0 -5
- chutils-3.2.0/conductor/archive/cloud_secret_managers_20260511/metadata.json +0 -8
- chutils-3.2.0/conductor/archive/cloud_secret_managers_20260511/plan.md +0 -36
- chutils-3.2.0/conductor/archive/cloud_secret_managers_20260511/spec.md +0 -42
- chutils-3.2.0/conductor/archive/custom_config_providers_20260714/index.md +0 -5
- chutils-3.2.0/conductor/archive/custom_config_providers_20260714/metadata.json +0 -8
- chutils-3.2.0/conductor/archive/custom_config_providers_20260714/plan.md +0 -18
- chutils-3.2.0/conductor/archive/custom_config_providers_20260714/spec.md +0 -24
- chutils-3.2.0/conductor/archive/db_manager_20260707/metadata.json +0 -8
- chutils-3.2.0/conductor/archive/db_manager_20260707/plan.md +0 -29
- chutils-3.2.0/conductor/archive/db_manager_20260707/spec.md +0 -41
- chutils-3.2.0/conductor/archive/db_migrations_cli_20260707/index.md +0 -5
- chutils-3.2.0/conductor/archive/db_migrations_cli_20260707/metadata.json +0 -8
- chutils-3.2.0/conductor/archive/db_migrations_cli_20260707/plan.md +0 -27
- chutils-3.2.0/conductor/archive/db_migrations_cli_20260707/spec.md +0 -40
- chutils-3.2.0/conductor/archive/dev_dashboard_20260610/index.md +0 -5
- chutils-3.2.0/conductor/archive/dev_dashboard_20260610/metadata.json +0 -8
- chutils-3.2.0/conductor/archive/dev_dashboard_20260610/plan.md +0 -39
- chutils-3.2.0/conductor/archive/dev_dashboard_20260610/spec.md +0 -43
- chutils-3.2.0/conductor/archive/http_20260702/index.md +0 -5
- chutils-3.2.0/conductor/archive/http_20260702/metadata.json +0 -8
- chutils-3.2.0/conductor/archive/http_20260702/plan.md +0 -28
- chutils-3.2.0/conductor/archive/http_20260702/spec.md +0 -51
- chutils-3.2.0/conductor/archive/profile_imports_20260610/index.md +0 -5
- chutils-3.2.0/conductor/archive/profile_imports_20260610/metadata.json +0 -8
- chutils-3.2.0/conductor/archive/profile_imports_20260610/plan.md +0 -42
- chutils-3.2.0/conductor/archive/profile_imports_20260610/spec.md +0 -40
- chutils-3.2.0/conductor/archive/setup_github_actions_20260714/index.md +0 -5
- chutils-3.2.0/conductor/archive/setup_github_actions_20260714/metadata.json +0 -8
- chutils-3.2.0/conductor/archive/setup_github_actions_20260714/plan.md +0 -28
- chutils-3.2.0/conductor/archive/setup_github_actions_20260714/spec.md +0 -27
- chutils-3.2.0/src/chutils/cache/decorator.py +0 -94
- chutils-3.2.0/src/chutils/commands/init.py +0 -151
- chutils-3.2.0/src/chutils/dev/rules/docstring.py +0 -218
- chutils-3.2.0/src/chutils/scraping/humanize/actions.py +0 -268
- chutils-3.2.0/src/chutils/scraping/humanize/antidetect.py +0 -123
- chutils-3.2.0/tests/unit/test_antidetect.py +0 -41
- {chutils-3.2.0 → chutils-3.3.0}/.gitattributes +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/.github/workflows/ci.yml +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/.github/workflows/publish-docs.yml +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/.gitignore +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/CODE_OF_CONDUCT.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/CONTRIBUTING.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/GEMINI.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/LICENSE +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/README.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/benchmarks/cold_start.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/conductor/.gitignore +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/conductor/GEMINI.md +0 -0
- {chutils-3.2.0/conductor/tracks → chutils-3.3.0/conductor/archive}/cache_invalidation_20260714/index.md +0 -0
- {chutils-3.2.0/conductor/tracks → chutils-3.3.0/conductor/archive}/cache_invalidation_20260714/metadata.json +0 -0
- {chutils-3.2.0/conductor/tracks → chutils-3.3.0/conductor/archive}/cache_invalidation_20260714/plan.md +0 -0
- {chutils-3.2.0/conductor/tracks → chutils-3.3.0/conductor/archive}/cache_invalidation_20260714/spec.md +0 -0
- {chutils-3.2.0/conductor/tracks → chutils-3.3.0/conductor/archive}/dev_clean_20260707/index.md +0 -0
- {chutils-3.2.0/conductor/tracks → chutils-3.3.0/conductor/archive}/dev_clean_20260707/metadata.json +0 -0
- {chutils-3.2.0/conductor/tracks → chutils-3.3.0/conductor/archive}/dev_clean_20260707/spec.md +0 -0
- {chutils-3.2.0/conductor/tracks → chutils-3.3.0/conductor/archive}/store_20260702/index.md +0 -0
- {chutils-3.2.0/conductor/tracks → chutils-3.3.0/conductor/archive}/store_20260702/metadata.json +0 -0
- {chutils-3.2.0/conductor/tracks → chutils-3.3.0/conductor/archive}/store_20260702/spec.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/conductor/code_styleguides/python.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/conductor/index.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/conductor/product-guidelines.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/conductor/product.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/conductor/setup_state.json +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/conductor/tech-stack.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/ai_manifests_few_shot_20260713/index.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/ai_manifests_few_shot_20260713/metadata.json +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/ai_manifests_few_shot_20260713/plan.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/ai_manifests_few_shot_20260713/spec.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/config_remote_push_20260702/index.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/config_remote_push_20260702/metadata.json +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/config_remote_push_20260702/plan.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/config_remote_push_20260702/spec.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/dev_watch_20260702/index.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/dev_watch_20260702/metadata.json +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/dev_watch_20260702/plan.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/dev_watch_20260702/spec.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/docstring_audit_20260521/index.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/docstring_audit_20260521/metadata.json +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/docstring_audit_20260521/plan.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/docstring_audit_20260521/spec.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/fallback_alias_20260707/index.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/fallback_alias_20260707/metadata.json +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/fallback_alias_20260707/plan.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/fallback_alias_20260707/spec.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/qt_integration_20260521/index.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/qt_integration_20260521/metadata.json +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/qt_integration_20260521/plan.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/qt_integration_20260521/spec.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/qt_typed_signals_20260521/index.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/qt_typed_signals_20260521/metadata.json +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/qt_typed_signals_20260521/plan.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/qt_typed_signals_20260521/spec.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/scraping_concurrency_20260707/index.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/scraping_concurrency_20260707/metadata.json +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/scraping_concurrency_20260707/plan.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/conductor/tracks/scraping_concurrency_20260707/spec.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/docs/CODE_OF_CONDUCT_RU.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/docs/CONTRIBUTING_RU.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/docs/INTEGRATION_AI.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/docs/README_RU.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/docs/ai_examples/README.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/docs/ai_examples/configuration/README.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/docs/ai_examples/configuration/bad_pattern.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/docs/ai_examples/configuration/good_pattern.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/docs/ai_examples/error_handling/README.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/docs/ai_examples/error_handling/bad_pattern.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/docs/ai_examples/error_handling/good_pattern.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/docs/ai_examples/logging/README.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/docs/ai_examples/logging/bad_pattern.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/docs/ai_examples/logging/good_pattern.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/docs/ai_examples/optional_deps/README.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/docs/ai_examples/optional_deps/bad_pattern.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/docs/ai_examples/optional_deps/good_pattern.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/docs/ai_examples/secrets/README.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/docs/ai_examples/secrets/bad_pattern.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/docs/ai_examples/secrets/good_pattern.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/docs/ai_hints.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/docs/ai_lint.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/docs/api.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/docs/captcha.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/docs/cli/config.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/docs/cli/env.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/docs/cli/index.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/docs/cli/init.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/docs/cli/pypi.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/docs/cli/secrets.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/docs/cli/show_paths.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/docs/cli/template.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/docs/cli/validate.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/docs/custom_config_providers.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/docs/index.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/docs/migration.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/docs/plugins.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/docs/testing.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/docs/web.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/examples/.env +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/examples/01_configuration.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/examples/02_logging.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/examples/03_secrets.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/examples/04_full_example.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/examples/05_different_log_levels.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/examples/06_local_config_override.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/examples/07_decorators_example.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/examples/08_multiple_loggers_example.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/examples/09_disable_keyring.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/examples/10_universal_env_override.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/examples/11_retry_decorator.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/examples/12_secret_masking.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/examples/13_pydantic_validation.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/examples/15_context_logging.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/examples/17_timeout_decorator.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/examples/18_config_hot_reload.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/examples/19_remote_config.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/examples/20_opentelemetry_tracing.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/examples/21_config_diagnostics.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/examples/22_circuit_breaker_decorator.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/examples/22_safe_path_resolution.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/examples/23_event_bus.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/examples/24_task_scheduler.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/examples/25_testing_fixtures_example.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/examples/26_metrics_prometheus.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/examples/27_rate_limiting.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/examples/28_dependency_injection.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/examples/captcha_solvers_usage.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/examples/config.yml +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/examples/scraping_humanize_usage.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/examples/web_client_usage.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/mkdocs.yml +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/__main__.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/antigravity.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/cache/__init__.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/cache/utils.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/cli.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/cli_booster.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/cli_utils.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/commands/__init__.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/commands/base.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/commands/config.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/commands/db.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/commands/dev/base.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/commands/dev/chat_context.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/commands/dev/diagnostics.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/commands/dev/few_shot.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/commands/dev/mock.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/commands/dev/scaffold.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/commands/dev/sync_env.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/commands/env.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/commands/paths.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/commands/pypi.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/commands/secrets.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/commands/template.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/commands/utils.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/commands/validate.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/config/GEMINI.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/config/__init__.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/config/ast_fallback_parser.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/config/core.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/config/diagnostics.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/config/generator.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/config/getters.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/config/providers.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/config/schema.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/config/watcher.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/context.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/crypto.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/chat_context.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/constants.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/env_parser.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/env_sync.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/few_shot/__init__.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/few_shot/detector.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/few_shot/models.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/few_shot/renderer.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/few_shot/writer.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/mock_server.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/models/__init__.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/models/base.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/models/index.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/models/node.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/models/symbol.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/rules/__init__.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/rules/dependency_sync.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/rules/env.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/rules/linter_coverage.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/rules/manifest.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/rules/security.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/dev/scaffold.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/di/__init__.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/diagnostics/__init__.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/diagnostics/manager.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/diagnostics/models.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/diagnostics/web.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/env.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/env.pyi +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/events/__init__.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/exceptions/__init__.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/exceptions/base.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/exceptions/cache.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/exceptions/config.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/exceptions/di.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/exceptions/events.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/exceptions/logger.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/exceptions/resilience.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/exceptions/secrets.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/exceptions/system.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/exceptions/validation.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/exceptions/watcher.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/features.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/fs.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/logger/GEMINI.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/logger/__init__.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/logger/core.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/logger/formatters.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/logger/handlers.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/logger/internal/builder.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/logger/internal/levels.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/logger/internal/utils.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/logger/masking.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/metrics/base.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/metrics/in_memory.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/metrics/timer.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/plugins/__init__.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/plugins/interfaces.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/scraping/__init__.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/scraping/captcha/__init__.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/scraping/captcha/anticaptcha.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/scraping/captcha/base.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/scraping/captcha/capmonster.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/scraping/captcha/exceptions.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/scraping/captcha/rucaptcha.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/secret_manager/GEMINI.md +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/secret_manager/__init__.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/secret_manager/providers/base.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/secret_manager/providers/dotenv.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/secret_manager/providers/env.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/secret_manager/providers/keyring_provider.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/tasks/__init__.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/testing/__init__.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/testing/fixtures.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/text.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/typing.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/validation.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/validation.pyi +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/web/__init__.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/web/client.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/web/proxy_pool.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/src/chutils/web/user_agent.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/conftest.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/integration/__init__.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/integration/test_ai_lint_integration.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/integration/test_cli_e2e.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/integration/test_db_migrations.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/integration/test_event_loops.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/integration/test_examples.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/integration/test_hooks_integration.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/integration/test_masking_integration.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/integration/test_otel_tracing.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/integration/test_remote_config_integration.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/manual/manual_test_cli_booster.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/cli/conftest.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/cli/test_cli.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/cli/test_cli_booster.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/cli/test_cli_config.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/cli/test_cli_config_cmd.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/cli/test_cli_config_schema.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/cli/test_cli_dev.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/cli/test_cli_dev_tree.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/cli/test_cli_diagnostics.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/cli/test_cli_extras_suggestion.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/cli/test_cli_init.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/cli/test_cli_paths.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/cli/test_cli_pypi.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/cli/test_cli_rich.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/cli/test_cli_rich_width.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/cli/test_cli_secrets.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/cli/test_cli_template.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/cli/test_cli_utils_internal.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/cli/test_cli_validate.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/config/test_config.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/config/test_config_ast_parser.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/config/test_config_dev.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/config/test_config_diagnostics.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/config/test_config_env.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/config/test_config_env_loading.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/config/test_config_generator.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/config/test_config_json.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/config/test_config_pydantic.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/config/test_config_required.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/config/test_config_schema.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/config/test_config_tracing.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/config/test_config_universal_env.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/config/test_config_utils.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/config/test_config_validation_group.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/config/test_config_watcher.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/config/test_custom_config_providers.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/config/test_priority_unification.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/config/test_remote_config.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/core/test_ast_indexer.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/core/test_ast_indexer_abstract.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/core/test_ast_indexer_graph.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/core/test_ast_indexer_layers.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/core/test_ast_indexer_metadata.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/core/test_dev_models.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/core/test_exceptions.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/core/test_features.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/core/test_fs.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/core/test_lifecycle.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/core/test_thread_safety.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/core/test_time.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/decorators/test_decorator_circuit_breaker.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/decorators/test_decorator_retry.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/decorators/test_decorator_timeout.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/decorators/test_decorators.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/decorators/test_rate_limit.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/dev/test_ai_lint_staged.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/dev/test_chat_context.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/dev/test_env_parser.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/dev/test_env_sync.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/dev/test_generate_few_shot.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/dev/test_linter_coverage_rule.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/dev/test_mock_server.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/dev/test_scaffold.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/events/test_event_bus.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/logger/conftest.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/logger/test_basics.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/logger/test_compression.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/logger/test_config_sections.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/logger/test_configuration.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/logger/test_context.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/logger/test_env_control.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/logger/test_files.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/logger/test_json_format.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/logger/test_logger_rich_width.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/logger/test_masking.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/logger/test_performance_security.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/logger/test_rich.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/logger/test_rotation.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/metrics/test_metrics.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/plugins/test_integration.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/plugins/test_interfaces.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/plugins/test_plugins.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/secret_manager/test_secret_manager.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/secret_manager/test_secret_manager_env.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/secret_manager/test_secret_manager_providers.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/secret_manager/test_secrets_required.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/tasks/test_scheduler.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_ai_lint_ignore.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_anticaptcha.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_async_web_client.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_capmonster.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_captcha_base.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_captcha_imports.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_cli_db.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_crypto.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_crypto_dependencies.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_diagnostics.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_env.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_events_exception_group.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_humanize_math.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_minimal_imports.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_playwright_humanize.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_proxy_pool.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_rucaptcha.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_scraping_imports.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_selenium_humanize.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_text.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_text_dependencies.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_user_agent.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_validation.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_web_client.py +0 -0
- {chutils-3.2.0 → chutils-3.3.0}/tests/unit/test_web_imports.py +0 -0
- {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.
|
|
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.
|
|
3
|
-
project_version: 3.
|
|
4
|
-
git_commit:
|
|
5
|
-
generated_at: 2026-07-
|
|
6
|
-
project_hash:
|
|
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
|
-
| `
|
|
95
|
-
| `
|
|
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]`
|
|
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 | `(
|
|
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 | | |
|
{chutils-3.2.0/conductor/tracks → chutils-3.3.0/conductor/archive}/dev_clean_20260707/plan.md
RENAMED
|
@@ -1,44 +1,44 @@
|
|
|
1
1
|
# Plan: Уборка мусора разработки (chutils dev clean)
|
|
2
2
|
|
|
3
3
|
## Phase 1: Проектирование и подготовка инфраструктуры
|
|
4
|
-
- [
|
|
5
|
-
- [
|
|
6
|
-
- [
|
|
7
|
-
- [
|
|
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
|
-
- [
|
|
11
|
-
- [
|
|
12
|
-
- [
|
|
13
|
-
- [
|
|
14
|
-
- [
|
|
15
|
-
- [
|
|
16
|
-
- [
|
|
17
|
-
- [
|
|
18
|
-
- [
|
|
19
|
-
- [
|
|
20
|
-
- [
|
|
21
|
-
- [
|
|
22
|
-
- [
|
|
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
|
-
- [
|
|
26
|
-
- [
|
|
27
|
-
- [
|
|
28
|
-
- [
|
|
29
|
-
- [
|
|
30
|
-
- [
|
|
31
|
-
- [
|
|
32
|
-
- [
|
|
33
|
-
- [
|
|
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
|
-
- [
|
|
37
|
-
- [
|
|
38
|
-
- [
|
|
39
|
-
- [
|
|
40
|
-
- [
|
|
41
|
-
- [
|
|
42
|
-
- [
|
|
43
|
-
- [
|
|
44
|
-
- [
|
|
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)
|
|
@@ -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. Написаны тесты, покрывающие логику реконнекта и фильтрации для обеих технологий.
|
|
@@ -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)
|