Skip to content

Commit

Permalink
Enhance app.py and lambda_setup.py: improve environment variable hand…
Browse files Browse the repository at this point in the history
…ling, explicitly install critical dependencies, and add verification for key imports to ensure proper Lambda functionality
  • Loading branch information
Your Name committed May 12, 2025
1 parent 6fbd794 commit 02fa8ce
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 9 deletions.
35 changes: 35 additions & 0 deletions app.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,41 @@
error by placing an entrypoint at the root level of the Lambda package.
"""

import sys
import os
import importlib.util

# Add Lambda task root directory to Python path
sys.path.insert(0, '/var/task')

# Try to read environment variables if they exist
if os.path.exists('/var/task/.env'):
with open('/var/task/.env', 'r') as env_file:
for line in env_file:
if '=' in line:
key, value = line.strip().split('=', 1)
os.environ[key] = value
if key == 'PYTHONPATH':
for path in value.split(':'):
if path and path not in sys.path:
sys.path.insert(0, path)

# Fallback check for critical dependencies
for module in ['pydantic', 'jinja2']:
try:
importlib.import_module(module)
except ImportError:
print(f"Warning: {module} not found in standard paths. Looking in /var/task...")
# Look for the module in /var/task
module_paths = [
f'/var/task/{module}',
f'/var/task/lib/python3.11/site-packages/{module}'
]
for path in module_paths:
if os.path.exists(path):
sys.path.insert(0, os.path.dirname(path))
break

from template_automation.app import lambda_handler

# Re-export the lambda_handler function for Lambda runtime to find it
Expand Down
58 changes: 49 additions & 9 deletions scripts/lambda_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
# Constants
LAMBDA_TASK_ROOT = '/var/task'
TMP_DIR = '/tmp'
PYTHON_VERSION = "3.11" # Match the Lambda container's Python version

def run_command(cmd, check=True):
"""Run a shell command and print its output"""
Expand All @@ -34,14 +35,24 @@ def copy_file(src, dest):
def install_dependencies():
"""Install Python dependencies"""
print("=== Installing dependencies from requirements.txt ===")
run_command(f"pip3 install --no-cache-dir -r {TMP_DIR}/requirements.txt -t {LAMBDA_TASK_ROOT} -v")

# Explicitly install pydantic to ensure it's available
print("=== Explicitly installing pydantic ===")
run_command(f"pip3 install --no-cache-dir pydantic -t {LAMBDA_TASK_ROOT} -v")
# Create a site-packages directory if it doesn't exist
site_packages = f"{LAMBDA_TASK_ROOT}/lib/python{PYTHON_VERSION}/site-packages"
os.makedirs(site_packages, exist_ok=True)

# Install dependencies directly to the site-packages directory
run_command(f"pip3 install --no-cache-dir -r {TMP_DIR}/requirements.txt -t {LAMBDA_TASK_ROOT}")

# Explicitly install critical dependencies
print("=== Explicitly installing critical dependencies ===")
run_command(f"pip3 install --no-cache-dir pydantic jinja2 -t {LAMBDA_TASK_ROOT}")

# Create a .pth file to ensure the Lambda runtime can find the packages
with open(f"{LAMBDA_TASK_ROOT}/lambda_path.pth", "w") as f:
f.write(f"{LAMBDA_TASK_ROOT}\n")

print("=== Installing package in development mode ===")
run_command(f"pip3 install --no-cache-dir -e {TMP_DIR} -t {LAMBDA_TASK_ROOT} -v")
run_command(f"pip3 install --no-cache-dir -e {TMP_DIR} -t {LAMBDA_TASK_ROOT}")

def verify_dependencies():
"""Verify that key dependencies are installed correctly"""
Expand All @@ -52,13 +63,18 @@ def verify_dependencies():
run_command("python3 -c 'import sys; print(sys.path)'")

# Check key dependencies
dependencies = []
dependencies = ['pydantic', 'jinja2'] # Add critical dependencies here
with open(f"{TMP_DIR}/requirements.txt") as f:
dependencies = [line.strip().split("=")[0] for line in f if line.strip() and not line.startswith("#")]
for line in f:
line = line.strip()
if line and not line.startswith("#"):
pkg = line.split("=")[0].split("<")[0].split(">")[0].split("~")[0].strip()
if pkg and pkg not in dependencies:
dependencies.append(pkg)


# Use the Lambda container's Python to verify imports
for dep in dependencies:
cmd = f"python3 -c 'import {dep}; print(f\"{dep} installed successfully\")' || echo '{dep} not installed correctly'"
cmd = f"cd {LAMBDA_TASK_ROOT} && python3 -c 'import {dep}; print(f\"{dep} installed successfully\")' || echo '{dep} not installed correctly'"
run_command(cmd, check=False)

def setup_lambda_environment():
Expand All @@ -81,6 +97,10 @@ def setup_lambda_environment():
print("=== Copying template_automation package ===")
copy_directory(f"{TMP_DIR}/template_automation", f"{LAMBDA_TASK_ROOT}/template_automation")

# Create a wrapper script that ensures the Python path is set correctly
with open(f"{LAMBDA_TASK_ROOT}/.env", "w") as f:
f.write(f"PYTHONPATH={LAMBDA_TASK_ROOT}:{LAMBDA_TASK_ROOT}/lib/python{PYTHON_VERSION}/site-packages\n")

# Verify dependencies
verify_dependencies()

Expand All @@ -92,6 +112,26 @@ def setup_lambda_environment():
print("=== Verifying Lambda task root contents ===")
run_command(f"ls -la {LAMBDA_TASK_ROOT}")
run_command(f"ls -la {LAMBDA_TASK_ROOT}/template_automation")

# Final check - try to import jinja2 and pydantic from the Lambda environment
print("=== Testing key imports from Lambda environment ===")
test_import = """
import sys
print("Python Path:", sys.path)
try:
import pydantic
print("pydantic successfully imported:", pydantic.__file__)
except ImportError as e:
print("Error importing pydantic:", str(e))
try:
import jinja2
print("jinja2 successfully imported:", jinja2.__file__)
except ImportError as e:
print("Error importing jinja2:", str(e))
"""
with open(f"{LAMBDA_TASK_ROOT}/test_imports.py", "w") as f:
f.write(test_import)
run_command(f"cd {LAMBDA_TASK_ROOT} && python3 test_imports.py")

if __name__ == "__main__":
setup_lambda_environment()
Expand Down

0 comments on commit 02fa8ce

Please sign in to comment.