Files
2026-07-13 12:24:33 +08:00

84 lines
2.7 KiB
Python

# SPDX-License-Identifier: Apache-2.0
# Standard
from typing import Any, List
import importlib
# Third Party
from fastapi import APIRouter
from starlette.requests import Request
from starlette.responses import PlainTextResponse
# First Party
from lmcache.logging import init_logger
logger = init_logger(__name__)
router = APIRouter()
def _get_allowed_imports(request: Request) -> List[str]:
"""Extract script_allowed_imports from either inProcess or mp mode."""
adapter = getattr(request.app.state, "lmcache_adapter", None)
if adapter is not None:
return getattr(adapter.config, "script_allowed_imports", None) or []
configs = getattr(request.app.state, "configs", None)
if isinstance(configs, dict):
mp_cfg = configs.get("mp")
return getattr(mp_cfg, "script_allowed_imports", None) or []
return []
@router.post("/run_script")
async def run_script(request: Request):
form_data = await request.form()
script_file = form_data.get("script")
if not script_file or not hasattr(script_file, "file"):
return PlainTextResponse("No script file provided", status_code=400)
script_content = await script_file.read()
try:
allowed_imports = _get_allowed_imports(request)
# Pre-import allowed modules
allowed_modules = {}
for module_name in allowed_imports:
try:
module = importlib.import_module(module_name)
allowed_modules[module_name] = module
logger.info("Imported allowed module: %s", module_name)
except ImportError as e:
logger.warning("Failed to import module %s: %s", module_name, e)
# Create custom __import__ function that only allows configured modules
def restricted_import(name, globals=None, locals=None, fromlist=(), level=0):
if name in allowed_modules:
return allowed_modules[name]
raise ImportError(f"Import of '{name}' is not allowed")
restricted_globals = {
"__builtins__": {
"print": print,
"str": str,
"int": int,
"float": float,
"list": list,
"dict": dict,
"tuple": tuple,
"set": set,
"__import__": restricted_import,
},
"app": request.app,
}
restricted_locals: dict[str, Any] = {}
exec(script_content, restricted_globals, restricted_locals)
result = restricted_locals.get("result", "Script executed successfully")
return PlainTextResponse(str(result), media_type="text/plain")
except Exception as e:
return PlainTextResponse(f"Error executing script: {str(e)}", status_code=500)