From 37c0882d2d9e651bb5e21da4a10bb6700fdca3dd Mon Sep 17 00:00:00 2001 From: cclohmar Date: Mon, 16 Mar 2026 16:15:18 +0000 Subject: [PATCH] chore: auto-commit 2026-03-16 16:15 --- install.sh | 156 +++++++++++++++++++++++++++++++++++++++-------- requirements.txt | 38 ++++++------ 2 files changed, 148 insertions(+), 46 deletions(-) diff --git a/install.sh b/install.sh index 75ef153..9ef5a6e 100644 --- a/install.sh +++ b/install.sh @@ -58,6 +58,40 @@ check_prerequisites() { exit 1 fi + # Check Python version for compatibility + PYTHON_VERSION=$(python3 -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}')") + PYTHON_MAJOR=$(python3 -c "import sys; print(sys.version_info.major)") + PYTHON_MINOR=$(python3 -c "import sys; print(sys.version_info.minor)") + + print_info "Python version: $PYTHON_VERSION" + + # Warn about Python 3.13+ compatibility issues + if [[ $PYTHON_MAJOR -eq 3 ]] && [[ $PYTHON_MINOR -ge 13 ]]; then + print_warning "Python $PYTHON_VERSION detected. Some packages may have compatibility issues." + print_warning "For production, Python 3.11 or 3.12 is recommended for better package compatibility." + echo + print_info "Checking for alternative Python versions..." + + # Check if python3.12 or python3.11 are available + if command -v python3.12 &> /dev/null; then + print_info "Found python3.12. You can switch to it by modifying this script." + elif command -v python3.11 &> /dev/null; then + print_info "Found python3.11. You can switch to it by modifying this script." + else + print_info "No alternative Python versions found. Continuing with Python $PYTHON_VERSION." + fi + + echo + print_warning "Continuing with Python $PYTHON_VERSION. Compatibility issues may occur." + read -p "Continue anyway? (y/N): " -n 1 -r + echo + if [[ ! $REPLY =~ ^[Yy]$ ]]; then + print_info "Installation aborted. Please install Python 3.11 or 3.12 and try again." + print_info "On Ubuntu/Debian: sudo apt-get install python3.12" + exit 1 + fi + fi + # Check pip if ! command -v pip3 &> /dev/null; then print_warning "pip3 not found. Installing..." @@ -82,27 +116,52 @@ generate_random_string() { setup_environment() { print_status "Setting up Python virtual environment..." - # Create virtual environment - if [[ ! -d "$VENV_DIR" ]]; then - python3 -m venv "$VENV_DIR" - print_status "Virtual environment created at $VENV_DIR" - else - print_warning "Virtual environment already exists at $VENV_DIR" - read -p "Recreate virtual environment? (y/N): " -n 1 -r - echo - if [[ $REPLY =~ ^[Yy]$ ]]; then + # Get Python version for compatibility handling + PYTHON_MAJOR=$(python3 -c "import sys; print(sys.version_info.major)") + PYTHON_MINOR=$(python3 -c "import sys; print(sys.version_info.minor)") + + # For Python 3.13+, always recreate virtual environment for fresh install + if [[ $PYTHON_MAJOR -eq 3 ]] && [[ $PYTHON_MINOR -ge 13 ]]; then + print_warning "Python 3.13+ detected. Forcing fresh virtual environment for compatibility." + if [[ -d "$VENV_DIR" ]]; then rm -rf "$VENV_DIR" + print_status "Removed existing virtual environment." + fi + python3 -m venv "$VENV_DIR" + print_status "Created fresh virtual environment for Python 3.13+ compatibility." + else + # Normal flow for Python < 3.13 + if [[ ! -d "$VENV_DIR" ]]; then python3 -m venv "$VENV_DIR" - print_status "Virtual environment recreated." + print_status "Virtual environment created at $VENV_DIR" + else + print_warning "Virtual environment already exists at $VENV_DIR" + read -p "Recreate virtual environment? (y/N): " -n 1 -r + echo + if [[ $REPLY =~ ^[Yy]$ ]]; then + rm -rf "$VENV_DIR" + python3 -m venv "$VENV_DIR" + print_status "Virtual environment recreated." + fi fi fi # Activate virtual environment and install dependencies source "${VENV_DIR}/bin/activate" + + # Upgrade pip to latest version (important for Python 3.13+ compatibility) + print_status "Upgrading pip to latest version..." pip install --upgrade pip + # For Python 3.13+, install packages with --upgrade flag and better error handling print_status "Installing Python dependencies..." - pip install -r "${APP_DIR}/requirements.txt" + + if [[ $PYTHON_MAJOR -eq 3 ]] && [[ $PYTHON_MINOR -ge 13 ]]; then + print_info "Python 3.13+ detected: Using --upgrade flag for all packages." + pip install --upgrade -r "${APP_DIR}/requirements.txt" + else + pip install -r "${APP_DIR}/requirements.txt" + fi deactivate print_status "Dependencies installed." @@ -294,31 +353,74 @@ initialize_database() { # Activate virtual environment source "${VENV_DIR}/bin/activate" - # Run a simple Python script to initialize database + # Get Python version for logging + PYTHON_VERSION=$(python3 -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}')") + + # First, ensure database directory exists + DB_PATH=$(grep "^DATABASE_URL=" "${APP_DIR}/.env" 2>/dev/null | cut -d'=' -f2- | sed "s|sqlite+aiosqlite:///||" || echo "${APP_DIR}/mockapi.db") + DB_DIR=$(dirname "$DB_PATH") + + if [[ ! -d "$DB_DIR" ]]; then + mkdir -p "$DB_DIR" + print_status "Created database directory: $DB_DIR" + fi + + # Try to initialize database with Python script (with error handling) + print_info "Attempting to create database tables..." + python3 -c " import asyncio import sys +import traceback sys.path.insert(0, '${APP_DIR}') -from app.core.database import engine -from app.core.config import settings -import asyncio -async def init_db(): - from sqlalchemy.ext.asyncio import AsyncSession - from sqlalchemy.orm import sessionmaker - from app.core.database import Base - from app.modules.endpoints.models import Endpoint - from app.modules.oauth2.models import OAuthClient, OAuthToken, OAuthUser +try: + # Try to import SQLAlchemy and app modules + from app.core.database import engine, init_db + from app.core.config import settings - async with engine.begin() as conn: - await conn.run_sync(Base.metadata.create_all) - print('Database tables created successfully') - -asyncio.run(init_db()) + async def create_tables(): + try: + # Call the app's init_db function which handles table creation + await init_db() + print('Database tables created successfully via init_db()') + except Exception as e: + print(f'Error in init_db(): {e}') + # Fallback: try direct table creation + try: + from app.core.database import Base + async with engine.begin() as conn: + await conn.run_sync(Base.metadata.create_all) + print('Database tables created successfully (fallback method)') + except Exception as e2: + print(f'Fallback also failed: {e2}') + print('Tables will be created when application starts') + + asyncio.run(create_tables()) + +except ImportError as e: + print(f'Import error (package compatibility issue): {e}') + print('This may be due to Python ${PYTHON_VERSION} compatibility issues.') + print('Database tables will be created when the application starts.') + print('If the application fails to start, try:') + print('1. Installing Python 3.11 or 3.12') + print('2. Checking pip package versions') + +except Exception as e: + print(f'Unexpected error during database initialization: {e}') + print(traceback.format_exc()) + print('Database tables will be created when the application starts.') " + # Create empty database file if it doesn't exist (for SQLite) + if [[ ! -f "$DB_PATH" ]]; then + touch "$DB_PATH" + print_status "Created empty database file: $DB_PATH" + print_info "Tables will be created when application starts." + fi + deactivate - print_status "Database initialized." + print_status "Database initialization attempted. Tables will be created on application startup if not already present." } start_service() { diff --git a/requirements.txt b/requirements.txt index c832bdc..c1f34a5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,30 +1,30 @@ # Core Framework -fastapi==0.104.1 -uvicorn[standard]==0.24.0 -waitress==3.0.1 -asgiref==3.7.0 -a2wsgi==1.10.10 +fastapi>=0.111.0,<1.0.0 # 0.111.0+ for Python 3.14 compatibility +uvicorn[standard]>=0.30.0,<1.0.0 # 0.30.0+ for Python 3.14 compatibility +waitress>=3.0.1,<4.0.0 +asgiref>=3.7.0,<4.0.0 +a2wsgi>=1.10.10,<2.0.0 # Database -sqlalchemy==2.0.23 -aiosqlite==0.19.0 +sqlalchemy>=2.0.27,<2.1.0 # 2.0.27+ fixes Python 3.13+ compatibility +aiosqlite>=0.19.0,<0.20.0 # Templates & UI -jinja2==3.1.2 -python-multipart==0.0.6 +jinja2>=3.1.2,<4.0.0 +python-multipart>=0.0.6,<0.1.0 # Authentication & Security -passlib[bcrypt]==1.7.4 -python-jose[cryptography]==3.3.0 -python-dotenv==1.0.0 -pydantic-settings==2.11.0 -itsdangerous==2.2.0 +passlib[bcrypt]>=1.7.4,<2.0.0 +python-jose[cryptography]>=3.3.0,<4.0.0 +python-dotenv>=1.0.0,<2.0.0 +pydantic-settings>=2.11.0,<3.0.0 +itsdangerous>=2.2.0,<3.0.0 # Development & Testing -pytest==7.4.3 -pytest-asyncio==0.21.1 -httpx==0.25.1 +pytest>=7.4.3,<8.0.0 +pytest-asyncio>=0.21.1,<1.0.0 +httpx>=0.25.1,<1.0.0 # Optional (for future enhancements) -redis==5.0.1 # For distributed route sync -celery==5.3.4 # For background tasks +redis>=5.0.1,<6.0.0 # For distributed route sync +celery>=5.3.4,<6.0.0 # For background tasks