Task 11: Implement Deployment and Configuration
- Add production.py with security hardening and performance optimizations - Required environment variables for security (JWT, passwords, database) - Database connection pooling for PostgreSQL/MySQL - Security configurations and allowed hosts - Production logging and rotation settings - API rate limiting and performance tuning - Add development.py with relaxed settings for local development - Defaults for development (SQLite, debug logging, auto-reload) - Higher rate limits and longer session timeouts - Dev credentials for easy local setup - Development database defaults - Add environment configuration loader (__init__.py) - Automatic environment detection - Factory functions for lazy loading settings - Proper environment validation - Add startup scripts (start.sh) - Bash script for starting application in any environment - Conda environment validation - Automatic directory creation - Environment file generation - Database initialization - Development vs production startup modes - Add setup script (setup.py) - Python setup automation for environment initialization - Dependency installation - Environment file generation - Database initialization - Comprehensive validation and error handling - Update requirements.txt with psutil dependency All configurations follow project coding standards and include comprehensive documentation, type hints, and error handling.
This commit is contained in:
245
scripts/start.sh
Normal file
245
scripts/start.sh
Normal file
@@ -0,0 +1,245 @@
|
||||
#!/bin/bash
|
||||
|
||||
################################################################################
|
||||
# Aniworld Application Startup Script
|
||||
#
|
||||
# This script initializes the development or production environment,
|
||||
# installs dependencies, sets up the database, and starts the application.
|
||||
#
|
||||
# Usage:
|
||||
# ./start.sh [development|production] [--no-install] [--no-migrate]
|
||||
#
|
||||
# Environment Variables:
|
||||
# ENVIRONMENT: 'development' or 'production' (default: development)
|
||||
# CONDA_ENV: Conda environment name (default: AniWorld)
|
||||
# PORT: Server port (default: 8000)
|
||||
# HOST: Server host (default: 127.0.0.1)
|
||||
#
|
||||
################################################################################
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# ============================================================================
|
||||
# Configuration
|
||||
# ============================================================================
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
|
||||
CONDA_ENV="${CONDA_ENV:-AniWorld}"
|
||||
ENVIRONMENT="${1:-development}"
|
||||
INSTALL_DEPS="${INSTALL_DEPS:-true}"
|
||||
RUN_MIGRATIONS="${RUN_MIGRATIONS:-true}"
|
||||
PORT="${PORT:-8000}"
|
||||
HOST="${HOST:-127.0.0.1}"
|
||||
|
||||
# ============================================================================
|
||||
# Color Output
|
||||
# ============================================================================
|
||||
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# ============================================================================
|
||||
# Functions
|
||||
# ============================================================================
|
||||
|
||||
log_info() {
|
||||
echo -e "${BLUE}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
log_success() {
|
||||
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
||||
}
|
||||
|
||||
log_warning() {
|
||||
echo -e "${YELLOW}[WARNING]${NC} $1"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
# Check if conda environment exists
|
||||
check_conda_env() {
|
||||
if ! conda env list | grep -q "^$CONDA_ENV "; then
|
||||
log_error "Conda environment '$CONDA_ENV' not found."
|
||||
log_info "Create it with: conda create -n $CONDA_ENV python=3.11"
|
||||
exit 1
|
||||
fi
|
||||
log_success "Conda environment '$CONDA_ENV' found."
|
||||
}
|
||||
|
||||
# Validate environment parameter
|
||||
validate_environment() {
|
||||
if [[ ! "$ENVIRONMENT" =~ ^(development|production|testing)$ ]]; then
|
||||
log_error "Invalid environment: $ENVIRONMENT"
|
||||
log_info "Valid options: development, production, testing"
|
||||
exit 1
|
||||
fi
|
||||
log_success "Environment set to: $ENVIRONMENT"
|
||||
}
|
||||
|
||||
# Create necessary directories
|
||||
create_directories() {
|
||||
log_info "Creating necessary directories..."
|
||||
mkdir -p "$PROJECT_ROOT/logs"
|
||||
mkdir -p "$PROJECT_ROOT/data"
|
||||
mkdir -p "$PROJECT_ROOT/data/config_backups"
|
||||
mkdir -p "$PROJECT_ROOT/Temp"
|
||||
log_success "Directories created."
|
||||
}
|
||||
|
||||
# Install dependencies
|
||||
install_dependencies() {
|
||||
if [[ "$INSTALL_DEPS" != "true" ]]; then
|
||||
log_warning "Skipping dependency installation."
|
||||
return
|
||||
fi
|
||||
|
||||
log_info "Installing dependencies..."
|
||||
conda run -n "$CONDA_ENV" pip install -q -r "$PROJECT_ROOT/requirements.txt"
|
||||
log_success "Dependencies installed."
|
||||
}
|
||||
|
||||
# Run database migrations
|
||||
run_migrations() {
|
||||
if [[ "$RUN_MIGRATIONS" != "true" ]]; then
|
||||
log_warning "Skipping database migrations."
|
||||
return
|
||||
fi
|
||||
|
||||
log_info "Running database migrations..."
|
||||
cd "$PROJECT_ROOT"
|
||||
conda run -n "$CONDA_ENV" \
|
||||
python -m alembic upgrade head 2>/dev/null || log_warning "No migrations to run."
|
||||
log_success "Database migrations completed."
|
||||
}
|
||||
|
||||
# Initialize database
|
||||
init_database() {
|
||||
log_info "Initializing database..."
|
||||
cd "$PROJECT_ROOT"
|
||||
conda run -n "$CONDA_ENV" \
|
||||
python -c "from src.server.database import init_db; import asyncio; asyncio.run(init_db())"
|
||||
log_success "Database initialized."
|
||||
}
|
||||
|
||||
# Create environment file if it doesn't exist
|
||||
create_env_file() {
|
||||
ENV_FILE="$PROJECT_ROOT/.env.$ENVIRONMENT"
|
||||
if [[ ! -f "$ENV_FILE" ]]; then
|
||||
log_warning "Creating $ENV_FILE with defaults..."
|
||||
cat > "$ENV_FILE" << EOF
|
||||
# Aniworld Configuration for $ENVIRONMENT
|
||||
|
||||
# Security Settings
|
||||
JWT_SECRET_KEY=your-secret-key-here
|
||||
PASSWORD_SALT=your-salt-here
|
||||
MASTER_PASSWORD_HASH=\$2b\$12\$wP0KBVbJKVAb8CdSSXw0NeGTKCkbw4fSAFXIqR2/wDqPSEBn9w7lS
|
||||
|
||||
# Database
|
||||
DATABASE_URL=sqlite:///./data/aniworld_${ENVIRONMENT}.db
|
||||
|
||||
# Application
|
||||
ENVIRONMENT=${ENVIRONMENT}
|
||||
ANIME_DIRECTORY=/path/to/anime
|
||||
|
||||
# Server
|
||||
PORT=${PORT}
|
||||
HOST=${HOST}
|
||||
|
||||
# Logging
|
||||
LOG_LEVEL=$([ "$ENVIRONMENT" = "production" ] && echo "WARNING" || echo "DEBUG")
|
||||
|
||||
# Features (development only)
|
||||
$([ "$ENVIRONMENT" = "development" ] && echo "DEBUG=true" || echo "DEBUG=false")
|
||||
EOF
|
||||
log_success "Created $ENV_FILE - please configure with your settings"
|
||||
fi
|
||||
}
|
||||
|
||||
# Start the application
|
||||
start_application() {
|
||||
log_info "Starting Aniworld application..."
|
||||
log_info "Environment: $ENVIRONMENT"
|
||||
log_info "Conda Environment: $CONDA_ENV"
|
||||
log_info "Server: http://$HOST:$PORT"
|
||||
|
||||
cd "$PROJECT_ROOT"
|
||||
|
||||
case "$ENVIRONMENT" in
|
||||
development)
|
||||
log_info "Starting in development mode with auto-reload..."
|
||||
conda run -n "$CONDA_ENV" \
|
||||
python -m uvicorn \
|
||||
src.server.fastapi_app:app \
|
||||
--host "$HOST" \
|
||||
--port "$PORT" \
|
||||
--reload
|
||||
;;
|
||||
production)
|
||||
WORKERS="${WORKERS:-4}"
|
||||
log_info "Starting in production mode with $WORKERS workers..."
|
||||
conda run -n "$CONDA_ENV" \
|
||||
python -m uvicorn \
|
||||
src.server.fastapi_app:app \
|
||||
--host "$HOST" \
|
||||
--port "$PORT" \
|
||||
--workers "$WORKERS" \
|
||||
--worker-class "uvicorn.workers.UvicornWorker"
|
||||
;;
|
||||
testing)
|
||||
log_warning "Starting in testing mode..."
|
||||
# Testing mode typically runs tests instead of starting server
|
||||
conda run -n "$CONDA_ENV" \
|
||||
python -m pytest tests/ -v --tb=short
|
||||
;;
|
||||
*)
|
||||
log_error "Unknown environment: $ENVIRONMENT"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# Main Script
|
||||
# ============================================================================
|
||||
|
||||
main() {
|
||||
log_info "=========================================="
|
||||
log_info "Aniworld Application Startup"
|
||||
log_info "=========================================="
|
||||
|
||||
# Parse command-line options
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--no-install)
|
||||
INSTALL_DEPS="false"
|
||||
shift
|
||||
;;
|
||||
--no-migrate)
|
||||
RUN_MIGRATIONS="false"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
ENVIRONMENT="$1"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
validate_environment
|
||||
check_conda_env
|
||||
create_directories
|
||||
create_env_file
|
||||
install_dependencies
|
||||
init_database
|
||||
run_migrations
|
||||
start_application
|
||||
}
|
||||
|
||||
# Run main function
|
||||
main "$@"
|
||||
Reference in New Issue
Block a user