Add more extensive typing to openhands/runtime directory (#8288)

Co-authored-by: openhands <openhands@all-hands.dev>
This commit is contained in:
Graham Neubig
2025-05-06 13:51:06 -04:00
committed by GitHub
parent 59db982704
commit 601c2f6f25
13 changed files with 27 additions and 25 deletions

View File

@@ -40,7 +40,7 @@ class BrowserEnv:
self.init_browser()
atexit.register(self.close)
def get_html_text_converter(self):
def get_html_text_converter(self) -> html2text.HTML2Text:
html_text_converter = html2text.HTML2Text()
# ignore links and images
html_text_converter.ignore_links = False
@@ -56,7 +56,7 @@ class BrowserEnv:
stop=tenacity.stop_after_attempt(5) | stop_if_should_exit(),
retry=tenacity.retry_if_exception_type(BrowserInitException),
)
def init_browser(self):
def init_browser(self) -> None:
logger.debug('Starting browser env...')
try:
self.process = multiprocessing.Process(target=self.browser_process)
@@ -69,7 +69,7 @@ class BrowserEnv:
self.close()
raise BrowserInitException('Failed to start browser environment.')
def browser_process(self):
def browser_process(self) -> None:
if self.eval_mode:
assert self.browsergym_eval_env is not None
logger.info('Initializing browser env for web browsing evaluation.')
@@ -196,17 +196,18 @@ class BrowserEnv:
if self.agent_side.poll(timeout=0.01):
response_id, obs = self.agent_side.recv()
if response_id == unique_request_id:
return obs
return dict(obs)
def check_alive(self, timeout: float = 60):
def check_alive(self, timeout: float = 60) -> bool:
self.agent_side.send(('IS_ALIVE', None))
if self.agent_side.poll(timeout=timeout):
response_id, _ = self.agent_side.recv()
if response_id == 'ALIVE':
return True
logger.debug(f'Browser env is not alive. Response ID: {response_id}')
return False
def close(self):
def close(self) -> None:
if not self.process.is_alive():
return
try:
@@ -229,7 +230,7 @@ class BrowserEnv:
@staticmethod
def image_to_png_base64_url(
image: np.ndarray | Image.Image, add_data_prefix: bool = False
):
) -> str:
"""Convert a numpy array to a base64 encoded png image url."""
if isinstance(image, np.ndarray):
image = Image.fromarray(image)
@@ -248,7 +249,7 @@ class BrowserEnv:
@staticmethod
def image_to_jpg_base64_url(
image: np.ndarray | Image.Image, add_data_prefix: bool = False
):
) -> str:
"""Convert a numpy array to a base64 encoded jpeg image url."""
if isinstance(image, np.ndarray):
image = Image.fromarray(image)

View File

@@ -36,7 +36,7 @@ class DockerRuntimeBuilder(RuntimeBuilder):
self.rolling_logger = RollingLogger(max_lines=10)
@staticmethod
def check_buildx(is_podman: bool = False):
def check_buildx(is_podman: bool = False) -> bool:
"""Check if Docker Buildx is available"""
try:
result = subprocess.run(

View File

@@ -100,7 +100,7 @@ class RemoteRuntimeBuilder(RuntimeBuilder):
if status == 'SUCCESS':
logger.debug(f"Successfully built {status_data['image']}")
return status_data['image']
return str(status_data['image'])
elif status in [
'FAILURE',
'INTERNAL_ERROR',
@@ -146,4 +146,4 @@ class RemoteRuntimeBuilder(RuntimeBuilder):
else:
logger.debug(f'Image {image_name} does not exist.')
return result['exists']
return bool(result['exists'])

View File

@@ -21,12 +21,12 @@ def create_app() -> FastAPI:
)
@app.get('/')
async def root():
async def root() -> dict[str, str]:
"""Root endpoint to check if the server is running."""
return {'status': 'File viewer server is running'}
@app.get('/view')
async def view_file(path: str, request: Request):
async def view_file(path: str, request: Request) -> HTMLResponse:
"""View a file using an embedded viewer.
Args:

View File

@@ -2,7 +2,7 @@ from types import ModuleType
def import_functions(
module: ModuleType, function_names: list[str], target_globals: dict
module: ModuleType, function_names: list[str], target_globals: dict[str, object]
) -> None:
for name in function_names:
if hasattr(module, name):

View File

@@ -138,7 +138,7 @@ class JupyterKernel:
retry=retry_if_exception_type(ConnectionRefusedError),
stop=stop_after_attempt(3),
wait=wait_fixed(2),
)
) # type: ignore
async def execute(self, code: str, timeout: int = 120) -> str:
if not self.ws or self.ws.stream.closed():
await self._connect()

View File

@@ -6,7 +6,7 @@ import uuid
from enum import Enum
from typing import Any
import bashlex # type: ignore
import bashlex
import libtmux
from openhands.core.logger import openhands_logger as logger

View File

@@ -28,7 +28,7 @@ class GitHandler:
self.execute = execute_shell_fn
self.cwd: str | None = None
def set_cwd(self, cwd: str):
def set_cwd(self, cwd: str) -> None:
"""
Sets the current working directory for Git operations.

View File

@@ -14,7 +14,7 @@ class LogStreamer:
def __init__(
self,
container: docker.models.containers.Container,
logFn: Callable,
logFn: Callable[[str, str], None],
):
self.log = logFn
# Initialize all attributes before starting the thread on this instance

View File

@@ -2,7 +2,7 @@
import threading
from memory_profiler import memory_usage # type: ignore
from memory_profiler import memory_usage
from openhands.core.logger import openhands_logger as logger

View File

@@ -19,7 +19,7 @@ class RequestHTTPError(httpx.HTTPStatusError):
s = super().__str__()
if self.detail is not None:
s += f'\nDetails: {self.detail}'
return s
return str(s)
def is_retryable_error(exception: Any) -> bool:
@@ -57,4 +57,4 @@ def send_request(
response=e.response,
detail=_json.get('detail') if _json is not None else None,
) from e
return response # type: ignore
return response

View File

@@ -8,7 +8,7 @@ from enum import Enum
from pathlib import Path
import docker
from dirhash import dirhash # type: ignore
from dirhash import dirhash
from jinja2 import Environment, FileSystemLoader
import openhands
@@ -283,8 +283,9 @@ def prep_build_folder(
build_from=build_from,
extra_deps=extra_deps,
)
with open(Path(build_folder, 'Dockerfile'), 'w') as file: # type: ignore
file.write(dockerfile_content) # type: ignore
dockerfile_path = Path(build_folder, 'Dockerfile')
with open(str(dockerfile_path), 'w') as f:
f.write(dockerfile_content)
_ALPHABET = string.digits + string.ascii_lowercase

View File

@@ -5,7 +5,7 @@ import time
import psutil
def get_system_stats() -> dict:
def get_system_stats() -> dict[str, object]:
"""Get current system resource statistics.
Returns: