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
|
||||
|
||||
# System Configuration
|
||||
APP_ENV_TYPE = dev
|
||||
APP_ENV_TYPE = prod
|
||||
APP_ENV_LABEL = Production Instance
|
||||
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
|
||||
|
||||
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.
|
||||
Integrated executor functionality with enhanced result extraction.
|
||||
Original implementation with venv creation for non-Azure environments.
|
||||
|
||||
Args:
|
||||
code: Python code to execute
|
||||
|
|
@ -788,6 +960,32 @@ Return ONLY Python code without explanations or markdown.
|
|||
# Clean up resources
|
||||
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):
|
||||
"""Clean up temporary resources from code execution."""
|
||||
if self.tempDir and os.path.exists(self.tempDir):
|
||||
|
|
|
|||
Loading…
Reference in a new issue