#!/bin/bash # Install Python 3.12 on Amazon Linux (without sudo) # This script attempts to install Python 3.12 in user space set -e echo "🐍 Installing Python 3.12 for AWS Lambda Layers..." # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # No Color print_status() { echo -e "${GREEN}[INFO]${NC} $1" } print_warning() { echo -e "${YELLOW}[WARNING]${NC} $1" } print_error() { echo -e "${RED}[ERROR]${NC} $1" } # Check if we already have Python 3.12 if command -v python3.12 &> /dev/null; then print_status "Python 3.12 is already available: $(python3.12 --version)" exit 0 fi # Try to install Python 3.12 using package manager first print_status "Attempting to install Python 3.12 using package manager..." # For Amazon Linux 2023 if [ -f /etc/os-release ]; then source /etc/os-release if [[ "$NAME" == *"Amazon Linux"* ]]; then print_status "Detected Amazon Linux" # Try with dnf (Amazon Linux 2023) if command -v dnf &> /dev/null; then print_status "Using dnf to install Python 3.12..." dnf install -y python3.12 python3.12-pip python3.12-devel || { print_warning "Failed to install Python 3.12 via dnf" } # Try with yum (Amazon Linux 2) elif command -v yum &> /dev/null; then print_status "Using yum to install Python 3.12..." yum install -y python3.12 python3.12-pip python3.12-devel || { print_warning "Failed to install Python 3.12 via yum" } fi fi fi # Check if installation was successful if command -v python3.12 &> /dev/null; then print_status "✅ Python 3.12 installed successfully: $(python3.12 --version)" # Create symlinks if they don't exist if [ ! -f /usr/bin/python3.12 ]; then which python3.12 > /dev/null && ln -sf $(which python3.12) /usr/local/bin/python3.12 || true fi # Set alternatives if command -v alternatives &> /dev/null; then alternatives --install /usr/bin/python3 python3 /usr/bin/python3.12 1 || true alternatives --install /usr/bin/pip3 pip3 /usr/bin/pip3.12 1 || true fi exit 0 fi # If package manager installation failed, try building from source print_warning "Package manager installation failed. Attempting to build from source..." # Create a local installation directory PYTHON_HOME="$HOME/.local/python3.12" mkdir -p $PYTHON_HOME # Download Python 3.12 source PYTHON_VERSION="3.12.2" PYTHON_URL="https://www.python.org/ftp/python/${PYTHON_VERSION}/Python-${PYTHON_VERSION}.tgz" print_status "Downloading Python ${PYTHON_VERSION}..." cd /tmp wget $PYTHON_URL tar -xzf Python-${PYTHON_VERSION}.tgz cd Python-${PYTHON_VERSION} # Configure and build print_status "Configuring Python build..." ./configure --prefix=$PYTHON_HOME \ --enable-optimizations \ --enable-shared \ --with-ensurepip=install print_status "Building Python (this may take a while)..." make -j$(nproc) print_status "Installing Python to ${PYTHON_HOME}..." make install # Create symlinks ln -sf $PYTHON_HOME/bin/python3.12 $HOME/.local/bin/python3.12 ln -sf $PYTHON_HOME/bin/pip3.12 $HOME/.local/bin/pip3.12 # Add to PATH echo "export PATH=$HOME/.local/bin:$PATH" >> $HOME/.bashrc export PATH=$HOME/.local/bin:$PATH # Verify installation if command -v python3.12 &> /dev/null; then print_status "✅ Python 3.12 built and installed successfully!" print_status "Version: $(python3.12 --version)" print_status "Location: $(which python3.12)" else print_error "❌ Failed to install Python 3.12" exit 1 fi # Clean up cd $HOME rm -rf /tmp/Python-${PYTHON_VERSION}* print_status "🎉 Python 3.12 is ready to use!" print_status "Run 'source ~/.bashrc' or restart your shell to update PATH"