"""
Sandboxed code execution for Microsoft Graph MCP.
Provides a restricted environment with only allowed imports.
"""
import sys
import json
import re
from datetime import datetime, timedelta
from typing import Any, Dict
import traceback
# Import the API module
from . import api as msgraph_api
# Allowed modules for sandboxed execution
ALLOWED_MODULES = {
"msgraph": msgraph_api,
"json": json,
"re": re,
"datetime": datetime,
"timedelta": timedelta,
}
def execute_code(code: str, timeout: int = 30) -> Dict[str, Any]:
"""
Execute Python code in a sandboxed environment.
Args:
code: Python code to execute (must set 'result' variable)
timeout: Execution timeout in seconds (not enforced in this simple impl)
Returns:
Dict with result, output, or error
"""
# Create restricted globals
sandbox_globals = {
"__builtins__": {
# Safe builtins only
"len": len,
"str": str,
"int": int,
"float": float,
"bool": bool,
"list": list,
"dict": dict,
"tuple": tuple,
"set": set,
"range": range,
"enumerate": enumerate,
"zip": zip,
"map": map,
"filter": filter,
"sorted": sorted,
"reversed": reversed,
"min": min,
"max": max,
"sum": sum,
"abs": abs,
"round": round,
"isinstance": isinstance,
"type": type,
"print": print,
"True": True,
"False": False,
"None": None,
},
# Allowed modules
"msgraph": msgraph_api,
"json": json,
"re": re,
"datetime": datetime,
"timedelta": timedelta,
}
sandbox_locals = {}
# Capture stdout
import io
from contextlib import redirect_stdout
stdout_capture = io.StringIO()
try:
with redirect_stdout(stdout_capture):
exec(code, sandbox_globals, sandbox_locals)
stdout_output = stdout_capture.getvalue()
# Get result variable if set
result = sandbox_locals.get("result", None)
response = {"success": True}
if result is not None:
# Try to serialize result
try:
if isinstance(result, (dict, list)):
response["result"] = result
else:
response["result"] = str(result)
except Exception:
response["result"] = str(result)
if stdout_output:
response["output"] = stdout_output
return response
except Exception as e:
return {
"success": False,
"error": str(e),
"traceback": traceback.format_exc()
}