Merge remote-tracking branch 'origin/main'

This commit is contained in:
Fahad
2025-06-21 09:15:27 +04:00

View File

@@ -213,10 +213,183 @@ find_python() {
return 1
}
# Detect Linux distribution
detect_linux_distro() {
if [[ -f /etc/os-release ]]; then
. /etc/os-release
echo "${ID:-unknown}"
elif [[ -f /etc/debian_version ]]; then
echo "debian"
elif [[ -f /etc/redhat-release ]]; then
echo "rhel"
elif [[ -f /etc/arch-release ]]; then
echo "arch"
else
echo "unknown"
fi
}
# Get package manager and install command for the distro
get_install_command() {
local distro="$1"
local python_version="${2:-}"
# Extract major.minor version if provided
local version_suffix=""
if [[ -n "$python_version" ]] && [[ "$python_version" =~ ([0-9]+\.[0-9]+) ]]; then
version_suffix="${BASH_REMATCH[1]}"
fi
case "$distro" in
ubuntu|debian|raspbian|pop|linuxmint|elementary)
if [[ -n "$version_suffix" ]]; then
# Try version-specific packages first, then fall back to generic
echo "sudo apt update && (sudo apt install -y python${version_suffix}-venv python${version_suffix}-dev || sudo apt install -y python3-venv python3-pip)"
else
echo "sudo apt update && sudo apt install -y python3-venv python3-pip"
fi
;;
fedora)
echo "sudo dnf install -y python3-venv python3-pip"
;;
rhel|centos|rocky|almalinux|oracle)
echo "sudo dnf install -y python3-venv python3-pip || sudo yum install -y python3-venv python3-pip"
;;
arch|manjaro|endeavouros)
echo "sudo pacman -Syu --noconfirm python-pip python-virtualenv"
;;
opensuse|suse)
echo "sudo zypper install -y python3-venv python3-pip"
;;
alpine)
echo "sudo apk add --no-cache python3-dev py3-pip py3-virtualenv"
;;
*)
echo ""
;;
esac
}
# Check if we can use sudo
can_use_sudo() {
# Check if sudo exists and user can use it
if command -v sudo &> /dev/null; then
# Test sudo with a harmless command
if sudo -n true 2>/dev/null; then
return 0
elif [[ -t 0 ]]; then
# Terminal is interactive, test if sudo works with password
if sudo true 2>/dev/null; then
return 0
fi
fi
fi
return 1
}
# Try to install system packages automatically
try_install_system_packages() {
local python_cmd="${1:-python3}"
local os_type=$(detect_os)
# Skip on macOS as it works fine
if [[ "$os_type" == "macos" ]]; then
return 1
fi
# Only try on Linux systems
if [[ "$os_type" != "linux" && "$os_type" != "wsl" ]]; then
return 1
fi
# Get Python version
local python_version=""
if command -v "$python_cmd" &> /dev/null; then
python_version=$($python_cmd --version 2>&1 | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' || echo "")
fi
local distro=$(detect_linux_distro)
local install_cmd=$(get_install_command "$distro" "$python_version")
if [[ -z "$install_cmd" ]]; then
return 1
fi
print_info "Attempting to install required Python packages..."
# Check if we can use sudo
if can_use_sudo; then
print_info "Installing system packages (this may ask for your password)..."
if eval "$install_cmd" >/dev/null 2>&1; then
print_success "System packages installed successfully"
return 0
else
print_warning "Failed to install system packages automatically"
fi
fi
return 1
}
# Bootstrap pip in virtual environment
bootstrap_pip() {
local venv_python="$1"
local python_cmd="$2"
print_info "Bootstrapping pip in virtual environment..."
# Try ensurepip first
if $venv_python -m ensurepip --default-pip 2>/dev/null; then
print_success "Successfully bootstrapped pip using ensurepip"
return 0
fi
# Try to download get-pip.py
print_info "Downloading pip installer..."
local get_pip_url="https://bootstrap.pypa.io/get-pip.py"
local temp_pip=$(mktemp)
local download_success=false
# Try curl first
if command -v curl &> /dev/null; then
if curl -sSL "$get_pip_url" -o "$temp_pip" 2>/dev/null; then
download_success=true
fi
fi
# Try wget if curl failed
if [[ "$download_success" == false ]] && command -v wget &> /dev/null; then
if wget -qO "$temp_pip" "$get_pip_url" 2>/dev/null; then
download_success=true
fi
fi
# Try python urllib as last resort
if [[ "$download_success" == false ]]; then
print_info "Using Python to download pip installer..."
if $python_cmd -c "import urllib.request; urllib.request.urlretrieve('$get_pip_url', '$temp_pip')" 2>/dev/null; then
download_success=true
fi
fi
if [[ "$download_success" == true ]] && [[ -f "$temp_pip" ]] && [[ -s "$temp_pip" ]]; then
print_info "Installing pip..."
if $venv_python "$temp_pip" --no-warn-script-location >/dev/null 2>&1; then
rm -f "$temp_pip"
print_success "Successfully installed pip"
return 0
fi
fi
rm -f "$temp_pip" 2>/dev/null
return 1
}
# Setup virtual environment
setup_venv() {
local python_cmd="$1"
local venv_python=""
local venv_pip=""
# Create venv if it doesn't exist
if [[ ! -d "$VENV_PATH" ]]; then
@@ -227,68 +400,92 @@ setup_venv() {
if venv_error=$($python_cmd -m venv "$VENV_PATH" 2>&1); then
print_success "Created isolated environment"
else
print_error "Failed to create virtual environment"
echo ""
echo "Error details:"
echo "$venv_error"
echo ""
# Check for common Linux issues and try fallbacks
local os_type=$(detect_os)
if [[ "$os_type" == "linux" || "$os_type" == "wsl" ]]; then
if echo "$venv_error" | grep -E -q "No module named venv|venv.*not found"; then
print_warning "Python venv module not available, trying fallback methods..."
# Try virtualenv as fallback
if command -v virtualenv &> /dev/null; then
print_info "Attempting to create environment with virtualenv..."
local fallback_error
if fallback_error=$(virtualenv -p "$python_cmd" "$VENV_PATH" 2>&1); then
print_success "Created environment using virtualenv fallback"
# Continue to path setup below instead of early return
if echo "$venv_error" | grep -E -q "No module named venv|venv.*not found|ensurepip is not|python3.*-venv"; then
# Try to install system packages automatically first
if try_install_system_packages "$python_cmd"; then
print_info "Retrying virtual environment creation..."
if venv_error=$($python_cmd -m venv "$VENV_PATH" 2>&1); then
print_success "Created isolated environment"
else
echo "virtualenv fallback failed: $fallback_error"
# Continue to fallback methods below
print_warning "Still unable to create venv, trying fallback methods..."
fi
fi
# Try python -m virtualenv if directory wasn't created
# If venv still doesn't exist, try fallback methods
if [[ ! -d "$VENV_PATH" ]]; then
local fallback_error
if fallback_error=$($python_cmd -m virtualenv "$VENV_PATH" 2>&1); then
print_success "Created environment using python -m virtualenv fallback"
# Continue to path setup below instead of early return
else
echo "python -m virtualenv fallback failed: $fallback_error"
# Try virtualenv as fallback
if command -v virtualenv &> /dev/null; then
print_info "Attempting to create environment with virtualenv..."
if virtualenv -p "$python_cmd" "$VENV_PATH" &>/dev/null 2>&1; then
print_success "Created environment using virtualenv fallback"
fi
fi
# Try python -m virtualenv if directory wasn't created
if [[ ! -d "$VENV_PATH" ]]; then
if $python_cmd -m virtualenv "$VENV_PATH" &>/dev/null 2>&1; then
print_success "Created environment using python -m virtualenv fallback"
fi
fi
# Last resort: try to install virtualenv via pip and use it
if [[ ! -d "$VENV_PATH" ]] && command -v pip3 &> /dev/null; then
print_info "Installing virtualenv via pip..."
if pip3 install --user virtualenv &>/dev/null 2>&1; then
local user_bin="$HOME/.local/bin"
if [[ -f "$user_bin/virtualenv" ]]; then
if "$user_bin/virtualenv" -p "$python_cmd" "$VENV_PATH" &>/dev/null 2>&1; then
print_success "Created environment using pip-installed virtualenv"
fi
fi
fi
fi
fi
# Check if any fallback succeeded
# Check if any method succeeded
if [[ ! -d "$VENV_PATH" ]]; then
print_error "All virtual environment creation methods failed!"
print_error "Unable to create virtual environment"
echo ""
echo "Please install the venv or virtualenv package:"
echo " Ubuntu/Debian: sudo apt install python3-venv python3-virtualenv"
echo " RHEL/CentOS: sudo dnf install python3-venv python3-virtualenv"
echo " Fedora: sudo dnf install python3-venv python3-virtualenv"
echo " Arch: sudo pacman -S python-virtualenv"
echo "Your system is missing Python development packages."
echo ""
echo "Or install via pip:"
echo " $python_cmd -m pip install --user virtualenv"
local distro=$(detect_linux_distro)
local python_version=$($python_cmd --version 2>&1 | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' || echo "")
local install_cmd=$(get_install_command "$distro" "$python_version")
if [[ -n "$install_cmd" ]]; then
echo "Please run this command to install them:"
echo " $install_cmd"
else
echo "Please install Python venv support for your system:"
echo " Ubuntu/Debian: sudo apt install python3-venv python3-pip"
echo " RHEL/CentOS: sudo dnf install python3-venv python3-pip"
echo " Arch: sudo pacman -S python-pip python-virtualenv"
fi
echo ""
echo "Then run this script again."
exit 1
fi
elif echo "$venv_error" | grep -q "Permission denied"; then
print_error "Permission denied creating virtual environment"
echo ""
echo "Try running with different permissions or in a different directory:"
echo " mkdir -p ~/zen-mcp-temp && cd ~/zen-mcp-temp"
echo " git clone <repository-url> && cd zen-mcp-server && ./run-server.sh"
echo "Try running in a different directory:"
echo " cd ~ && git clone <repository-url> && cd zen-mcp-server && ./run-server.sh"
echo ""
exit 1
else
print_error "Failed to create virtual environment"
echo "Error: $venv_error"
exit 1
fi
else
# For non-Linux systems, show the error and exit
print_error "Failed to create virtual environment"
echo "Error: $venv_error"
exit 1
fi
fi
@@ -299,25 +496,89 @@ setup_venv() {
case "$os_type" in
windows)
venv_python="$VENV_PATH/Scripts/python.exe"
venv_pip="$VENV_PATH/Scripts/pip.exe"
;;
*)
venv_python="$VENV_PATH/bin/python"
venv_pip="$VENV_PATH/bin/pip"
;;
esac
# Always use venv Python
if [[ -f "$venv_python" ]]; then
if [[ -n "${VIRTUAL_ENV:-}" ]]; then
print_success "Using activated virtual environment"
fi
# Convert to absolute path for MCP registration
local abs_venv_python=$(cd "$(dirname "$venv_python")" && pwd)/$(basename "$venv_python")
echo "$abs_venv_python"
return 0
else
# Check if venv Python exists
if [[ ! -f "$venv_python" ]]; then
print_error "Virtual environment Python not found"
exit 1
fi
# Check if pip exists in the virtual environment
if [[ ! -f "$venv_pip" ]] && ! $venv_python -m pip --version &>/dev/null 2>&1; then
# On Linux, try to install system packages if pip is missing
local os_type=$(detect_os)
if [[ "$os_type" == "linux" || "$os_type" == "wsl" ]]; then
if try_install_system_packages "$python_cmd"; then
# Check if pip is now available after system package install
if $venv_python -m pip --version &>/dev/null 2>&1; then
print_success "pip is now available"
else
# Still need to bootstrap pip
bootstrap_pip "$venv_python" "$python_cmd" || true
fi
else
# Try to bootstrap pip without system packages
bootstrap_pip "$venv_python" "$python_cmd" || true
fi
else
# For non-Linux systems, just try to bootstrap pip
bootstrap_pip "$venv_python" "$python_cmd" || true
fi
# Final check after all attempts
if ! $venv_python -m pip --version &>/dev/null 2>&1; then
print_error "Failed to install pip in virtual environment"
echo ""
echo "Your Python installation appears to be incomplete."
echo ""
local distro=$(detect_linux_distro)
local python_version=$($python_cmd --version 2>&1 | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' || echo "")
local install_cmd=$(get_install_command "$distro" "$python_version")
if [[ -n "$install_cmd" ]]; then
echo "Please run this command to install Python packages:"
echo " $install_cmd"
else
echo "Please install Python pip support for your system."
fi
echo ""
echo "Then delete the virtual environment and run this script again:"
echo " rm -rf $VENV_PATH"
echo " ./run-server.sh"
echo ""
exit 1
fi
fi
# Verify pip is working
if ! $venv_python -m pip --version &>/dev/null 2>&1; then
print_error "pip is not working correctly in the virtual environment"
echo ""
echo "Try deleting the virtual environment and running again:"
echo " rm -rf $VENV_PATH"
echo " ./run-server.sh"
echo ""
exit 1
fi
if [[ -n "${VIRTUAL_ENV:-}" ]]; then
print_success "Using activated virtual environment with pip"
else
print_success "Virtual environment ready with pip"
fi
# Convert to absolute path for MCP registration
local abs_venv_python=$(cd "$(dirname "$venv_python")" && pwd)/$(basename "$venv_python")
echo "$abs_venv_python"
return 0
}
# Check if package is installed
@@ -332,8 +593,17 @@ install_dependencies() {
local python_cmd="$1"
local deps_needed=false
# First verify pip is available
if ! $python_cmd -m pip --version &>/dev/null 2>&1; then
print_error "pip is not available in the Python environment"
echo ""
echo "This indicates an incomplete Python installation."
echo "Please see the instructions above for installing the required packages."
return 1
fi
# Check required packages
local packages=("mcp" "google.generativeai" "openai" "pydantic")
local packages=("mcp" "google.generativeai" "openai" "pydantic" "dotenv")
for package in "${packages[@]}"; do
local import_name=${package%%.*} # Get first part before dot
if ! check_package "$python_cmd" "$import_name"; then
@@ -353,6 +623,7 @@ install_dependencies() {
echo " • MCP protocol library"
echo " • AI model connectors"
echo " • Data validation tools"
echo " • Environment configuration"
echo ""
# Determine if we're in a venv
@@ -363,16 +634,69 @@ install_dependencies() {
install_cmd="$python_cmd -m pip install -q --user -r requirements.txt"
fi
# Install packages
# Install packages with better error handling
echo -n "Downloading packages..."
if $install_cmd 2>&1 | grep -i error | grep -v warning; then
local install_output
local install_error
# Capture both stdout and stderr
install_output=$($install_cmd 2>&1)
local exit_code=$?
if [[ $exit_code -ne 0 ]]; then
echo -e "\r${RED}✗ Setup failed${NC} "
echo ""
echo "Try running manually:"
echo " $python_cmd -m pip install mcp google-genai openai pydantic"
echo "Installation error:"
echo "$install_output" | head -20
echo ""
# Check for common issues
if echo "$install_output" | grep -q "No module named pip"; then
print_error "pip module not found"
echo ""
echo "Your Python installation is incomplete. Please install pip:"
local distro=$(detect_linux_distro)
local python_version=$($python_cmd --version 2>&1 | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' || echo "")
local install_cmd=$(get_install_command "$distro" "$python_version")
if [[ -n "$install_cmd" ]]; then
echo ""
echo "For your system ($distro), run:"
echo " $install_cmd"
else
echo ""
echo " Ubuntu/Debian: sudo apt install python3-pip"
echo " RHEL/CentOS: sudo dnf install python3-pip"
echo " Arch: sudo pacman -S python-pip"
fi
elif echo "$install_output" | grep -q "Permission denied"; then
print_error "Permission denied during installation"
echo ""
echo "Try using a virtual environment or install with --user flag:"
echo " $python_cmd -m pip install --user -r requirements.txt"
else
echo "Try running manually:"
echo " $python_cmd -m pip install -r requirements.txt"
echo ""
echo "Or install individual packages:"
echo " $python_cmd -m pip install mcp google-genai openai pydantic python-dotenv"
fi
return 1
else
echo -e "\r${GREEN}✓ Setup complete!${NC} "
# Verify critical imports work
if ! check_package "$python_cmd" "dotenv"; then
print_warning "python-dotenv not imported correctly, installing explicitly..."
if $python_cmd -m pip install python-dotenv &>/dev/null 2>&1; then
print_success "python-dotenv installed successfully"
else
print_error "Failed to install python-dotenv"
return 1
fi
fi
return 0
fi
}