| |
| """ |
| Interactive Setup Wizard for ATOM Application |
| Guides users through environment configuration step-by-step. |
| """ |
|
|
| import base64 |
| import os |
| from pathlib import Path |
| import secrets |
|
|
|
|
| def generate_secret_key() -> str: |
| """Generate a secure random key for encryption.""" |
| return base64.b64encode(secrets.token_bytes(32)).decode('utf-8') |
|
|
|
|
| def get_input(prompt: str, default: str = "", required: bool = False) -> str: |
| """Get user input with optional default value.""" |
| if default: |
| full_prompt = f"{prompt} [{default}]: " |
| else: |
| full_prompt = f"{prompt}: " |
| |
| while True: |
| value = input(full_prompt).strip() |
| if not value and default: |
| return default |
| if not value and required: |
| print("❌ This field is required. Please provide a value.") |
| continue |
| return value |
|
|
|
|
| def main(): |
| """Main setup wizard.""" |
| print("=" * 80) |
| print("🚀 ATOM APPLICATION - INTERACTIVE SETUP WIZARD") |
| print("=" * 80) |
| print() |
| print("This wizard will help you create a .env file with your credentials.") |
| print("Press Enter to skip optional fields.") |
| print() |
| |
| |
| env_path = Path(__file__).parent.parent.parent / ".env" |
| if env_path.exists(): |
| response = input("⚠️ .env file already exists. Overwrite? (y/N): ").strip().lower() |
| if response != 'y': |
| print("Setup cancelled.") |
| return |
| |
| config = {} |
| |
| |
| print("\n🔒 SECURITY CONFIGURATION (Required)") |
| print("-" * 80) |
| print("Generating secure encryption keys...") |
| config["NEXTAUTH_SECRET"] = generate_secret_key() |
| config["ATOM_ENCRYPTION_KEY"] = generate_secret_key() |
| config["BYOK_ENCRYPTION_KEY"] = generate_secret_key() |
| print("✅ Generated NEXTAUTH_SECRET") |
| print("✅ Generated ATOM_ENCRYPTION_KEY") |
| print("✅ Generated BYOK_ENCRYPTION_KEY") |
| |
| config["NEXTAUTH_URL"] = get_input( |
| "NextAuth URL", |
| default="http://localhost:3000", |
| required=True |
| ) |
| |
| |
| print("\n⚙️ CORE CONFIGURATION") |
| print("-" * 80) |
| config["NODE_ENV"] = get_input("Environment", default="development") |
| config["NEXT_PUBLIC_API_BASE_URL"] = get_input( |
| "Backend API URL", |
| default="http://localhost:8000" |
| ) |
| config["LOG_LEVEL"] = get_input("Log Level", default="info") |
| |
| |
| print("\n💾 DATABASE CONFIGURATION") |
| print("-" * 80) |
| config["LANCEDB_PATH"] = get_input("LanceDB Path", default="./data/lancedb") |
| config["SQLITE_PATH"] = get_input("SQLite Path", default="./data/atom.db") |
| |
| use_postgres = input("Use PostgreSQL? (y/N): ").strip().lower() == 'y' |
| if use_postgres: |
| config["DATABASE_URL"] = get_input("PostgreSQL URL", required=True) |
| |
| |
| print("\n🤖 AI SERVICES (Optional - Add as needed)") |
| print("-" * 80) |
| print("Tip: You can skip these and add them later in .env") |
| |
| if input("Configure OpenAI? (y/N): ").strip().lower() == 'y': |
| config["OPENAI_API_KEY"] = get_input("OpenAI API Key", required=True) |
| |
| if input("Configure Anthropic (Claude)? (y/N): ").strip().lower() == 'y': |
| config["ANTHROPIC_API_KEY"] = get_input("Anthropic API Key", required=True) |
| |
| |
| print("\n🔌 INTEGRATIONS (Optional)") |
| print("-" * 80) |
| print("You can configure integrations now or add them later.") |
| print("See docs/missing_credentials_guide.md for full list.") |
| |
| if input("Configure Slack? (y/N): ").strip().lower() == 'y': |
| config["SLACK_CLIENT_ID"] = get_input("Slack Client ID", required=True) |
| config["SLACK_CLIENT_SECRET"] = get_input("Slack Client Secret", required=True) |
| |
| if input("Configure Google Services? (y/N): ").strip(). lower() == 'y': |
| config["GOOGLE_CLIENT_ID"] = get_input("Google Client ID", required=True) |
| config["GOOGLE_CLIENT_SECRET"] = get_input("Google Client Secret", required=True) |
| |
| |
| print("\n📝 Writing .env file...") |
| with open(env_path, 'w') as f: |
| f.write("# ATOM Application Environment Variables\n") |
| f.write(f"# Generated by setup wizard\n\n") |
| |
| for key, value in config.items(): |
| f.write(f"{key}={value}\n") |
| |
| f.write("\n# Add more credentials as needed") |
| f.write("\n# See .env.example for full template\n") |
| |
| print("✅ .env file created successfully!") |
| print() |
| print("=" * 80) |
| print("NEXT STEPS") |
| print("=" * 80) |
| print("1. Review and edit .env to add more integrations") |
| print("2. Run: python backend/scripts/validate_credentials.py") |
| print("3. Start backend: cd backend && python main_api_app.py") |
| print("4. Start frontend: cd frontend-nextjs && npm run dev") |
| print() |
| print("📖 For more integrations: See .env.example and docs/missing_credentials_guide.md") |
| print("=" * 80) |
|
|
|
|
| if __name__ == "__main__": |
| try: |
| main() |
| except KeyboardInterrupt: |
| print("\n\nSetup cancelled by user.") |
| except Exception as e: |
| print(f"\n❌ Error: {e}") |
| print("Please check your inputs and try again.") |
|
|