feat: add exists method to sandbox sources for existence checks

- Implemented the `exists` method in `SandboxFileSource` and its subclasses to verify the availability of sandbox sources.
- Updated `SandboxFileService` to utilize the new `exists` method for improved error handling when listing files and downloading files.
- Removed the previous check for storage existence in `archive_source.py` and replaced it with the new method.
This commit is contained in:
Harry
2026-01-30 17:32:12 +08:00
parent 25ee3f7bc4
commit 3f5f893e6c
5 changed files with 32 additions and 3 deletions

View File

@@ -69,8 +69,6 @@ print(json.dumps(entries))
from extensions.storage.file_presign_storage import FilePresignStorage
storage_key = f"sandbox_archives/{self._tenant_id}/{self._sandbox_id}.tar.gz"
if not storage.exists(storage_key):
raise ValueError("Sandbox archive not found")
presign_storage = FilePresignStorage(storage.storage_runner)
return presign_storage.get_download_url(storage_key, self._EXPORT_EXPIRES_IN_SECONDS)
@@ -80,9 +78,13 @@ print(json.dumps(entries))
return ZipSandbox(tenant_id=self._tenant_id, user_id="system", app_id="sandbox-archive-browser")
def exists(self) -> bool:
"""Check if the sandbox archive exists in storage."""
storage_key = f"sandbox_archives/{self._tenant_id}/{self._sandbox_id}.tar.gz"
return storage.exists(storage_key)
def list_files(self, *, path: str, recursive: bool) -> list[SandboxFileNode]:
archive_url = self._get_archive_download_url()
with self._create_zip_sandbox() as zs:
# Download and extract the archive
archive_path = zs.download_archive(archive_url, path="workspace.tar.gz")

View File

@@ -14,6 +14,15 @@ class SandboxFileSource(abc.ABC):
self._tenant_id = tenant_id
self._sandbox_id = sandbox_id
@abc.abstractmethod
def exists(self) -> bool:
"""Check if the sandbox source exists and is available.
Returns:
True if the sandbox source exists and can be accessed, False otherwise.
"""
raise NotImplementedError
@abc.abstractmethod
def list_files(self, *, path: str, recursive: bool) -> list[SandboxFileNode]:
raise NotImplementedError

View File

@@ -35,6 +35,10 @@ class SandboxFileBrowser:
return SandboxFileRuntimeSource(tenant_id=self._tenant_id, sandbox_id=self._sandbox_id, runtime=runtime)
return SandboxFileArchiveSource(tenant_id=self._tenant_id, sandbox_id=self._sandbox_id)
def exists(self) -> bool:
"""Check if the sandbox source exists and is available."""
return self._backend().exists()
def list_files(self, *, path: str | None = None, recursive: bool = False) -> list[SandboxFileNode]:
workspace_path = self._normalize_workspace_path(path)
return self._backend().list_files(path=workspace_path, recursive=recursive)

View File

@@ -20,6 +20,10 @@ class SandboxFileRuntimeSource(SandboxFileSource):
super().__init__(tenant_id=tenant_id, sandbox_id=sandbox_id)
self._runtime = runtime
def exists(self) -> bool:
"""Check if the sandbox runtime exists and is available."""
return self._runtime is not None
def list_files(self, *, path: str, recursive: bool) -> list[SandboxFileNode]:
script = r"""
import json

View File

@@ -20,6 +20,12 @@ class SandboxFileService:
cache_key_prefix="sandbox_files",
)
@classmethod
def exists(cls, *, tenant_id: str, sandbox_id: str) -> bool:
"""Check if the sandbox source exists and is available."""
browser = SandboxFileBrowser(tenant_id=tenant_id, sandbox_id=sandbox_id)
return browser.exists()
@classmethod
def list_files(
cls,
@@ -30,9 +36,13 @@ class SandboxFileService:
recursive: bool = False,
) -> list[SandboxFileNode]:
browser = SandboxFileBrowser(tenant_id=tenant_id, sandbox_id=sandbox_id)
if not browser.exists():
return []
return browser.list_files(path=path, recursive=recursive)
@classmethod
def download_file(cls, *, tenant_id: str, sandbox_id: str, path: str) -> SandboxFileDownloadTicket:
browser = SandboxFileBrowser(tenant_id=tenant_id, sandbox_id=sandbox_id)
if not browser.exists():
raise ValueError("Sandbox source not found")
return browser.download_file(path=path)