by-framework 0.2.2.dev6__tar.gz → 0.2.2.dev8__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.
- by_framework-0.2.2.dev8/.dockerignore +18 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/.github/workflows/publish.yml +38 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/PKG-INFO +1 -1
- by_framework-0.2.2.dev8/libs/by-framework-dashboard/Dockerfile +40 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-dashboard/README.md +23 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-dashboard/pyproject.toml +1 -1
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-langgraph/pyproject.toml +1 -1
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-trace-langfuse/pyproject.toml +1 -1
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/pyproject.toml +1 -1
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/admin/cli.py +24 -8
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/common/config.py +26 -2
- by_framework-0.2.2.dev8/src/by_framework/common/constants.py +542 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/common/emitter.py +10 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/common/redis_client.py +51 -11
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/core/discovery.py +1 -1
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/core/protocol/content_type.py +1 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/core/registry.py +27 -10
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/metrics/snapshot.py +76 -80
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/trace/span_recorder.py +40 -25
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/trace/trace_writer.py +34 -20
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/worker/app.py +59 -14
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/worker/context.py +4 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/worker/heartbeat.py +26 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/worker/runner.py +42 -3
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/admin/test_cli.py +112 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/common/test_config.py +88 -0
- by_framework-0.2.2.dev8/tests/common/test_constants.py +506 -0
- by_framework-0.2.2.dev8/tests/common/test_redis_client.py +318 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/core/test_registry.py +53 -6
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/metrics/test_snapshot.py +107 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/trace/test_span_recorder.py +44 -0
- by_framework-0.2.2.dev8/tests/trace/test_trace_writer.py +87 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/worker/test_app.py +171 -10
- by_framework-0.2.2.dev8/tests/worker/test_fetch_messages.py +133 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/worker/test_heartbeat.py +29 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/uv.lock +4 -4
- by_framework-0.2.2.dev6/src/by_framework/common/constants.py +0 -296
- by_framework-0.2.2.dev6/tests/common/test_redis_client.py +0 -64
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/.github/RELEASING.md +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/.github/workflows/ci.yml +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/.github/workflows/stale.yml +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/.gitignore +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/.pre-commit-config.yaml +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/AGENTS.md +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/CHANGELOG.md +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/CLAUDE.md +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/CODE_OF_CONDUCT.md +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/CONTRIBUTING.md +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/LICENSE +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/Makefile +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/README.md +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/README_zh.md +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/SECURITY.md +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/assets/img/architecture_en.png +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/assets/img/architecture_zh.png +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/autoformat.sh +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/docs/README.md +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/docs/by-framework-trace-change-usage.html +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/docs/by-framework-trace-complete-guide.html +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/docs/plans/2026-05-15-worker-task-state-stats.md +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/docs/plans/2026-06-10-trace-metrics-correlation.md +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/docs/worker_management.html +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-adk/README.md +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-adk/pyproject.toml +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-adk/src/by_framework_adk/__init__.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-adk/src/by_framework_adk/_utils.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-adk/src/by_framework_adk/adapter.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-adk/src/by_framework_adk/worker.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-adk/tests/test_worker.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-dashboard/frontend/index.html +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-dashboard/frontend/package-lock.json +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-dashboard/frontend/package.json +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-dashboard/frontend/src/main.jsx +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-dashboard/frontend/src/styles.css +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-dashboard/frontend/vite.config.js +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-dashboard/src/by_framework_dashboard/__init__.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-dashboard/src/by_framework_dashboard/adapters.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-dashboard/src/by_framework_dashboard/dashboard.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-dashboard/src/by_framework_dashboard/static/__init__.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-dashboard/src/by_framework_dashboard/static/app.js +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-dashboard/src/by_framework_dashboard/static/index.html +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-dashboard/src/by_framework_dashboard/static/styles.css +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-dashboard/tests/test_dashboard_server.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-history-byclaw/README.md +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-history-byclaw/pyproject.toml +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-history-byclaw/src/by_framework_history_byclaw/__init__.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-history-byclaw/src/by_framework_history_byclaw/byclaw_history.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-history-byclaw/tests/test_byclaw_history.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-history-postgres/README.md +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-history-postgres/pyproject.toml +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-history-postgres/src/by_framework_history_postgres/__init__.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-history-postgres/src/by_framework_history_postgres/postgres.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-history-postgres/tests/test_postgres_history_storage.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-langgraph/README.md +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-langgraph/src/by_framework_langgraph/__init__.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-langgraph/src/by_framework_langgraph/_utils.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-langgraph/src/by_framework_langgraph/adapter.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-langgraph/src/by_framework_langgraph/tools.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-langgraph/src/by_framework_langgraph/worker.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-langgraph/tests/test_adapter.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-langgraph/tests/test_tools.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-langgraph/tests/test_utils.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-trace-langfuse/README.md +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-trace-langfuse/src/by_framework_trace_langfuse/__init__.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-trace-langfuse/src/by_framework_trace_langfuse/langfuse.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-trace-langfuse/tests/test_langfuse_import.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-trace-phoenix/README.md +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-trace-phoenix/pyproject.toml +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-trace-phoenix/src/by_framework_trace_phoenix/__init__.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-trace-phoenix/src/by_framework_trace_phoenix/phoenix.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-trace-phoenix/tests/test_phoenix_import.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-trace-phoenix/tests/test_phoenix_plugin.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-trace-query/pyproject.toml +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-trace-query/src/by_framework_trace_query/__init__.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-trace-query/src/by_framework_trace_query/client.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-trace-query/src/by_framework_trace_query/merger.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-trace-query/src/by_framework_trace_query/models.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-trace-query/src/by_framework_trace_query/redis_source.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/libs/by-framework-trace-query/tests/test_trace_query_sdk.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/pylintrc +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/scripts/python_quality.sh +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/__init__.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/__main__.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/admin/__init__.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/admin/worker_manager.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/client/__init__.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/client/byai_client.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/client/client.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/common/__init__.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/common/exceptions.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/common/logger.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/core/__init__.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/core/availability.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/core/delivery_gate.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/core/extensions/__init__.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/core/extensions/agent_config.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/core/extensions/agent_config_audit.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/core/extensions/plugin.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/core/extensions/registry.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/core/extensions/trace_provider.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/core/protocol/__init__.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/core/protocol/action_type.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/core/protocol/agent_state.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/core/protocol/byai_codec.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/core/protocol/byai_command.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/core/protocol/byai_types.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/core/protocol/commands.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/core/protocol/content_codec.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/core/protocol/data_message.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/core/protocol/data_shapes.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/core/protocol/event_type.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/core/protocol/events.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/core/protocol/message.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/core/protocol/message_header.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/core/protocol/responses.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/core/protocol/results.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/core/runtime/__init__.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/core/runtime/agent_config_manager.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/core/runtime/agent_runtime_state.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/core/runtime/file_manager.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/core/runtime/file_paths.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/core/runtime/file_permissions.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/core/runtime/filestore/__init__.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/core/runtime/filestore/base.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/core/runtime/filestore/local.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/core/runtime/history/__init__.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/core/runtime/history/base.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/core/runtime/history/history_manager.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/core/runtime/history/in_memory.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/core/runtime/session_manager.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/core/wakeup_controller.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/core/workspace.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/errors/__init__.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/errors/base.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/errors/common.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/errors/execution.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/errors/http.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/errors/protocol.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/errors/registry.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/metrics/__init__.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/metrics/catalog.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/metrics/collector.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/metrics/read_client.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/trace/__init__.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/trace/external_trace.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/trace/trace_schema.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/util/__init__.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/util/discovery_http_client.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/util/generate_message_id.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/util/http_client.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/worker/__init__.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/worker/_control_handling.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/worker/_execution_tracking.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/worker/_message_processing.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/worker/byai_context.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/worker/byai_worker.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/worker/processor.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/worker/sandbox/__init__.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/worker/sandbox/hook_sandbox.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/src/by_framework/worker/worker.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/admin/__init__.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/client/__init__.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/client/test_client.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/common/__init__.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/common/test_exceptions.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/common/test_logger.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/conftest.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/core/__init__.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/core/protocol/__init__.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/core/protocol/test_byai_codec.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/core/protocol/test_command_wire.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/core/protocol/test_protocol.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/core/protocol/test_results.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/core/runtime/history/__init__.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/core/runtime/history/test_history_persistence.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/core/runtime/test_file_access_context.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/core/runtime/test_file_manager_default_storage.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/core/runtime/test_file_paths.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/core/runtime/test_file_permissions.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/core/runtime/test_filestore_local_collection.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/core/runtime/test_filestore_local_mutation.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/core/runtime/test_filestore_local_read.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/core/runtime/test_filestore_local_search.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/core/test_agent_config_audit.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/core/test_availability.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/core/test_discovery.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/core/test_worker_manager.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/integration/__init__.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/integration/test_ask_user_flow.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/integration/test_callback_flow.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/integration/test_logger_integration.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/integration/test_scatter_gather.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/metrics/test_catalog.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/metrics/test_collector.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/metrics/test_metrics.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/metrics/test_read_client.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/plugin/__init__.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/plugin/test_langfuse_plugin.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/plugin/test_plugin_discovery.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/plugin/test_plugin_improvements.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/plugin/test_plugin_registry.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/plugin/test_plugin_system.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/trace/test_external_trace.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/trace/test_logger_correlation.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/trace/test_otel_exporter.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/util/test_discovery_http_client.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/util/test_discovery_http_client_download.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/util/test_discovery_http_client_upload.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/util/test_http_client.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/worker/__init__.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/worker/test_admin_control_handling.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/worker/test_byai_worker.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/worker/test_context.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/worker/test_control_handling.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/worker/test_emitter.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/worker/test_gateway_worker.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/worker/test_message_processing.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/worker/test_processor.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/worker/test_runner.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/worker/test_sandbox.py +0 -0
- {by_framework-0.2.2.dev6 → by_framework-0.2.2.dev8}/tests/worker/test_workspace.py +0 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
.git
|
|
2
|
+
.github
|
|
3
|
+
.pytest_cache
|
|
4
|
+
.ruff_cache
|
|
5
|
+
.mypy_cache
|
|
6
|
+
**/__pycache__
|
|
7
|
+
**/*.py[cod]
|
|
8
|
+
**/.pytest_cache
|
|
9
|
+
**/.ruff_cache
|
|
10
|
+
**/.mypy_cache
|
|
11
|
+
**/node_modules
|
|
12
|
+
**/dist
|
|
13
|
+
**/build
|
|
14
|
+
**/*.egg-info
|
|
15
|
+
.venv
|
|
16
|
+
venv
|
|
17
|
+
htmlcov
|
|
18
|
+
by-framework.log
|
|
@@ -15,6 +15,7 @@ on:
|
|
|
15
15
|
|
|
16
16
|
permissions:
|
|
17
17
|
contents: write
|
|
18
|
+
packages: write
|
|
18
19
|
pull-requests: write
|
|
19
20
|
|
|
20
21
|
jobs:
|
|
@@ -153,6 +154,43 @@ jobs:
|
|
|
153
154
|
with:
|
|
154
155
|
packages-dir: dist/
|
|
155
156
|
|
|
157
|
+
publish-dashboard-image:
|
|
158
|
+
runs-on: ubuntu-latest
|
|
159
|
+
needs:
|
|
160
|
+
- resolve-package
|
|
161
|
+
- build
|
|
162
|
+
- publish
|
|
163
|
+
if: needs.resolve-package.outputs.package_name == 'by-framework-dashboard'
|
|
164
|
+
permissions:
|
|
165
|
+
contents: read
|
|
166
|
+
packages: write
|
|
167
|
+
steps:
|
|
168
|
+
- uses: actions/checkout@v4
|
|
169
|
+
- name: Resolve image name
|
|
170
|
+
id: image
|
|
171
|
+
shell: bash
|
|
172
|
+
run: |
|
|
173
|
+
echo "name=ghcr.io/${GITHUB_REPOSITORY_OWNER,,}/by-framework-dashboard" >> "$GITHUB_OUTPUT"
|
|
174
|
+
- name: Log in to GitHub Container Registry
|
|
175
|
+
uses: docker/login-action@v3
|
|
176
|
+
with:
|
|
177
|
+
registry: ghcr.io
|
|
178
|
+
username: ${{ github.actor }}
|
|
179
|
+
password: ${{ secrets.GITHUB_TOKEN }}
|
|
180
|
+
- name: Build and publish dashboard image
|
|
181
|
+
uses: docker/build-push-action@v6
|
|
182
|
+
with:
|
|
183
|
+
context: .
|
|
184
|
+
file: libs/by-framework-dashboard/Dockerfile
|
|
185
|
+
push: true
|
|
186
|
+
tags: |
|
|
187
|
+
${{ steps.image.outputs.name }}:${{ needs.resolve-package.outputs.version }}
|
|
188
|
+
${{ steps.image.outputs.name }}:latest
|
|
189
|
+
labels: |
|
|
190
|
+
org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }}
|
|
191
|
+
org.opencontainers.image.version=${{ needs.resolve-package.outputs.version }}
|
|
192
|
+
org.opencontainers.image.title=by-framework-dashboard
|
|
193
|
+
|
|
156
194
|
post-release:
|
|
157
195
|
runs-on: ubuntu-latest
|
|
158
196
|
needs:
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# syntax=docker/dockerfile:1
|
|
2
|
+
|
|
3
|
+
FROM node:22-bookworm-slim AS frontend
|
|
4
|
+
|
|
5
|
+
WORKDIR /app/libs/by-framework-dashboard/frontend
|
|
6
|
+
COPY libs/by-framework-dashboard/frontend/package*.json ./
|
|
7
|
+
RUN npm ci --no-audit --progress=false
|
|
8
|
+
COPY libs/by-framework-dashboard/frontend/ ./
|
|
9
|
+
RUN npm run build
|
|
10
|
+
|
|
11
|
+
FROM ghcr.io/astral-sh/uv:python3.12-bookworm-slim AS runtime
|
|
12
|
+
|
|
13
|
+
ENV PYTHONUNBUFFERED=1 \
|
|
14
|
+
UV_NO_CACHE=1 \
|
|
15
|
+
PATH="/opt/venv/bin:${PATH}"
|
|
16
|
+
|
|
17
|
+
WORKDIR /app
|
|
18
|
+
|
|
19
|
+
COPY pyproject.toml uv.lock README.md ./
|
|
20
|
+
COPY src ./src
|
|
21
|
+
COPY libs/by-framework-dashboard ./libs/by-framework-dashboard
|
|
22
|
+
COPY libs/by-framework-trace-query ./libs/by-framework-trace-query
|
|
23
|
+
COPY --from=frontend /app/libs/by-framework-dashboard/src/by_framework_dashboard/static/ ./libs/by-framework-dashboard/src/by_framework_dashboard/static/
|
|
24
|
+
|
|
25
|
+
RUN uv venv /opt/venv \
|
|
26
|
+
&& uv build --wheel --project . --out-dir /tmp/wheels \
|
|
27
|
+
&& uv build --wheel --project libs/by-framework-trace-query --out-dir /tmp/wheels \
|
|
28
|
+
&& uv build --wheel --project libs/by-framework-dashboard --out-dir /tmp/wheels \
|
|
29
|
+
&& uv pip install --python /opt/venv/bin/python \
|
|
30
|
+
/tmp/wheels/by_framework-*.whl \
|
|
31
|
+
/tmp/wheels/by_framework_trace_query-*.whl \
|
|
32
|
+
/tmp/wheels/by_framework_dashboard-*.whl \
|
|
33
|
+
&& rm -rf /tmp/wheels
|
|
34
|
+
|
|
35
|
+
EXPOSE 8765
|
|
36
|
+
|
|
37
|
+
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
|
|
38
|
+
CMD python -c "import json, urllib.request; response = urllib.request.urlopen('http://127.0.0.1:8765/api/health', timeout=3); json.load(response)"
|
|
39
|
+
|
|
40
|
+
CMD ["by-framework-dashboard", "--host", "0.0.0.0", "--port", "8765"]
|
|
@@ -19,6 +19,29 @@ Then open:
|
|
|
19
19
|
http://127.0.0.1:8765
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
+
## Container Image
|
|
23
|
+
|
|
24
|
+
Dashboard release tags also publish a GHCR image:
|
|
25
|
+
|
|
26
|
+
```text
|
|
27
|
+
ghcr.io/<owner>/by-framework-dashboard:<version>
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
For example, pushing `by-framework-dashboard-v0.1.0` builds and publishes:
|
|
31
|
+
|
|
32
|
+
```text
|
|
33
|
+
ghcr.io/<owner>/by-framework-dashboard:0.1.0
|
|
34
|
+
ghcr.io/<owner>/by-framework-dashboard:latest
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
To run the image:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
docker run --rm -p 8765:8765 \
|
|
41
|
+
-e REDIS_HOST=host.docker.internal \
|
|
42
|
+
ghcr.io/<owner>/by-framework-dashboard:0.1.0
|
|
43
|
+
```
|
|
44
|
+
|
|
22
45
|
For demo data without a live Redis cluster:
|
|
23
46
|
|
|
24
47
|
```text
|
|
@@ -13,7 +13,8 @@ from rich.console import Console
|
|
|
13
13
|
from rich.table import Table
|
|
14
14
|
|
|
15
15
|
from by_framework.admin.worker_manager import WorkerManager
|
|
16
|
-
from by_framework.common.
|
|
16
|
+
from by_framework.common.config import RedisConfig
|
|
17
|
+
from by_framework.common.redis_client import init_redis, init_redis_from_url
|
|
17
18
|
from by_framework.core.registry import WorkerRegistry
|
|
18
19
|
from by_framework.metrics.snapshot import (
|
|
19
20
|
build_observability_snapshot,
|
|
@@ -27,7 +28,12 @@ from by_framework.metrics.snapshot import (
|
|
|
27
28
|
app = typer.Typer(
|
|
28
29
|
name="by-admin",
|
|
29
30
|
no_args_is_help=True,
|
|
30
|
-
help=
|
|
31
|
+
help=(
|
|
32
|
+
"by-framework cluster admin CLI. For Redis Cluster, omit --redis-url "
|
|
33
|
+
"and set REDIS_CLUSTER_HOST (comma-separated host:port list; implies "
|
|
34
|
+
"cluster mode) and REDIS_KEY_SCHEMA_VERSION=v2. REDIS_MODE=cluster + "
|
|
35
|
+
"REDIS_CLUSTER_NODES also still works."
|
|
36
|
+
),
|
|
31
37
|
)
|
|
32
38
|
worker_app = typer.Typer(no_args_is_help=True)
|
|
33
39
|
type_app = typer.Typer(no_args_is_help=True)
|
|
@@ -43,7 +49,8 @@ app.add_typer(metrics_app, name="metrics", help="Metrics and observability")
|
|
|
43
49
|
|
|
44
50
|
console = Console()
|
|
45
51
|
err_console = Console(stderr=True)
|
|
46
|
-
|
|
52
|
+
_DEFAULT_REDIS_URL = "redis://localhost:6379/0"
|
|
53
|
+
_redis_url: Optional[str] = None
|
|
47
54
|
|
|
48
55
|
|
|
49
56
|
@app.callback()
|
|
@@ -52,13 +59,16 @@ def _global(
|
|
|
52
59
|
None,
|
|
53
60
|
"--redis-url",
|
|
54
61
|
envvar=["BYAI_REDIS_URL", "REDIS_URL"],
|
|
55
|
-
help=
|
|
62
|
+
help=(
|
|
63
|
+
"Standalone Redis connection URL [env: BYAI_REDIS_URL]. "
|
|
64
|
+
"For Redis Cluster, omit this and set REDIS_CLUSTER_HOST "
|
|
65
|
+
"(comma-separated host:port list)."
|
|
66
|
+
),
|
|
56
67
|
),
|
|
57
68
|
):
|
|
58
69
|
"""by-framework cluster admin CLI."""
|
|
59
70
|
global _redis_url
|
|
60
|
-
|
|
61
|
-
_redis_url = redis_url
|
|
71
|
+
_redis_url = redis_url
|
|
62
72
|
|
|
63
73
|
|
|
64
74
|
def _run(coro): # type: ignore[no-untyped-def]
|
|
@@ -70,8 +80,14 @@ def _die(msg: str, code: int = 1) -> None:
|
|
|
70
80
|
raise typer.Exit(code)
|
|
71
81
|
|
|
72
82
|
|
|
73
|
-
def _get_redis():
|
|
74
|
-
|
|
83
|
+
def _get_redis(redis_url: Optional[str] = None):
|
|
84
|
+
configured_url = redis_url if redis_url is not None else _redis_url
|
|
85
|
+
if configured_url:
|
|
86
|
+
return init_redis_from_url(configured_url)
|
|
87
|
+
config = RedisConfig.from_env()
|
|
88
|
+
if config.mode == "cluster":
|
|
89
|
+
return init_redis(config=config)
|
|
90
|
+
return init_redis_from_url(_DEFAULT_REDIS_URL)
|
|
75
91
|
|
|
76
92
|
|
|
77
93
|
# --------------------------------------------------------------------------- #
|
|
@@ -6,7 +6,7 @@ Provides typed configuration loaded from environment variables.
|
|
|
6
6
|
|
|
7
7
|
import os
|
|
8
8
|
from dataclasses import dataclass, field
|
|
9
|
-
from typing import Optional
|
|
9
|
+
from typing import Literal, Optional
|
|
10
10
|
|
|
11
11
|
from by_framework.common.constants import RedisKeys
|
|
12
12
|
|
|
@@ -22,13 +22,35 @@ class RedisConfig:
|
|
|
22
22
|
username: Optional[str] = None
|
|
23
23
|
decode_responses: bool = True
|
|
24
24
|
max_connections: Optional[int] = None
|
|
25
|
+
mode: Literal["standalone", "cluster"] = "standalone"
|
|
26
|
+
cluster_nodes: Optional[list[tuple[str, int]]] = None
|
|
27
|
+
socket_connect_timeout: int = 5
|
|
28
|
+
socket_timeout: int = 10
|
|
25
29
|
|
|
26
30
|
@classmethod
|
|
27
31
|
def from_env(cls) -> "RedisConfig":
|
|
28
|
-
"""Load Redis configuration from environment variables.
|
|
32
|
+
"""Load Redis configuration from environment variables.
|
|
33
|
+
|
|
34
|
+
REDIS_CLUSTER_HOST (comma-separated "host:port" list) is the
|
|
35
|
+
preferred way to configure Cluster mode: just setting it is enough
|
|
36
|
+
to switch to cluster mode, no separate REDIS_MODE=cluster needed.
|
|
37
|
+
An explicit REDIS_MODE still takes precedence when set, so existing
|
|
38
|
+
explicit REDIS_MODE=cluster + REDIS_CLUSTER_NODES setups keep working.
|
|
39
|
+
"""
|
|
29
40
|
password = os.environ.get("REDIS_PASSWORD", "")
|
|
30
41
|
username = os.environ.get("REDIS_USERNAME") or None
|
|
31
42
|
max_connections = os.environ.get("REDIS_MAX_CONNECTIONS")
|
|
43
|
+
cluster_host_str = os.environ.get("REDIS_CLUSTER_HOST")
|
|
44
|
+
cluster_nodes_str = cluster_host_str or os.environ.get("REDIS_CLUSTER_NODES")
|
|
45
|
+
mode = os.environ.get("REDIS_MODE") or (
|
|
46
|
+
"cluster" if cluster_host_str else "standalone"
|
|
47
|
+
)
|
|
48
|
+
cluster_nodes = None
|
|
49
|
+
if cluster_nodes_str:
|
|
50
|
+
cluster_nodes = []
|
|
51
|
+
for node in cluster_nodes_str.split(","):
|
|
52
|
+
node_host, node_port = node.rsplit(":", 1)
|
|
53
|
+
cluster_nodes.append((node_host, int(node_port)))
|
|
32
54
|
return cls(
|
|
33
55
|
host=os.environ.get("REDIS_HOST", "localhost"),
|
|
34
56
|
port=int(os.environ.get("REDIS_PORT", "6379")),
|
|
@@ -36,6 +58,8 @@ class RedisConfig:
|
|
|
36
58
|
password=password,
|
|
37
59
|
username=username,
|
|
38
60
|
max_connections=int(max_connections) if max_connections else None,
|
|
61
|
+
mode=mode,
|
|
62
|
+
cluster_nodes=cluster_nodes,
|
|
39
63
|
)
|
|
40
64
|
|
|
41
65
|
|