chore: auto-commit 2026-03-16 16:15
This commit is contained in:
parent
7da4eff745
commit
37c0882d2d
2 changed files with 148 additions and 46 deletions
156
install.sh
156
install.sh
|
|
@ -58,6 +58,40 @@ check_prerequisites() {
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
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
|
# Check pip
|
||||||
if ! command -v pip3 &> /dev/null; then
|
if ! command -v pip3 &> /dev/null; then
|
||||||
print_warning "pip3 not found. Installing..."
|
print_warning "pip3 not found. Installing..."
|
||||||
|
|
@ -82,27 +116,52 @@ generate_random_string() {
|
||||||
setup_environment() {
|
setup_environment() {
|
||||||
print_status "Setting up Python virtual environment..."
|
print_status "Setting up Python virtual environment..."
|
||||||
|
|
||||||
# Create virtual environment
|
# Get Python version for compatibility handling
|
||||||
if [[ ! -d "$VENV_DIR" ]]; then
|
PYTHON_MAJOR=$(python3 -c "import sys; print(sys.version_info.major)")
|
||||||
python3 -m venv "$VENV_DIR"
|
PYTHON_MINOR=$(python3 -c "import sys; print(sys.version_info.minor)")
|
||||||
print_status "Virtual environment created at $VENV_DIR"
|
|
||||||
else
|
# For Python 3.13+, always recreate virtual environment for fresh install
|
||||||
print_warning "Virtual environment already exists at $VENV_DIR"
|
if [[ $PYTHON_MAJOR -eq 3 ]] && [[ $PYTHON_MINOR -ge 13 ]]; then
|
||||||
read -p "Recreate virtual environment? (y/N): " -n 1 -r
|
print_warning "Python 3.13+ detected. Forcing fresh virtual environment for compatibility."
|
||||||
echo
|
if [[ -d "$VENV_DIR" ]]; then
|
||||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
|
||||||
rm -rf "$VENV_DIR"
|
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"
|
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
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Activate virtual environment and install dependencies
|
# Activate virtual environment and install dependencies
|
||||||
source "${VENV_DIR}/bin/activate"
|
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
|
pip install --upgrade pip
|
||||||
|
|
||||||
|
# For Python 3.13+, install packages with --upgrade flag and better error handling
|
||||||
print_status "Installing Python dependencies..."
|
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
|
deactivate
|
||||||
print_status "Dependencies installed."
|
print_status "Dependencies installed."
|
||||||
|
|
@ -294,31 +353,74 @@ initialize_database() {
|
||||||
# Activate virtual environment
|
# Activate virtual environment
|
||||||
source "${VENV_DIR}/bin/activate"
|
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 "
|
python3 -c "
|
||||||
import asyncio
|
import asyncio
|
||||||
import sys
|
import sys
|
||||||
|
import traceback
|
||||||
sys.path.insert(0, '${APP_DIR}')
|
sys.path.insert(0, '${APP_DIR}')
|
||||||
from app.core.database import engine
|
|
||||||
from app.core.config import settings
|
|
||||||
import asyncio
|
|
||||||
|
|
||||||
async def init_db():
|
try:
|
||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
# Try to import SQLAlchemy and app modules
|
||||||
from sqlalchemy.orm import sessionmaker
|
from app.core.database import engine, init_db
|
||||||
from app.core.database import Base
|
from app.core.config import settings
|
||||||
from app.modules.endpoints.models import Endpoint
|
|
||||||
from app.modules.oauth2.models import OAuthClient, OAuthToken, OAuthUser
|
|
||||||
|
|
||||||
async with engine.begin() as conn:
|
async def create_tables():
|
||||||
await conn.run_sync(Base.metadata.create_all)
|
try:
|
||||||
print('Database tables created successfully')
|
# Call the app's init_db function which handles table creation
|
||||||
|
await init_db()
|
||||||
asyncio.run(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
|
deactivate
|
||||||
print_status "Database initialized."
|
print_status "Database initialization attempted. Tables will be created on application startup if not already present."
|
||||||
}
|
}
|
||||||
|
|
||||||
start_service() {
|
start_service() {
|
||||||
|
|
|
||||||
|
|
@ -1,30 +1,30 @@
|
||||||
# Core Framework
|
# Core Framework
|
||||||
fastapi==0.104.1
|
fastapi>=0.111.0,<1.0.0 # 0.111.0+ for Python 3.14 compatibility
|
||||||
uvicorn[standard]==0.24.0
|
uvicorn[standard]>=0.30.0,<1.0.0 # 0.30.0+ for Python 3.14 compatibility
|
||||||
waitress==3.0.1
|
waitress>=3.0.1,<4.0.0
|
||||||
asgiref==3.7.0
|
asgiref>=3.7.0,<4.0.0
|
||||||
a2wsgi==1.10.10
|
a2wsgi>=1.10.10,<2.0.0
|
||||||
|
|
||||||
# Database
|
# Database
|
||||||
sqlalchemy==2.0.23
|
sqlalchemy>=2.0.27,<2.1.0 # 2.0.27+ fixes Python 3.13+ compatibility
|
||||||
aiosqlite==0.19.0
|
aiosqlite>=0.19.0,<0.20.0
|
||||||
|
|
||||||
# Templates & UI
|
# Templates & UI
|
||||||
jinja2==3.1.2
|
jinja2>=3.1.2,<4.0.0
|
||||||
python-multipart==0.0.6
|
python-multipart>=0.0.6,<0.1.0
|
||||||
|
|
||||||
# Authentication & Security
|
# Authentication & Security
|
||||||
passlib[bcrypt]==1.7.4
|
passlib[bcrypt]>=1.7.4,<2.0.0
|
||||||
python-jose[cryptography]==3.3.0
|
python-jose[cryptography]>=3.3.0,<4.0.0
|
||||||
python-dotenv==1.0.0
|
python-dotenv>=1.0.0,<2.0.0
|
||||||
pydantic-settings==2.11.0
|
pydantic-settings>=2.11.0,<3.0.0
|
||||||
itsdangerous==2.2.0
|
itsdangerous>=2.2.0,<3.0.0
|
||||||
|
|
||||||
# Development & Testing
|
# Development & Testing
|
||||||
pytest==7.4.3
|
pytest>=7.4.3,<8.0.0
|
||||||
pytest-asyncio==0.21.1
|
pytest-asyncio>=0.21.1,<1.0.0
|
||||||
httpx==0.25.1
|
httpx>=0.25.1,<1.0.0
|
||||||
|
|
||||||
# Optional (for future enhancements)
|
# Optional (for future enhancements)
|
||||||
redis==5.0.1 # For distributed route sync
|
redis>=5.0.1,<6.0.0 # For distributed route sync
|
||||||
celery==5.3.4 # For background tasks
|
celery>=5.3.4,<6.0.0 # For background tasks
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue