prod azure 1.0.10
This commit is contained in:
parent
682bab26bc
commit
443387f394
2 changed files with 201 additions and 3 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
# Production Environment Configuration
|
# Production Environment Configuration
|
||||||
|
|
||||||
# System Configuration
|
# System Configuration
|
||||||
APP_ENV_TYPE = dev
|
APP_ENV_TYPE = prod
|
||||||
APP_ENV_LABEL = Production Instance
|
APP_ENV_LABEL = Production Instance
|
||||||
APP_CALL=uvicorn app:app --host 0.0.0.0 --port 8000
|
APP_CALL=uvicorn app:app --host 0.0.0.0 --port 8000
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -591,10 +591,182 @@ Return ONLY Python code without explanations or markdown.
|
||||||
|
|
||||||
return code, requirements
|
return code, requirements
|
||||||
|
|
||||||
def _executeCode(self, code: str, requirements: List[str] = None) -> Dict[str, Any]:
|
def _executeCodeProd(self, code: str, requirements: List[str] = None) -> Dict[str, Any]:
|
||||||
|
"""
|
||||||
|
Execute Python code in Azure environment using the antenv interpreter.
|
||||||
|
Optimized for production use in Azure Web App environment where venv creation fails.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
code: Python code to execute
|
||||||
|
requirements: List of required packages
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Execution result dictionary
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
# 1. Create temp directory for code files
|
||||||
|
self.tempDir = tempfile.mkdtemp(prefix="code_exec_")
|
||||||
|
|
||||||
|
# Try different possible paths to find the antenv Python interpreter
|
||||||
|
possible_python_paths = [
|
||||||
|
"/home/site/wwwroot/antenv/bin/python",
|
||||||
|
"/antenv/bin/python",
|
||||||
|
"/tmp/8dd8c226509f116/antenv/bin/python", # Path from your error logs
|
||||||
|
sys.executable # Fallback to system Python
|
||||||
|
]
|
||||||
|
|
||||||
|
pythonExe = None
|
||||||
|
for path in possible_python_paths:
|
||||||
|
if os.path.exists(path):
|
||||||
|
pythonExe = path
|
||||||
|
logger.info(f"Found Python interpreter at: {pythonExe}")
|
||||||
|
break
|
||||||
|
|
||||||
|
if not pythonExe:
|
||||||
|
logger.error("Could not find a valid Python interpreter in Azure environment")
|
||||||
|
return {
|
||||||
|
"success": False,
|
||||||
|
"output": "",
|
||||||
|
"error": "Could not find a valid Python interpreter in Azure environment",
|
||||||
|
"result": None,
|
||||||
|
"exitCode": -1
|
||||||
|
}
|
||||||
|
|
||||||
|
# 2. Install requirements to a temporary user directory if provided
|
||||||
|
if requirements:
|
||||||
|
logger.info(f"Installing requirements in Azure environment: {requirements}")
|
||||||
|
|
||||||
|
# Create requirements.txt
|
||||||
|
reqFile = os.path.join(self.tempDir, "requirements.txt")
|
||||||
|
with open(reqFile, "w") as f:
|
||||||
|
f.write("\n".join(requirements))
|
||||||
|
|
||||||
|
# Set up a custom PYTHONUSERBASE to isolate package installations
|
||||||
|
custom_user_base = os.path.join(self.tempDir, "pip_packages")
|
||||||
|
os.makedirs(custom_user_base, exist_ok=True)
|
||||||
|
|
||||||
|
env = os.environ.copy()
|
||||||
|
env["PYTHONUSERBASE"] = custom_user_base
|
||||||
|
|
||||||
|
# Install requirements to the custom user directory
|
||||||
|
try:
|
||||||
|
pipResult = subprocess.run(
|
||||||
|
[pythonExe, "-m", "pip", "install", "--user", "-r", reqFile],
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
env=env,
|
||||||
|
timeout=int(APP_CONFIG.get("Agent_Coder_INSTALL_TIMEOUT"))
|
||||||
|
)
|
||||||
|
|
||||||
|
if pipResult.returncode != 0:
|
||||||
|
logger.warning(f"Error installing requirements in Azure: {pipResult.stderr}")
|
||||||
|
else:
|
||||||
|
logger.info(f"Requirements installed successfully to {custom_user_base}")
|
||||||
|
|
||||||
|
# Try to find the site-packages directory
|
||||||
|
import glob
|
||||||
|
site_packages = os.path.join(custom_user_base, "lib", "python*", "site-packages")
|
||||||
|
site_packages_paths = glob.glob(site_packages)
|
||||||
|
|
||||||
|
if site_packages_paths:
|
||||||
|
env["PYTHONPATH"] = os.pathsep.join([site_packages_paths[0], env.get("PYTHONPATH", "")])
|
||||||
|
logger.info(f"Added {site_packages_paths[0]} to PYTHONPATH")
|
||||||
|
else:
|
||||||
|
# Alternative paths for different Python versions
|
||||||
|
alt_site_packages = os.path.join(custom_user_base, "site-packages")
|
||||||
|
if os.path.exists(alt_site_packages):
|
||||||
|
env["PYTHONPATH"] = os.pathsep.join([alt_site_packages, env.get("PYTHONPATH", "")])
|
||||||
|
logger.info(f"Added {alt_site_packages} to PYTHONPATH")
|
||||||
|
except Exception as e:
|
||||||
|
logger.warning(f"Exception during requirements installation in Azure: {str(e)}")
|
||||||
|
else:
|
||||||
|
env = os.environ.copy()
|
||||||
|
|
||||||
|
# 3. Write code to file
|
||||||
|
codeFile = os.path.join(self.tempDir, "code.py")
|
||||||
|
with open(codeFile, "w", encoding="utf-8") as f:
|
||||||
|
f.write(code)
|
||||||
|
|
||||||
|
# 4. Execute code with the modified environment
|
||||||
|
logger.debug(f"Executing code in Azure environment with timeout of {self.executorTimeout} seconds")
|
||||||
|
process = subprocess.run(
|
||||||
|
[pythonExe, codeFile],
|
||||||
|
timeout=self.executorTimeout,
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
env=env
|
||||||
|
)
|
||||||
|
|
||||||
|
# 5. Process results
|
||||||
|
stdout = process.stdout
|
||||||
|
stderr = process.stderr
|
||||||
|
|
||||||
|
# Try to extract result from stdout
|
||||||
|
resultData = None
|
||||||
|
if process.returncode == 0:
|
||||||
|
try:
|
||||||
|
# Find the last line that might be JSON
|
||||||
|
jsonLines = []
|
||||||
|
for line in stdout.strip().split('\n'):
|
||||||
|
line = line.strip()
|
||||||
|
if line and line[0] in '{[' and line[-1] in '}]':
|
||||||
|
try:
|
||||||
|
parsed = json.loads(line)
|
||||||
|
jsonLines.append((line, parsed))
|
||||||
|
except json.JSONDecodeError:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Use the last valid JSON that appears to be a dictionary
|
||||||
|
if jsonLines:
|
||||||
|
for line, parsed in reversed(jsonLines):
|
||||||
|
if isinstance(parsed, dict):
|
||||||
|
resultData = parsed
|
||||||
|
logger.debug(f"Extracted result data from stdout: {type(resultData)}")
|
||||||
|
break
|
||||||
|
except Exception as e:
|
||||||
|
logger.debug(f"Error extracting result from stdout: {str(e)}")
|
||||||
|
|
||||||
|
# Enhanced logging of what was found
|
||||||
|
if resultData:
|
||||||
|
logger.info(f"Found result dictionary with {len(resultData)} entries: {list(resultData.keys())}")
|
||||||
|
else:
|
||||||
|
logger.warning("No result dictionary found in output")
|
||||||
|
|
||||||
|
# Create result dictionary
|
||||||
|
return {
|
||||||
|
"success": process.returncode == 0,
|
||||||
|
"output": stdout,
|
||||||
|
"error": stderr if process.returncode != 0 else "",
|
||||||
|
"result": resultData,
|
||||||
|
"exitCode": process.returncode
|
||||||
|
}
|
||||||
|
|
||||||
|
except subprocess.TimeoutExpired:
|
||||||
|
logger.error(f"Execution in Azure timed out after {self.executorTimeout} seconds")
|
||||||
|
return {
|
||||||
|
"success": False,
|
||||||
|
"output": "",
|
||||||
|
"error": f"Execution timed out after {self.executorTimeout} seconds",
|
||||||
|
"result": None,
|
||||||
|
"exitCode": -1
|
||||||
|
}
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Execution error in Azure environment: {str(e)}")
|
||||||
|
return {
|
||||||
|
"success": False,
|
||||||
|
"output": "",
|
||||||
|
"error": f"Execution error in Azure environment: {str(e)}",
|
||||||
|
"result": None,
|
||||||
|
"exitCode": -1
|
||||||
|
}
|
||||||
|
finally:
|
||||||
|
# Clean up resources
|
||||||
|
self._cleanupExecution()
|
||||||
|
|
||||||
|
def _executeCodeVenv(self, code: str, requirements: List[str] = None) -> Dict[str, Any]:
|
||||||
"""
|
"""
|
||||||
Execute Python code in a virtual environment.
|
Execute Python code in a virtual environment.
|
||||||
Integrated executor functionality with enhanced result extraction.
|
Original implementation with venv creation for non-Azure environments.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
code: Python code to execute
|
code: Python code to execute
|
||||||
|
|
@ -788,6 +960,32 @@ Return ONLY Python code without explanations or markdown.
|
||||||
# Clean up resources
|
# Clean up resources
|
||||||
self._cleanupExecution()
|
self._cleanupExecution()
|
||||||
|
|
||||||
|
def _executeCode(self, code: str, requirements: List[str] = None) -> Dict[str, Any]:
|
||||||
|
"""
|
||||||
|
Execute Python code in the appropriate environment based on configuration.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
code: Python code to execute
|
||||||
|
requirements: List of required packages
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Execution result dictionary
|
||||||
|
"""
|
||||||
|
# Check if we're in a production Azure environment
|
||||||
|
env_type = APP_CONFIG.get("APP_ENV_TYPE", "dev").lower()
|
||||||
|
|
||||||
|
logger.info(f"Executing code in environment type: {env_type}")
|
||||||
|
|
||||||
|
if env_type == "prod":
|
||||||
|
# Use the Azure-optimized execution method
|
||||||
|
logger.info("Using Azure-optimized code execution method")
|
||||||
|
return self._executeCodeProd(code, requirements)
|
||||||
|
else:
|
||||||
|
# Use the standard virtual environment execution method
|
||||||
|
logger.info("Using standard virtual environment execution method")
|
||||||
|
return self._executeCodeVenv(code, requirements)
|
||||||
|
|
||||||
|
|
||||||
def _cleanupExecution(self):
|
def _cleanupExecution(self):
|
||||||
"""Clean up temporary resources from code execution."""
|
"""Clean up temporary resources from code execution."""
|
||||||
if self.tempDir and os.path.exists(self.tempDir):
|
if self.tempDir and os.path.exists(self.tempDir):
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue