mirror of
https://github.com/All-Hands-AI/OpenHands.git
synced 2026-01-09 14:57:59 -05:00
Add return type annotations to docker runtime (#8543)
Co-authored-by: openhands <openhands@all-hands.dev>
This commit is contained in:
@@ -41,7 +41,7 @@ APP_PORT_RANGE_1 = (50000, 54999)
|
||||
APP_PORT_RANGE_2 = (55000, 59999)
|
||||
|
||||
|
||||
def _is_retryablewait_until_alive_error(exception):
|
||||
def _is_retryablewait_until_alive_error(exception: Exception) -> bool:
|
||||
if isinstance(exception, tenacity.RetryError):
|
||||
cause = exception.last_attempt.exception()
|
||||
return _is_retryablewait_until_alive_error(cause)
|
||||
@@ -140,10 +140,10 @@ class DockerRuntime(ActionExecutionClient):
|
||||
)
|
||||
|
||||
@property
|
||||
def action_execution_server_url(self):
|
||||
def action_execution_server_url(self) -> str:
|
||||
return self.api_url
|
||||
|
||||
async def connect(self):
|
||||
async def connect(self) -> None:
|
||||
self.send_status_message('STATUS$STARTING_RUNTIME')
|
||||
try:
|
||||
await call_sync_from_async(self._attach_to_container)
|
||||
@@ -264,7 +264,7 @@ class DockerRuntime(ActionExecutionClient):
|
||||
|
||||
return volumes
|
||||
|
||||
def init_container(self):
|
||||
def init_container(self) -> None:
|
||||
self.log('debug', 'Preparing to start container...')
|
||||
self.send_status_message('STATUS$PREPARING_CONTAINER')
|
||||
self._host_port = self._find_available_port(EXECUTION_SERVER_PORT_RANGE)
|
||||
@@ -317,15 +317,18 @@ class DockerRuntime(ActionExecutionClient):
|
||||
)
|
||||
|
||||
# Combine environment variables
|
||||
environment = {
|
||||
'port': str(self._container_port),
|
||||
'PYTHONUNBUFFERED': '1',
|
||||
# Passing in the ports means nested runtimes do not come up with their own ports!
|
||||
'VSCODE_PORT': str(self._vscode_port),
|
||||
'APP_PORT_1': self._app_ports[0],
|
||||
'APP_PORT_2': self._app_ports[1],
|
||||
'PIP_BREAK_SYSTEM_PACKAGES': '1',
|
||||
}
|
||||
environment = dict(**self.initial_env_vars)
|
||||
environment.update(
|
||||
{
|
||||
'port': str(self._container_port),
|
||||
'PYTHONUNBUFFERED': '1',
|
||||
# Passing in the ports means nested runtimes do not come up with their own ports!
|
||||
'VSCODE_PORT': str(self._vscode_port),
|
||||
'APP_PORT_1': str(self._app_ports[0]),
|
||||
'APP_PORT_2': str(self._app_ports[1]),
|
||||
'PIP_BREAK_SYSTEM_PACKAGES': '1',
|
||||
}
|
||||
)
|
||||
if self.config.debug or DEBUG:
|
||||
environment['DEBUG'] = 'true'
|
||||
# also update with runtime_startup_env_vars
|
||||
@@ -396,7 +399,7 @@ class DockerRuntime(ActionExecutionClient):
|
||||
self.close()
|
||||
raise e
|
||||
|
||||
def _attach_to_container(self):
|
||||
def _attach_to_container(self) -> None:
|
||||
self.container = self.docker_client.containers.get(self.container_name)
|
||||
if self.container.status == 'exited':
|
||||
self.container.start()
|
||||
@@ -432,7 +435,7 @@ class DockerRuntime(ActionExecutionClient):
|
||||
reraise=True,
|
||||
wait=tenacity.wait_fixed(2),
|
||||
)
|
||||
def wait_until_alive(self):
|
||||
def wait_until_alive(self) -> None:
|
||||
try:
|
||||
container = self.docker_client.containers.get(self.container_name)
|
||||
if container.status == 'exited':
|
||||
@@ -446,7 +449,7 @@ class DockerRuntime(ActionExecutionClient):
|
||||
|
||||
self.check_if_alive()
|
||||
|
||||
def close(self, rm_all_containers: bool | None = None):
|
||||
def close(self, rm_all_containers: bool | None = None) -> None:
|
||||
"""Closes the DockerRuntime and associated objects
|
||||
|
||||
Parameters:
|
||||
@@ -466,7 +469,7 @@ class DockerRuntime(ActionExecutionClient):
|
||||
)
|
||||
stop_all_containers(close_prefix)
|
||||
|
||||
def _is_port_in_use_docker(self, port):
|
||||
def _is_port_in_use_docker(self, port: int) -> bool:
|
||||
containers = self.docker_client.containers.list()
|
||||
for container in containers:
|
||||
container_ports = container.ports
|
||||
@@ -474,7 +477,9 @@ class DockerRuntime(ActionExecutionClient):
|
||||
return True
|
||||
return False
|
||||
|
||||
def _find_available_port(self, port_range, max_attempts=5):
|
||||
def _find_available_port(
|
||||
self, port_range: tuple[int, int], max_attempts: int = 5
|
||||
) -> int:
|
||||
port = port_range[1]
|
||||
for _ in range(max_attempts):
|
||||
port = find_available_tcp_port(port_range[0], port_range[1])
|
||||
@@ -493,7 +498,7 @@ class DockerRuntime(ActionExecutionClient):
|
||||
return vscode_url
|
||||
|
||||
@property
|
||||
def web_hosts(self):
|
||||
def web_hosts(self) -> dict[str, int]:
|
||||
hosts: dict[str, int] = {}
|
||||
|
||||
host_addr = os.environ.get('DOCKER_HOST_ADDR', 'localhost')
|
||||
@@ -502,7 +507,7 @@ class DockerRuntime(ActionExecutionClient):
|
||||
|
||||
return hosts
|
||||
|
||||
def pause(self):
|
||||
def pause(self) -> None:
|
||||
"""Pause the runtime by stopping the container.
|
||||
This is different from container.stop() as it ensures environment variables are properly preserved."""
|
||||
if not self.container:
|
||||
@@ -515,7 +520,7 @@ class DockerRuntime(ActionExecutionClient):
|
||||
self.container.stop()
|
||||
self.log('debug', f'Container {self.container_name} paused')
|
||||
|
||||
def resume(self):
|
||||
def resume(self) -> None:
|
||||
"""Resume the runtime by starting the container.
|
||||
This is different from container.start() as it ensures environment variables are properly restored."""
|
||||
if not self.container:
|
||||
@@ -529,7 +534,7 @@ class DockerRuntime(ActionExecutionClient):
|
||||
self.wait_until_alive()
|
||||
|
||||
@classmethod
|
||||
async def delete(cls, conversation_id: str):
|
||||
async def delete(cls, conversation_id: str) -> None:
|
||||
docker_client = cls._init_docker_client()
|
||||
try:
|
||||
container_name = CONTAINER_NAME_PREFIX + conversation_id
|
||||
@@ -542,7 +547,7 @@ class DockerRuntime(ActionExecutionClient):
|
||||
finally:
|
||||
docker_client.close()
|
||||
|
||||
def get_action_execution_server_startup_command(self):
|
||||
def get_action_execution_server_startup_command(self) -> list[str]:
|
||||
return get_action_execution_server_startup_command(
|
||||
server_port=self._container_port,
|
||||
plugins=self.plugins,
|
||||
|
||||
Reference in New Issue
Block a user