cua-computer 0.1.28__py3-none-any.whl → 0.2.0__py3-none-any.whl

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.
@@ -0,0 +1,105 @@
1
+ """Base provider interface for VM backends."""
2
+
3
+ import abc
4
+ from enum import Enum
5
+ from typing import Dict, List, Optional, Any, AsyncContextManager
6
+
7
+
8
+ class VMProviderType(str, Enum):
9
+ """Enum of supported VM provider types."""
10
+ LUME = "lume"
11
+ LUMIER = "lumier"
12
+ CLOUD = "cloud"
13
+ UNKNOWN = "unknown"
14
+
15
+
16
+ class BaseVMProvider(AsyncContextManager):
17
+ """Base interface for VM providers.
18
+
19
+ All VM provider implementations must implement this interface.
20
+ """
21
+
22
+ @property
23
+ @abc.abstractmethod
24
+ def provider_type(self) -> VMProviderType:
25
+ """Get the provider type."""
26
+ pass
27
+
28
+ @abc.abstractmethod
29
+ async def get_vm(self, name: str, storage: Optional[str] = None) -> Dict[str, Any]:
30
+ """Get VM information by name.
31
+
32
+ Args:
33
+ name: Name of the VM to get information for
34
+ storage: Optional storage path override. If provided, this will be used
35
+ instead of the provider's default storage path.
36
+
37
+ Returns:
38
+ Dictionary with VM information including status, IP address, etc.
39
+ """
40
+ pass
41
+
42
+ @abc.abstractmethod
43
+ async def list_vms(self) -> List[Dict[str, Any]]:
44
+ """List all available VMs."""
45
+ pass
46
+
47
+ @abc.abstractmethod
48
+ async def run_vm(self, image: str, name: str, run_opts: Dict[str, Any], storage: Optional[str] = None) -> Dict[str, Any]:
49
+ """Run a VM by name with the given options.
50
+
51
+ Args:
52
+ image: Name/tag of the image to use
53
+ name: Name of the VM to run
54
+ run_opts: Dictionary of run options (memory, cpu, etc.)
55
+ storage: Optional storage path override. If provided, this will be used
56
+ instead of the provider's default storage path.
57
+
58
+ Returns:
59
+ Dictionary with VM run status and information
60
+ """
61
+ pass
62
+
63
+ @abc.abstractmethod
64
+ async def stop_vm(self, name: str, storage: Optional[str] = None) -> Dict[str, Any]:
65
+ """Stop a VM by name.
66
+
67
+ Args:
68
+ name: Name of the VM to stop
69
+ storage: Optional storage path override. If provided, this will be used
70
+ instead of the provider's default storage path.
71
+
72
+ Returns:
73
+ Dictionary with VM stop status and information
74
+ """
75
+ pass
76
+
77
+ @abc.abstractmethod
78
+ async def update_vm(self, name: str, update_opts: Dict[str, Any], storage: Optional[str] = None) -> Dict[str, Any]:
79
+ """Update VM configuration.
80
+
81
+ Args:
82
+ name: Name of the VM to update
83
+ update_opts: Dictionary of update options (memory, cpu, etc.)
84
+ storage: Optional storage path override. If provided, this will be used
85
+ instead of the provider's default storage path.
86
+
87
+ Returns:
88
+ Dictionary with VM update status and information
89
+ """
90
+ pass
91
+
92
+ @abc.abstractmethod
93
+ async def get_ip(self, name: str, storage: Optional[str] = None, retry_delay: int = 2) -> str:
94
+ """Get the IP address of a VM, waiting indefinitely until it's available.
95
+
96
+ Args:
97
+ name: Name of the VM to get the IP for
98
+ storage: Optional storage path override. If provided, this will be used
99
+ instead of the provider's default storage path.
100
+ retry_delay: Delay between retries in seconds (default: 2)
101
+
102
+ Returns:
103
+ IP address of the VM when it becomes available
104
+ """
105
+ pass
@@ -0,0 +1,5 @@
1
+ """CloudProvider module for interacting with cloud-based virtual machines."""
2
+
3
+ from .provider import CloudProvider
4
+
5
+ __all__ = ["CloudProvider"]
@@ -0,0 +1,100 @@
1
+ """Cloud VM provider implementation.
2
+
3
+ This module contains a stub implementation for a future cloud VM provider.
4
+ """
5
+
6
+ import logging
7
+ from typing import Dict, List, Optional, Any
8
+
9
+ from ..base import BaseVMProvider, VMProviderType
10
+
11
+ # Setup logging
12
+ logger = logging.getLogger(__name__)
13
+
14
+ class CloudProvider(BaseVMProvider):
15
+ """Cloud VM Provider stub implementation.
16
+
17
+ This is a placeholder for a future cloud VM provider implementation.
18
+ """
19
+
20
+ def __init__(
21
+ self,
22
+ host: str = "localhost",
23
+ port: int = 7777,
24
+ storage: Optional[str] = None,
25
+ verbose: bool = False,
26
+ ):
27
+ """Initialize the Cloud provider.
28
+
29
+ Args:
30
+ host: Host to use for API connections (default: localhost)
31
+ port: Port for the API server (default: 7777)
32
+ storage: Path to store VM data
33
+ verbose: Enable verbose logging
34
+ """
35
+ self.host = host
36
+ self.port = port
37
+ self.storage = storage
38
+ self.verbose = verbose
39
+
40
+ logger.warning("CloudProvider is not yet implemented")
41
+
42
+ @property
43
+ def provider_type(self) -> VMProviderType:
44
+ """Get the provider type."""
45
+ return VMProviderType.CLOUD
46
+
47
+ async def __aenter__(self):
48
+ """Enter async context manager."""
49
+ logger.debug("Entering CloudProvider context")
50
+ return self
51
+
52
+ async def __aexit__(self, exc_type, exc_val, exc_tb):
53
+ """Exit async context manager."""
54
+ logger.debug("Exiting CloudProvider context")
55
+
56
+ async def get_vm(self, name: str, storage: Optional[str] = None) -> Dict[str, Any]:
57
+ """Get VM information by name."""
58
+ logger.warning("CloudProvider.get_vm is not implemented")
59
+ return {
60
+ "name": name,
61
+ "status": "unavailable",
62
+ "message": "CloudProvider is not implemented"
63
+ }
64
+
65
+ async def list_vms(self) -> List[Dict[str, Any]]:
66
+ """List all available VMs."""
67
+ logger.warning("CloudProvider.list_vms is not implemented")
68
+ return []
69
+
70
+ async def run_vm(self, image: str, name: str, run_opts: Dict[str, Any], storage: Optional[str] = None) -> Dict[str, Any]:
71
+ """Run a VM with the given options."""
72
+ logger.warning("CloudProvider.run_vm is not implemented")
73
+ return {
74
+ "name": name,
75
+ "status": "unavailable",
76
+ "message": "CloudProvider is not implemented"
77
+ }
78
+
79
+ async def stop_vm(self, name: str, storage: Optional[str] = None) -> Dict[str, Any]:
80
+ """Stop a running VM."""
81
+ logger.warning("CloudProvider.stop_vm is not implemented")
82
+ return {
83
+ "name": name,
84
+ "status": "stopped",
85
+ "message": "CloudProvider is not implemented"
86
+ }
87
+
88
+ async def update_vm(self, name: str, update_opts: Dict[str, Any], storage: Optional[str] = None) -> Dict[str, Any]:
89
+ """Update VM configuration."""
90
+ logger.warning("CloudProvider.update_vm is not implemented")
91
+ return {
92
+ "name": name,
93
+ "status": "unchanged",
94
+ "message": "CloudProvider is not implemented"
95
+ }
96
+
97
+ async def get_ip(self, name: str, storage: Optional[str] = None, retry_delay: int = 2) -> str:
98
+ """Get the IP address of a VM."""
99
+ logger.warning("CloudProvider.get_ip is not implemented")
100
+ raise NotImplementedError("CloudProvider.get_ip is not implemented")
@@ -0,0 +1,118 @@
1
+ """Factory for creating VM providers."""
2
+
3
+ import logging
4
+ from typing import Dict, Optional, Any, Type, Union
5
+
6
+ from .base import BaseVMProvider, VMProviderType
7
+
8
+ logger = logging.getLogger(__name__)
9
+
10
+
11
+ class VMProviderFactory:
12
+ """Factory for creating VM providers based on provider type."""
13
+
14
+ @staticmethod
15
+ def create_provider(
16
+ provider_type: Union[str, VMProviderType],
17
+ port: int = 7777,
18
+ host: str = "localhost",
19
+ bin_path: Optional[str] = None,
20
+ storage: Optional[str] = None,
21
+ shared_path: Optional[str] = None,
22
+ image: Optional[str] = None,
23
+ verbose: bool = False,
24
+ ephemeral: bool = False,
25
+ noVNC_port: Optional[int] = None
26
+ ) -> BaseVMProvider:
27
+ """Create a VM provider of the specified type.
28
+
29
+ Args:
30
+ provider_type: Type of VM provider to create
31
+ port: Port for the API server
32
+ host: Hostname for the API server
33
+ bin_path: Path to provider binary if needed
34
+ storage: Path for persistent VM storage
35
+ shared_path: Path for shared folder between host and VM
36
+ image: VM image to use (for Lumier provider)
37
+ verbose: Enable verbose logging
38
+ ephemeral: Use ephemeral (temporary) storage
39
+ noVNC_port: Specific port for noVNC interface (for Lumier provider)
40
+
41
+ Returns:
42
+ An instance of the requested VM provider
43
+
44
+ Raises:
45
+ ImportError: If the required dependencies for the provider are not installed
46
+ ValueError: If the provider type is not supported
47
+ """
48
+ # Convert string to enum if needed
49
+ if isinstance(provider_type, str):
50
+ try:
51
+ provider_type = VMProviderType(provider_type.lower())
52
+ except ValueError:
53
+ provider_type = VMProviderType.UNKNOWN
54
+
55
+ if provider_type == VMProviderType.LUME:
56
+ try:
57
+ from .lume import LumeProvider, HAS_LUME
58
+ if not HAS_LUME:
59
+ raise ImportError(
60
+ "The pylume package is required for LumeProvider. "
61
+ "Please install it with 'pip install cua-computer[lume]'"
62
+ )
63
+ return LumeProvider(
64
+ port=port,
65
+ host=host,
66
+ storage=storage,
67
+ verbose=verbose,
68
+ ephemeral=ephemeral
69
+ )
70
+ except ImportError as e:
71
+ logger.error(f"Failed to import LumeProvider: {e}")
72
+ raise ImportError(
73
+ "The pylume package is required for LumeProvider. "
74
+ "Please install it with 'pip install cua-computer[lume]'"
75
+ ) from e
76
+ elif provider_type == VMProviderType.LUMIER:
77
+ try:
78
+ from .lumier import LumierProvider, HAS_LUMIER
79
+ if not HAS_LUMIER:
80
+ raise ImportError(
81
+ "Docker is required for LumierProvider. "
82
+ "Please install Docker for Apple Silicon and Lume CLI before using this provider."
83
+ )
84
+ return LumierProvider(
85
+ port=port,
86
+ host=host,
87
+ storage=storage,
88
+ shared_path=shared_path,
89
+ image=image or "macos-sequoia-cua:latest",
90
+ verbose=verbose,
91
+ ephemeral=ephemeral,
92
+ noVNC_port=noVNC_port
93
+ )
94
+ except ImportError as e:
95
+ logger.error(f"Failed to import LumierProvider: {e}")
96
+ raise ImportError(
97
+ "Docker and Lume CLI are required for LumierProvider. "
98
+ "Please install Docker for Apple Silicon and run the Lume installer script."
99
+ ) from e
100
+
101
+ elif provider_type == VMProviderType.CLOUD:
102
+ try:
103
+ from .cloud import CloudProvider
104
+ # Return the stub implementation of CloudProvider
105
+ return CloudProvider(
106
+ host=host,
107
+ port=port,
108
+ storage=storage,
109
+ verbose=verbose
110
+ )
111
+ except ImportError as e:
112
+ logger.error(f"Failed to import CloudProvider: {e}")
113
+ raise ImportError(
114
+ "The CloudProvider is not fully implemented yet. "
115
+ "Please use LUME or LUMIER provider instead."
116
+ ) from e
117
+ else:
118
+ raise ValueError(f"Unsupported provider type: {provider_type}")
@@ -0,0 +1,9 @@
1
+ """Lume VM provider implementation."""
2
+
3
+ try:
4
+ from .provider import LumeProvider
5
+ HAS_LUME = True
6
+ __all__ = ["LumeProvider"]
7
+ except ImportError:
8
+ HAS_LUME = False
9
+ __all__ = []