mirror of
https://github.com/OpenHands/OpenHands.git
synced 2025-12-25 21:36:52 +08:00
Co-authored-by: openhands <openhands@all-hands.dev> Co-authored-by: sp.wack <83104063+amanape@users.noreply.github.com> Co-authored-by: Engel Nyst <enyst@users.noreply.github.com>
92 lines
2.8 KiB
Python
92 lines
2.8 KiB
Python
"""Runtime Containers router for OpenHands Server."""
|
|
|
|
from typing import Annotated
|
|
|
|
from fastapi import APIRouter, HTTPException, Query, status
|
|
|
|
from openhands.agent_server.models import Success
|
|
from openhands.app_server.config import depends_sandbox_service
|
|
from openhands.app_server.sandbox.sandbox_models import SandboxInfo, SandboxPage
|
|
from openhands.app_server.sandbox.sandbox_service import (
|
|
SandboxService,
|
|
)
|
|
|
|
router = APIRouter(prefix='/sandboxes', tags=['Sandbox'])
|
|
sandbox_service_dependency = depends_sandbox_service()
|
|
|
|
# Read methods
|
|
|
|
|
|
@router.get('/search')
|
|
async def search_sandboxes(
|
|
page_id: Annotated[
|
|
str | None,
|
|
Query(title='Optional next_page_id from the previously returned page'),
|
|
] = None,
|
|
limit: Annotated[
|
|
int,
|
|
Query(title='The max number of results in the page', gt=0, lte=100),
|
|
] = 100,
|
|
sandbox_service: SandboxService = sandbox_service_dependency,
|
|
) -> SandboxPage:
|
|
"""Search / list sandboxes owned by the current user."""
|
|
assert limit > 0
|
|
assert limit <= 100
|
|
return await sandbox_service.search_sandboxes(page_id=page_id, limit=limit)
|
|
|
|
|
|
@router.get('')
|
|
async def batch_get_sandboxes(
|
|
id: Annotated[list[str], Query()],
|
|
sandbox_service: SandboxService = sandbox_service_dependency,
|
|
) -> list[SandboxInfo | None]:
|
|
"""Get a batch of sandboxes given their ids, returning null for any missing."""
|
|
assert len(id) < 100
|
|
sandboxes = await sandbox_service.batch_get_sandboxes(id)
|
|
return sandboxes
|
|
|
|
|
|
# Write Methods
|
|
|
|
|
|
@router.post('')
|
|
async def start_sandbox(
|
|
sandbox_spec_id: str | None = None,
|
|
sandbox_service: SandboxService = sandbox_service_dependency,
|
|
) -> SandboxInfo:
|
|
info = await sandbox_service.start_sandbox(sandbox_spec_id)
|
|
return info
|
|
|
|
|
|
@router.post('/{id}/pause', responses={404: {'description': 'Item not found'}})
|
|
async def pause_sandbox(
|
|
sandbox_id: str,
|
|
sandbox_service: SandboxService = sandbox_service_dependency,
|
|
) -> Success:
|
|
exists = await sandbox_service.pause_sandbox(sandbox_id)
|
|
if not exists:
|
|
raise HTTPException(status.HTTP_404_NOT_FOUND)
|
|
return Success()
|
|
|
|
|
|
@router.post('/{id}/resume', responses={404: {'description': 'Item not found'}})
|
|
async def resume_sandbox(
|
|
sandbox_id: str,
|
|
sandbox_service: SandboxService = sandbox_service_dependency,
|
|
) -> Success:
|
|
exists = await sandbox_service.resume_sandbox(sandbox_id)
|
|
if not exists:
|
|
raise HTTPException(status.HTTP_404_NOT_FOUND)
|
|
return Success()
|
|
|
|
|
|
@router.delete('/{id}', responses={404: {'description': 'Item not found'}})
|
|
async def delete_sandbox(
|
|
sandbox_id: str,
|
|
sandbox_service: SandboxService = sandbox_service_dependency,
|
|
) -> Success:
|
|
exists = await sandbox_service.delete_sandbox(sandbox_id)
|
|
if not exists:
|
|
raise HTTPException(status.HTTP_404_NOT_FOUND)
|
|
return Success()
|