Spaces:
Sleeping
Sleeping
| """ | |
| Direct HF Spaces deploy script — creates space, uploads all files. | |
| """ | |
| import os | |
| import json | |
| import shutil | |
| import tempfile | |
| from pathlib import Path | |
| from huggingface_hub import HfApi, upload_folder | |
| api = HfApi() | |
| SPACE_ID = "Raunak211006/hale-api" | |
| PROJECT_DIR = os.path.dirname(os.path.abspath(__file__)) | |
| print("=" * 60) | |
| print("HALE API -> Hugging Face Spaces Deploy") | |
| print("=" * 60) | |
| # 1. Create Space | |
| print("\n[1/4] Creating Space...") | |
| try: | |
| api.create_repo( | |
| repo_id=SPACE_ID, | |
| repo_type="space", | |
| space_sdk="docker", | |
| private=False, | |
| exist_ok=True, | |
| ) | |
| print(f" > Space ready: https://huggingface.co/spaces/{SPACE_ID}") | |
| except Exception as e: | |
| print(f" Space: {e}") | |
| # 2. Prepare deploy directory | |
| print("\n[2/4] Preparing deploy files...") | |
| deploy_dir = os.path.join(tempfile.gettempdir(), "hale-deploy") | |
| if os.path.exists(deploy_dir): | |
| shutil.rmtree(deploy_dir) | |
| os.makedirs(deploy_dir) | |
| # Files/dirs to SKIP | |
| SKIP = { | |
| '.git', '__pycache__', '.pytest_cache', 'hale-frontend', | |
| 'node_modules', '.env', 'data', 'logs', '.planning', | |
| 'Dockerfile.spaces', 'deploy_hf.py', 'deploy_spaces.py', | |
| '.github', '.gitattributes', '.dockerignore', | |
| 'docker-compose.yml', 'alembic', 'alembic.ini', | |
| 'debug_hale_db.py', 'migrate_db.py', 'seed_test_data.py', | |
| 'simulate_e2e.py', '.antigravityignore', | |
| } | |
| for item in os.listdir(PROJECT_DIR): | |
| if item in SKIP: | |
| continue | |
| src = os.path.join(PROJECT_DIR, item) | |
| dst = os.path.join(deploy_dir, item) | |
| try: | |
| if os.path.isdir(src): | |
| shutil.copytree(src, dst, dirs_exist_ok=True, | |
| ignore=shutil.ignore_patterns('__pycache__', '*.pyc', '.pytest_cache')) | |
| else: | |
| shutil.copy2(src, dst) | |
| except Exception as e: | |
| print(f" Skip {item}: {e}") | |
| # Copy Dockerfile.spaces as Dockerfile | |
| spaces_dockerfile = os.path.join(PROJECT_DIR, "Dockerfile.spaces") | |
| if os.path.exists(spaces_dockerfile): | |
| shutil.copy2(spaces_dockerfile, os.path.join(deploy_dir, "Dockerfile")) | |
| print(" > Dockerfile.spaces -> Dockerfile") | |
| # Create .env for spaces | |
| env_content = f"""APP_ENV=production | |
| DATABASE_URL=sqlite:///./data/hale.db | |
| CORS_ORIGINS=* | |
| LOG_LEVEL=INFO | |
| GEMINI_API_KEYS={os.environ.get('GEMINI_API_KEYS', '')} | |
| SECRET_KEY=hale-production-key-change-me-to-random-64-chars-in-settings | |
| """ | |
| # Read GEMINI keys from local .env | |
| local_env = os.path.join(PROJECT_DIR, ".env") | |
| if os.path.exists(local_env): | |
| with open(local_env) as f: | |
| for line in f: | |
| line = line.strip() | |
| if line.startswith("GEMINI_API_KEYS="): | |
| gemini_keys = line.split("=", 1)[1] | |
| env_content = env_content.replace( | |
| f"GEMINI_API_KEYS=", | |
| f"GEMINI_API_KEYS={gemini_keys}" | |
| ) | |
| break | |
| with open(os.path.join(deploy_dir, ".env"), "w", encoding="utf-8") as f: | |
| f.write(env_content) | |
| print(" > .env created") | |
| # Create README.md with HF Spaces metadata | |
| readme = "---\ntitle: HALE - Adaptive Learning Engine API\nemoji: \U0001F9E0\ncolorFrom: purple\ncolorTo: blue\nsdk: docker\napp_port: 7860\npinned: true\n---\n\n# HALE - Adaptive Learning Engine\n\nAI-powered adaptive learning API with Reinforcement Learning behavioral engine.\n\n**API Docs**: [Open Swagger UI](/docs)\n\n## Quick Start\n1. POST /api/auth/register - Register user\n2. POST /api/auth/login - Get JWT token\n3. POST /api/goals/ - Create a learning goal\n4. GET /api/plan - Get todays adaptive plan\n5. POST /api/complete-task - Mark task done\n6. GET /api/stats - View analytics\n\n## Features\n- Contextual Multi-Armed Bandit RL engine (Thompson Sampling)\n- AI-generated curriculum via Gemini\n- Behavioral adaptation (mood, fatigue, stress, sleep)\n- Multi-goal support with priority-weighted scheduling\n- Streak tracking, XP, and leveling system\n- Auto-close at 2 AM IST with next-day preparation\n" | |
| with open(os.path.join(deploy_dir, "README.md"), "w", encoding="utf-8") as f: | |
| f.write(readme) | |
| print(" > README.md created") | |
| # Count files | |
| file_count = sum(len(files) for _, _, files in os.walk(deploy_dir)) | |
| print(f" > {file_count} files ready") | |
| # 3. Upload | |
| print(f"\n[3/4] Uploading to HF Spaces ({SPACE_ID})...") | |
| try: | |
| api.upload_folder( | |
| folder_path=deploy_dir, | |
| repo_id=SPACE_ID, | |
| repo_type="space", | |
| commit_message="Deploy HALE API v3.1", | |
| ) | |
| print(" > Upload complete!") | |
| except Exception as e: | |
| print(f" Upload failed: {e}") | |
| raise | |
| # 4. Done | |
| print("") | |
| print("=" * 60) | |
| print("DEPLOYMENT COMPLETE!") | |
| print("") | |
| print("API: https://raunak211006-hale-api.hf.space") | |
| print("Docs: https://raunak211006-hale-api.hf.space/docs") | |
| print(f"Space: https://huggingface.co/spaces/{SPACE_ID}") | |
| print("") | |
| print("Building may take 2-3 minutes. Check the Space page for status.") | |
| print("=" * 60) | |