Spaces:
Running
Running
| from __future__ import annotations | |
| import time | |
| from typing import Optional | |
| from fastapi import APIRouter, Depends | |
| from app.api.deps import require_auth | |
| from app.core.logger import get_logger | |
| from app.models.schemas import ( | |
| CodeExecutionItemResult, | |
| CodeExecutionRequest, | |
| CodeExecutionResponse, | |
| ) | |
| from app.services.code_executor_service import CodeExecutorService | |
| router = APIRouter() | |
| _logger = get_logger(__name__) | |
| _executor: Optional[CodeExecutorService] = None | |
| def get_executor() -> CodeExecutorService: | |
| global _executor | |
| if _executor is None: | |
| _executor = CodeExecutorService() | |
| return _executor | |
| async def execute_code( | |
| body: CodeExecutionRequest, | |
| token: str = Depends(require_auth), | |
| executor: CodeExecutorService = Depends(get_executor), | |
| ) -> CodeExecutionResponse: | |
| _logger.info("Code execution request: items=%s", len(body.items)) | |
| start = time.perf_counter() | |
| results: list[CodeExecutionItemResult] = [] | |
| for item in body.items: | |
| t0 = time.perf_counter() | |
| try: | |
| result = await executor.execute(item.code, item.language) | |
| elapsed = (time.perf_counter() - t0) * 1000 | |
| results.append(CodeExecutionItemResult( | |
| success=result["success"], | |
| output=result.get("output", ""), | |
| error=result.get("error"), | |
| exit_code=result.get("exit_code"), | |
| execution_time_ms=round(elapsed, 2), | |
| language=result.get("language", item.language), | |
| timed_out=result.get("timed_out", False), | |
| )) | |
| except Exception as exc: | |
| elapsed = (time.perf_counter() - t0) * 1000 | |
| _logger.exception("Item execution error") | |
| results.append(CodeExecutionItemResult( | |
| success=False, | |
| error=str(exc), | |
| execution_time_ms=round(elapsed, 2), | |
| language=item.language, | |
| )) | |
| total_ms = (time.perf_counter() - start) * 1000 | |
| success_count = sum(1 for r in results if r.success) | |
| failed_count = len(results) - success_count | |
| all_ok = failed_count == 0 | |
| _logger.info( | |
| "Code execution done: items=%s, success=%s, failed=%s, total_ms=%s", | |
| len(results), success_count, failed_count, round(total_ms, 3), | |
| ) | |
| return CodeExecutionResponse( | |
| success=all_ok, | |
| time_ms=round(total_ms, 3), | |
| success_count=success_count, | |
| failed_count=failed_count, | |
| results=results, | |
| ) | |