puppycompanion-v3 / deploy_hf.sh.backup
Deploy Script
Deploy PuppyCompanion FastAPI 2025-06-02 10:08:59
4d264ff
#!/bin/bash
# HuggingFace deployment script for PuppyCompanion FastAPI
# Usage: ./deploy_hf.sh [--space-name SPACE_NAME]
set -e
# Colors
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
BLUE='\033[0;34m'
NC='\033[0m'
log() {
echo -e "${GREEN}[DEPLOY]${NC} $1"
}
warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
error() {
echo -e "${RED}[ERROR]${NC} $1"
}
info() {
echo -e "${BLUE}[INFO]${NC} $1"
}
# Default configuration
SPACE_NAME="puppycompanion-v3"
APP_DIR="."
HF_USERNAME="JTh34"
# Parse arguments
while [[ $# -gt 0 ]]; do
case $1 in
--space-name)
SPACE_NAME="$2"
shift 2
;;
*)
error "Unknown option: $1"
exit 1
;;
esac
done
# Ask for space name if not provided (with default)
if [ -z "$SPACE_NAME" ]; then
read -p "HuggingFace space name [puppycompanion-v3]: " SPACE_NAME
SPACE_NAME=${SPACE_NAME:-puppycompanion-v3}
fi
if [ -z "$SPACE_NAME" ]; then
error "Space name required"
exit 1
fi
# Check that the app directory exists
if [ ! -d "$APP_DIR" ]; then
error "Application directory not found: $APP_DIR"
exit 1
fi
cd "$APP_DIR"
log "Preparing deployment for FastAPI space: $HF_USERNAME/$SPACE_NAME"
# Pre-deployment checks
log "Pre-deployment checks..."
# Check required files for FastAPI application
REQUIRED_FILES=(
"main.py"
"Dockerfile"
"README.MD"
"all_books_preprocessed_chunks.json"
"rag_system.py"
"agent_workflow.py"
"embedding_models.py"
"books_config.json"
"static/index.html"
)
for file in "${REQUIRED_FILES[@]}"; do
if [ ! -f "$file" ]; then
error "Missing required file: $file"
exit 1
fi
done
log "βœ… All required files found"
# Check that API keys are not in files
ENV_FILES=(".env" ".env.local" ".env.prod" ".env.development" ".env.staging")
for env_file in "${ENV_FILES[@]}"; do
if [ -f "$env_file" ]; then
if grep -q "sk-\|OPENAI_API_KEY\|TAVILY_API_KEY" "$env_file" 2>/dev/null; then
warn "API keys detected in $env_file - file will be excluded from deployment"
warn "Make sure to configure your secrets on HuggingFace Spaces"
fi
fi
done
# Check for PDF files that should not be deployed
if ls data/*.pdf >/dev/null 2>&1; then
warn "PDF files detected in data/ directory"
warn "These will be excluded from deployment for security"
fi
# Validate chunks file size
if [ -f "all_books_preprocessed_chunks.json" ]; then
FILE_SIZE=$(stat -f%z "all_books_preprocessed_chunks.json" 2>/dev/null || stat -c%s "all_books_preprocessed_chunks.json" 2>/dev/null)
FILE_SIZE_MB=$((FILE_SIZE / 1024 / 1024))
log "Chunks file size: ${FILE_SIZE_MB}MB"
if [ $FILE_SIZE_MB -gt 100 ]; then
warn "Large chunks file detected (${FILE_SIZE_MB}MB)"
warn "This may cause slower deployment and startup times"
fi
fi
# Create requirements.txt from pyproject.toml if needed and requirements.txt doesn't exist
if [ ! -f "requirements.txt" ] && [ -f "pyproject.toml" ]; then
log "Generating requirements.txt from pyproject.toml..."
if command -v pip-compile &> /dev/null; then
pip-compile pyproject.toml
else
warn "pip-compile not found. Basic requirements.txt generation..."
# Basic extraction of dependencies from pyproject.toml
if command -v python &> /dev/null; then
python -c "
import tomllib
with open('pyproject.toml', 'rb') as f:
data = tomllib.load(f)
deps = data.get('project', {}).get('dependencies', [])
with open('requirements.txt', 'w') as f:
for dep in deps:
f.write(dep + '\n')
" 2>/dev/null || {
warn "Could not generate requirements.txt automatically"
warn "Please create the requirements.txt file manually"
exit 1
}
fi
fi
elif [ -f "requirements.txt" ]; then
log "βœ… requirements.txt found"
fi
# Validate Dockerfile for FastAPI
if grep -q "main.py" Dockerfile && grep -q "7860" Dockerfile; then
log "βœ… Dockerfile configured for FastAPI"
else
warn "Dockerfile may not be properly configured for FastAPI deployment"
fi
# Check SSH connection to HuggingFace
log "Checking HuggingFace SSH connection..."
if ! ssh -T [email protected] -o ConnectTimeout=10 -o BatchMode=yes 2>/dev/null; then
warn "SSH connection to HuggingFace failed"
info "Check your SSH configuration or use: ssh-keygen -t ed25519 -C '[email protected]'"
info "Then add the public key to your HuggingFace profile"
# Fallback to HTTPS if available
if command -v huggingface-cli &> /dev/null && huggingface-cli whoami &> /dev/null; then
warn "Using HTTPS as fallback..."
USE_SSH=false
else
error "No authentication method available"
exit 1
fi
else
log "βœ… HuggingFace SSH connection OK"
USE_SSH=true
fi
# Create the space if it does not exist (requires huggingface-cli)
if command -v huggingface-cli &> /dev/null; then
log "Creating/updating HuggingFace space..."
huggingface-cli repo create "$SPACE_NAME" --type space --space_sdk docker 2>/dev/null || true
else
warn "huggingface-cli not available, make sure the space exists"
fi
# Clone or update the repo
TEMP_DIR="/tmp/hf_deploy_$$"
log "Cloning repository..."
if [ "$USE_SSH" = true ]; then
# Use SSH
git clone "[email protected]:spaces/$HF_USERNAME/$SPACE_NAME" "$TEMP_DIR" || {
error "SSH clone failed. Check username and space name."
exit 1
}
else
# Use HTTPS
git clone "https://huggingface.co/spaces/$HF_USERNAME/$SPACE_NAME" "$TEMP_DIR" || {
error "HTTPS clone failed. Check username and space name."
exit 1
}
fi
# Copy files with FastAPI-specific exclusions
log "Copying FastAPI application files..."
rsync -av \
--exclude='.git' \
--exclude='venv_*' \
--exclude='.env*' \
--exclude='__pycache__' \
--exclude='.chainlit' \
--exclude='*.pdf' \
--exclude='*.PDF' \
--exclude='data/*.pdf' \
--exclude='data/*.PDF' \
--exclude='.DS_Store' \
--exclude='*.log' \
--exclude='qdrant_storage' \
--exclude='deploy_hf.sh' \
--exclude='.gitattributes' \
--exclude='uv.lock' \
--exclude='document_loader_preproc.py' \
./ "$TEMP_DIR/"
# Go to temp directory
cd "$TEMP_DIR"
# Configure Git if needed
git config user.email "[email protected]" || true
git config user.name "Deploy Script" || true
# Verify critical files are present
log "Verifying deployment files..."
CRITICAL_FILES=("main.py" "Dockerfile" "all_books_preprocessed_chunks.json")
for file in "${CRITICAL_FILES[@]}"; do
if [ ! -f "$file" ]; then
error "Critical file missing after copy: $file"
exit 1
fi
done
log "βœ… All critical files verified"
# Add and commit
log "Committing changes..."
git add .
git commit -m "Deploy PuppyCompanion FastAPI $(date '+%Y-%m-%d %H:%M:%S')" || {
warn "No changes detected"
}
# Push to HuggingFace
log "Pushing to HuggingFace..."
git push
# Clean up
cd - > /dev/null
rm -rf "$TEMP_DIR"
log "πŸš€ FastAPI deployment completed successfully!"
info "Your app will be available at: https://huggingface.co/spaces/$HF_USERNAME/$SPACE_NAME"
info "Deployment may take a few minutes to build and start..."
info "Check the logs on HuggingFace Spaces for any issues"