Refactor code structure for improved readability and maintainability

This commit is contained in:
Yeuoly
2025-12-30 16:31:34 +08:00
parent a513ab9a59
commit 274f9a3f32
9 changed files with 2793 additions and 2351 deletions

View File

@ -1,4 +1,6 @@
from collections.abc import Mapping
from enum import StrEnum
from typing import Any
from pydantic import BaseModel, Field
@ -19,6 +21,9 @@ class Metadata(BaseModel):
id: str = Field(description="The unique identifier of the virtual environment.")
arch: Arch = Field(description="Which architecture was used to create the virtual environment.")
store: Mapping[str, Any] = Field(
default_factory=dict, description="The store information of the virtual environment., Additional data."
)
class ConnectionHandle(BaseModel):
@ -34,5 +39,21 @@ class CommandStatus(BaseModel):
Status of a command executed in the virtual environment.
"""
class Status(StrEnum):
RUNNING = "running"
COMPLETED = "completed"
pid: int = Field(description="The process ID of the command.")
return_code: int = Field(description="The return code of the command execution.")
status: Status = Field(description="The status of the command execution.")
exit_code: int | None = Field(description="The return code of the command execution.")
class FileState(BaseModel):
"""
State of a file in the virtual environment.
"""
size: int = Field(description="The size of the file in bytes.")
path: str = Field(description="The path of the file in the virtual environment.")
created_at: int = Field(description="The creation timestamp of the file.")
updated_at: int = Field(description="The last modified timestamp of the file.")

View File

@ -0,0 +1,10 @@
class ArchNotSupportedError(Exception):
"""Exception raised when the architecture is not supported."""
pass
class VirtualEnvironmentLaunchFailedError(Exception):
"""Exception raised when launching the virtual environment fails."""
pass

View File

@ -1,9 +1,9 @@
from abc import ABC, abstractmethod
from collections.abc import Mapping
from collections.abc import Mapping, Sequence
from io import BytesIO
from typing import Any
from core.virtual_environment.__base.entities import CommandStatus, ConnectionHandle, Metadata
from core.virtual_environment.__base.entities import CommandStatus, ConnectionHandle, FileState, Metadata
class VirtualEnvironment(ABC):
@ -11,30 +11,30 @@ class VirtualEnvironment(ABC):
Base class for virtual environment implementations.
"""
@abstractmethod
def request_environment(self, options: Mapping[str, Any]) -> Metadata:
def __init__(self, options: Mapping[str, Any]) -> None:
"""
Initialize the virtual environment with metadata.
"""
Request a virtual environment with the given options.
Args:
options (Mapping[str, Any]): Options for requesting the virtual environment.
Those options are implementation-specific, which can be defined in environment
self.options = options
self.metadata = self.construct_environment(options)
@abstractmethod
def construct_environment(self, options: Mapping[str, Any]) -> Metadata:
"""
Construct the unique identifier for the virtual environment.
Returns:
Metadata: Metadata about the requested virtual environment.
Raises:
Exception: If the environment cannot be requested.
str: The unique identifier of the virtual environment.
"""
@abstractmethod
def upload_file(self, environment_id: str, destination_path: str, content: BytesIO) -> None:
def upload_file(self, path: str, content: BytesIO) -> None:
"""
Upload a file to the virtual environment.
Args:
environment_id (str): The unique identifier of the virtual environment.
destination_path (str): The destination path in the virtual environment.
path (str): The destination path in the virtual environment.
content (BytesIO): The content of the file to upload.
Raises:
@ -42,12 +42,49 @@ class VirtualEnvironment(ABC):
"""
@abstractmethod
def establish_connection(self, environment_id: str) -> ConnectionHandle:
def download_file(self, path: str) -> BytesIO:
"""
Establish a connection to the virtual environment.
Download a file from the virtual environment.
Args:
environment_id (str): The unique identifier of the virtual environment.
source_path (str): The source path in the virtual environment.
Returns:
BytesIO: The content of the downloaded file.
Raises:
Exception: If the file cannot be downloaded.
"""
@abstractmethod
def list_files(self, directory_path: str, limit: int) -> Sequence[FileState]:
"""
List files in a directory of the virtual environment.
Args:
directory_path (str): The directory path in the virtual environment.
limit (int): The maximum number of files(including recursive paths) to return.
Returns:
Sequence[FileState]: A list of file states in the specified directory.
Raises:
Exception: If the files cannot be listed.
Example:
If the directory structure is like:
/dir
/subdir1
file1.txt
/subdir2
file2.txt
And limit is 2, the returned list may look like:
[
FileState(path="/dir/subdir1/file1.txt", is_directory=False, size=1234, created_at=..., updated_at=...),
FileState(path="/dir/subdir2", is_directory=True, size=0, created_at=..., updated_at=...),
]
"""
@abstractmethod
def establish_connection(self) -> ConnectionHandle:
"""
Establish a connection to the virtual environment.
Returns:
ConnectionHandle: Handle for managing the connection to the virtual environment.
@ -69,13 +106,10 @@ class VirtualEnvironment(ABC):
"""
@abstractmethod
def release_environment(self, environment_id: str) -> None:
def release_environment(self) -> None:
"""
Release the virtual environment.
Args:
environment_id (str): The unique identifier of the virtual environment.
Raises:
Exception: If the environment cannot be released.
Multiple calls to `release_environment` with the same `environment_id` is acceptable.
@ -92,7 +126,7 @@ class VirtualEnvironment(ABC):
Returns:
tuple[int, int, int, int]: A tuple containing pid and 3 handle to os.pipe(): (stdin, stdout, stderr).
After exuection, the 3 handles will be closed by `execute_command` itself.
After exuection, the 3 handles will be closed by caller.
"""
@abstractmethod