Files
connpy/connpy/services/provider.py
T
fluzzi32 1c814eb9fd refactor: Major upgrade to v5.1b6 - AWS SSM support & Distributed Architecture
Core & Protocols:
- Native AWS SSM support added (aws ssm start-session).
- Improved Pexpect logic for ssm, kubectl, and docker.
- Cleaned connection success messages (omitting ports for non-IP protocols).

gRPC Layer:
- Migrated gRPC modules to 'connpy/grpc_layer/'.
- Implemented dynamic node naming (e.g. ssm-i-xxxx@aws) for accurate server-side logging.
- Added automatic sys.path resolution for gRPC generated modules.
- Enhanced InteractNode response with initial connection status.

Printer & Concurrency:
- Implemented ThreadLocalStream for isolated thread-safe output.
- Self-healing Console objects to prevent 'closed file' errors in test/async environments.
- Capture clean plugin output in remote executions.

AI & Services:
- Improved tool registration and debug visualization.
- Restored native dictionary returns for AI tools to fix Web UI rendering.
- Increased backup retention to 100 copies in SyncService.
- Silenced noisy auto-sync CLI messages.

Quality & Docs:
- Total tests: 267 (all passing).
- New test suites for gRPC layer and printer concurrency.
- Updated .gitignore to exclude internal planning docs.
- Full technical documentation regenerated with pdoc.
2026-04-24 19:23:00 -03:00

72 lines
3.0 KiB
Python

from .exceptions import InvalidConfigurationError
class RemoteStub:
def __getattr__(self, name):
raise NotImplementedError(
"Remote mode (gRPC) is not yet available. "
"Use local mode or wait for the gRPC implementation."
)
class ServiceProvider:
"""Dynamic service backend. Transparently provides local or remote services."""
def __init__(self, config, mode="local", remote_host=None):
self.mode = mode
self.config = config
self.remote_host = remote_host
if mode == "local":
self._init_local()
elif mode == "remote":
self._init_remote()
else:
raise ValueError(f"Unknown service mode: {mode}")
def _init_local(self):
from .node_service import NodeService
from .profile_service import ProfileService
from .config_service import ConfigService
from .plugin_service import PluginService
from .ai_service import AIService
from .system_service import SystemService
from .execution_service import ExecutionService
from .import_export_service import ImportExportService
from .context_service import ContextService
from .sync_service import SyncService
self.nodes = NodeService(self.config)
self.profiles = ProfileService(self.config)
self.config_svc = ConfigService(self.config)
self.plugins = PluginService(self.config)
self.ai = AIService(self.config)
self.system = SystemService(self.config)
self.execution = ExecutionService(self.config)
self.import_export = ImportExportService(self.config)
self.context = ContextService(self.config)
self.sync = SyncService(self.config)
def _init_remote(self):
# Allow ConfigService to work locally so the user can revert the mode
from .config_service import ConfigService
from .context_service import ContextService
from .sync_service import SyncService
self.config_svc = ConfigService(self.config)
self.context = ContextService(self.config)
self.sync = SyncService(self.config)
if not self.remote_host:
raise InvalidConfigurationError("Remote host must be specified in remote mode")
import grpc
from ..grpc_layer.stubs import NodeStub, ProfileStub, PluginStub, AIStub, ExecutionStub, ImportExportStub, SystemStub
channel = grpc.insecure_channel(self.remote_host)
self.nodes = NodeStub(channel, remote_host=self.remote_host, config=self.config)
self.profiles = ProfileStub(channel, remote_host=self.remote_host, node_stub=self.nodes)
self.plugins = PluginStub(channel, remote_host=self.remote_host)
self.ai = AIStub(channel, remote_host=self.remote_host)
self.system = SystemStub(channel, remote_host=self.remote_host)
self.execution = ExecutionStub(channel, remote_host=self.remote_host)
self.import_export = ImportExportStub(channel, remote_host=self.remote_host)