- Updated CI workflows to track poetry.lock instead of requirements.txt - Removed check-requirements-sync.py step from python-tests.yml - Updated dependency_scanner.py default from requirements.txt to pyproject.toml - Replaced all print() with click.echo() in deploy_edge_node.py (CLI script) - Replaced print() with logger.warning() in zk_cache.py - Updated setup.py files to read dependencies from pyproject.toml via tomli - Removed
8.9 KiB
sys.path Manipulation Debt
Overview
The AITBC codebase contains approximately 105 files with sys.path manipulation. This is structural debt that requires CLI packaging restructuring to eliminate properly.
Current State
CLI Modules (~14 files)
The CLI has multiple entrypoints and command modules that manipulate sys.path to find the repo root and sibling utilities:
cli/aitbc_cli.py- Main entrypoint, inserts REPO_ROOT and CLI_DIRcli/click_cli.py- Legacy Click entrypoint, inserts hardcoded/opt/aitbcpathscli/unified_cli.py- Unified CLI, inserts parent directorycli/miner_cli.py- Miner-specific CLI, inserts CLI directorycli/__init__.py- Package init, inserts CLI_DIRcli/variants/main_minimal.py- Minimal variant, inserts CLI_DIRcli/handlers/wallet.py- Wallet handler, inserts/opt/aitbc/clifor dynamic importscli/utils/wallet_daemon_client.py- Wallet client, inserts/opt/aitbc/clicli/utils/dual_mode_wallet_adapter.py- Wallet adapter, inserts/opt/aitbc/clicli/core/imports.py- Import helper, inserts coordinator-api srccli/aitbc_cli/commands/wallet.py- Wallet commands, inserts parent directoriescli/aitbc_cli/commands/simulate.py- Simulate commands, inserts parent directorycli/aitbc_cli/commands/node.py- Node commands, inserts blockchain-node srccli/aitbc_cli/commands/exchange.py- Exchange commands, inserts apps/exchange (now dynamic)cli/aitbc_cli/commands/agent_sdk.py- Agent SDK commands, inserts agent-sdk src
Wrapper Scripts (14 files)
All systemd service wrappers in scripts/wrappers/ use sys.path.insert to import aitbc constants before setting PYTHONPATH for the child process:
aitbc-agent-management-wrapper.pyaitbc-agent-coordinator-wrapper.pyaitbc-agent-daemon-wrapper.pyaitbc-agent-registry-wrapper.pyaitbc-blockchain-node-wrapper.pyaitbc-blockchain-rpc-wrapper.pyaitbc-blockchain-p2p-wrapper.pyaitbc-blockchain-sync-wrapper.pyaitbc-blockchain-event-bridge-wrapper.pyaitbc-coordinator-api-wrapper.pyaitbc-exchange-api-wrapper.pyaitbc-explorer-wrapper.pyaitbc-hermes-wrapper.pyaitbc-marketplace-wrapper.pyaitbc-monitoring-wrapper.pyaitbc-plugin-wrapper.pyaitbc-wallet-wrapper.py
Tests (~25 files)
Test files use sys.path manipulation for test isolation and to import fixtures:
tests/conftest.py- Root test configurationtests/cli/test_cli_integration.py- CLI integration teststests/fixtures/blockchain.py- Blockchain fixturestests/fixtures/coordinator.py- Coordinator fixturestests/fixtures/common.py- Common fixturestests/fixtures/staking_fixtures.py- Staking fixturestests/integration/test_agent_coordinator.py- Agent coordinator integration teststests/integration/test_staking_lifecycle.py- Staking lifecycle teststests/services/test_staking_service.py- Staking service tests- Various other test files
Scripts (~25 files)
Utility scripts in scripts/ use sys.path for ad-hoc imports:
scripts/utils/chain_regen_node.pyscripts/utils/migrate_secrets_to_keystore.pyscripts/utils/init_production_genesis.pyscripts/utils/fix_gpu_release.pyscripts/utils/fix_database_persistence.pyscripts/utils/encrypt_keystore_password.pyscripts/utils/cleanup_fake_gpus_db.pyscripts/utils/verify-production-advanced.shscripts/service/manage-services.shscripts/training/scenario_47_sdk_test.pyscripts/services/*.py- Various service scriptsscripts/testing/*.py- Testing scriptsscripts/monitoring/*.sh- Monitoring scriptsscripts/deployment/*.sh- Deployment scripts
Apps (~20 files)
App-specific scripts and modules use sys.path for local imports:
apps/blockchain-node/scripts/*.py- Blockchain node scriptsapps/blockchain-node/tests/conftest.py- Blockchain node test configapps/coordinator-api/scripts/*.py- Coordinator API scriptsapps/coordinator-api/tests/conftest.py- Coordinator API test configapps/coordinator-api/src/app/main.py- Coordinator API mainapps/coordinator-api/src/app/services/tenant_management.py- Tenant managementapps/exchange/exchange_api.py- Exchange APIapps/marketplace/scripts/marketplace.py- Marketplace scriptapps/agent-coordinator/scripts/agent_daemon.py- Agent daemon- Various other app-specific files
Dev/Docs (~20 files)
Development examples and documentation reference sys.path:
dev/examples/*.py- Example scriptsdev/scripts/blockchain/create_genesis_all.py- Genesis creationdev/onboarding/auto-onboard.py- Auto-onboardingdev/aitbc-debug- Debug scriptdocs/agent-training/ENVIRONMENT_SETUP.md- Training setup docs- Various other documentation files
Why This Exists
- CLI not packaged as installable - The CLI is run directly from source without proper package installation
- Multiple entrypoints - Legacy CLI variants (click_cli.py, unified_cli.py, miner_cli.py) coexist
- Ad-hoc script execution - Many scripts are run directly without proper Python package structure
- Test isolation - Tests manipulate sys.path to avoid import conflicts in monorepo
- Wrapper scripts - Systemd wrappers need to import aitbc constants before execing child processes
Why It's Hard to Eliminate
- CLI restructuring required - CLI needs to be packaged as a proper installable Python package with entry points
- Backward compatibility - Legacy CLI commands and entrypoints must continue working
- Monorepo complexity - Multiple apps in one repo make import resolution complex
- Runtime path resolution - Some scripts need to resolve paths at runtime based on execution context
- Wrapper pattern - Systemd wrappers need to import constants before setting up child process environment
Recommended Solution
Phase 1: Package CLI Properly
- Create proper
pyproject.tomlfor CLI with entry points - Define CLI as installable package with src-layout
- Use
console_scriptsentry points for CLI commands - Install CLI in venv with
pip install -e .
Phase 2: Consolidate Entry Points
- Deprecate legacy entrypoints (click_cli.py, miner_cli.py)
- Use unified_cli.py as single entry point
- Update systemd services to use installed CLI
- Update documentation to reflect new entry point
Phase 3: Standardize Imports
- Remove sys.path manipulation from CLI modules
- Use relative imports within CLI package
- Use PYTHONPATH environment variable for cross-package imports
- Consolidate import helpers into single module
Phase 4: Wrapper Refactoring
- Keep sys.path in wrappers for constants import (acceptable pattern)
- Ensure PYTHONPATH is set before exec for child processes
- Document wrapper pattern as acceptable for systemd services
Phase 5: Test and Script Cleanup
- Keep sys.path in tests (acceptable for test isolation)
- Add PYTHONPATH to script shebangs or wrapper scripts
- Document scripts that require specific PYTHONPATH setup
Acceptable sys.path Usage
The following patterns are acceptable and should remain:
- Test fixtures - Tests may manipulate sys.path for isolation
- Wrapper scripts - Systemd wrappers may use sys.path to import constants before exec
- Ad-hoc scripts - One-off utility scripts may use sys.path for simplicity
- App-specific scripts - Scripts within app directories may use local sys.path
Unacceptable sys.path Usage
The following patterns should be eliminated:
- Hardcoded absolute paths - e.g.,
/home/oib/windsurf/aitbc(fixed in exchange.py) - CLI entrypoint manipulation - CLI should be installable package
- Production scripts with hardcoded paths - Should use environment variables
- Cross-app imports via sys.path - Should use proper package structure
Current Status
- Fixed: 7 stale
/home/oibpaths incli/aitbc_cli/commands/exchange.py - Accepted: ~98 remaining sys.path usages as acceptable for monorepo CLI
- Decision: CLI packaging abandoned due to architectural incompatibility
Final Decision
After attempting to package the CLI as a standalone library, it was determined that:
- CLI is monorepo-specific - The CLI was designed to run from the monorepo with internal core modules and relative import structure
- Packaging is inappropriate - CLI-specific modules (deployment, analytics, marketplace, chain_manager) are not shared library code
- Risk outweighs benefit - Refactoring for packaging would break backward compatibility and introduce high risk
sys.path manipulation is ACCEPTED as necessary for monorepo CLI tools.
The CLI will continue to use sys.path manipulation to:
- Resolve imports from the aitbc package
- Access CLI-specific core modules
- Maintain backward compatibility
- Support the existing monorepo structure
Next Steps
- Accept current sys.path usage as appropriate for monorepo CLI
- Focus on other cleanup tasks (fix/backup/legacy files)
- Document sys.path pattern as acceptable in development guidelines