File size: 13,133 Bytes
09fa60b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
#!/usr/bin/env python3
"""

AudioForge Environment Setup Script

Helps configure .env file with Hugging Face token and other settings

"""

import os
import sys
from pathlib import Path
from typing import Optional

def get_input(prompt: str, default: Optional[str] = None, required: bool = False) -> str:
    """Get user input with optional default value."""
    if default:
        prompt = f"{prompt} [{default}]: "
    else:
        prompt = f"{prompt}: "
    
    while True:
        value = input(prompt).strip()
        if not value and default:
            return default
        if not value and required:
            print("❌ This field is required!")
            continue
        return value


def generate_secret_key() -> str:
    """Generate a secure random secret key."""
    import secrets
    return secrets.token_urlsafe(32)


def main():
    """Main setup function."""
    print("🎡 AudioForge Environment Setup")
    print("=" * 60)
    print()
    
    # Determine paths
    script_dir = Path(__file__).parent
    project_root = script_dir.parent
    backend_dir = project_root / "backend"
    env_file = backend_dir / ".env"
    env_example = backend_dir / ".env.example"
    
    # Check if .env already exists
    if env_file.exists():
        print(f"⚠️  .env file already exists at: {env_file}")
        overwrite = get_input("Do you want to overwrite it? (yes/no)", default="no")
        if overwrite.lower() not in ["yes", "y"]:
            print("❌ Setup cancelled.")
            sys.exit(0)
        print()
    
    print("πŸ“ Let's configure your environment variables...")
    print()
    
    # ═══════════════════════════════════════════════════════════
    # Hugging Face Token (MOST IMPORTANT)
    # ═══════════════════════════════════════════════════════════
    print("πŸ€— HUGGING FACE TOKEN (REQUIRED)")
    print("-" * 60)
    print("You need a Hugging Face token to download AI models.")
    print("Get your token from: https://huggingface.co/settings/tokens")
    print()
    
    hf_token = get_input(
        "Enter your Hugging Face token",
        required=True
    )
    print()
    
    # ═══════════════════════════════════════════════════════════
    # Environment Type
    # ═══════════════════════════════════════════════════════════
    print("🌍 ENVIRONMENT TYPE")
    print("-" * 60)
    environment = get_input(
        "Environment (development/staging/production)",
        default="development"
    )
    print()
    
    # ═══════════════════════════════════════════════════════════
    # Database Configuration
    # ═══════════════════════════════════════════════════════════
    print("πŸ—„οΈ  DATABASE CONFIGURATION")
    print("-" * 60)
    
    if environment == "production":
        # Production: User should provide their production database URL
        # Default shown is for reference only
        database_url = get_input(
            "Database URL",
            default="postgresql+asyncpg://postgres:postgres@localhost:5432/audioforge",
            required=True
        )
    else:
        # Development uses Docker port 5433 (mapped from container's 5432)
        database_url = "postgresql+asyncpg://postgres:postgres@localhost:5433/audioforge"
        print(f"Using default: {database_url}")
        print("  (Docker container exposes PostgreSQL on port 5433)")
    print()
    
    # ═══════════════════════════════════════════════════════════
    # Redis Configuration
    # ═══════════════════════════════════════════════════════════
    print("πŸ“¦ REDIS CONFIGURATION")
    print("-" * 60)
    redis_url = get_input(
        "Redis URL",
        default="redis://localhost:6379/0"
    )
    print()
    
    # ═══════════════════════════════════════════════════════════
    # Device Configuration
    # ═══════════════════════════════════════════════════════════
    print("πŸ–₯️  DEVICE CONFIGURATION")
    print("-" * 60)
    print("Device options: cpu, cuda (NVIDIA GPU), mps (Apple Silicon)")
    
    # Check if CUDA is available
    try:
        import torch
        if torch.cuda.is_available():
            print("βœ… CUDA detected! GPU acceleration available.")
            default_device = "cuda"
        else:
            print("ℹ️  No CUDA detected. Using CPU.")
            default_device = "cpu"
    except ImportError:
        print("ℹ️  PyTorch not installed yet. Defaulting to CPU.")
        default_device = "cpu"
    
    device = get_input(
        "Device for AI models",
        default=default_device
    )
    print()
    
    # ═══════════════════════════════════════════════════════════
    # CORS Configuration
    # ═══════════════════════════════════════════════════════════
    print("🌐 CORS CONFIGURATION")
    print("-" * 60)
    
    if environment == "production":
        allowed_origins = get_input(
            "Allowed origins (comma-separated)",
            default="https://yourdomain.com"
        )
    else:
        allowed_origins = "http://localhost:3000,http://localhost:3001"
        print(f"Using default: {allowed_origins}")
    print()
    
    # ═══════════════════════════════════════════════════════════
    # Secret Key
    # ═══════════════════════════════════════════════════════════
    print("πŸ” SECRET KEY")
    print("-" * 60)
    secret_key = generate_secret_key()
    print(f"Generated secure secret key: {secret_key[:20]}...")
    print()
    
    # ═══════════════════════════════════════════════════════════
    # Generate .env file
    # ═══════════════════════════════════════════════════════════
    print("πŸ“ Generating .env file...")
    
    env_content = f"""# ═══════════════════════════════════════════════════════════

# AudioForge Backend Environment Configuration

# Generated by setup_env.py on {Path(__file__).stat().st_mtime}

# ═══════════════════════════════════════════════════════════



# ─────────────────────────────────────────────────────────

# Application Settings

# ─────────────────────────────────────────────────────────

DEBUG={'true' if environment == 'development' else 'false'}

ENVIRONMENT={environment}

LOG_LEVEL={'DEBUG' if environment == 'development' else 'INFO'}

SECRET_KEY={secret_key}



# ─────────────────────────────────────────────────────────

# Database Configuration

# ─────────────────────────────────────────────────────────

DATABASE_URL={database_url}



# ─────────────────────────────────────────────────────────

# Redis Configuration

# ─────────────────────────────────────────────────────────

REDIS_URL={redis_url}



# ─────────────────────────────────────────────────────────

# AI Models Configuration

# ─────────────────────────────────────────────────────────



# Hugging Face Token (REQUIRED)

HUGGINGFACE_TOKEN={hf_token}

HF_TOKEN={hf_token}



# Device configuration

MUSICGEN_DEVICE={device}

BARK_DEVICE={device}

DEMUCS_DEVICE={device}



# Model versions

MUSICGEN_MODEL=facebook/musicgen-small

BARK_MODEL=suno/bark-small

DEMUCS_MODEL=htdemucs



# ─────────────────────────────────────────────────────────

# API Configuration

# ─────────────────────────────────────────────────────────

API_V1_PREFIX=/api/v1

ALLOWED_ORIGINS={allowed_origins}



# ─────────────────────────────────────────────────────────

# Audio Processing Settings

# ─────────────────────────────────────────────────────────

MAX_AUDIO_DURATION=300

DEFAULT_AUDIO_DURATION=30

AUDIO_SAMPLE_RATE=32000



# ─────────────────────────────────────────────────────────

# Feature Flags

# ─────────────────────────────────────────────────────────

ENABLE_VOCALS=true

ENABLE_MASTERING=true

ENABLE_STEM_SEPARATION=true



# ─────────────────────────────────────────────────────────

# Monitoring (Optional)

# ─────────────────────────────────────────────────────────

ENABLE_METRICS=true



# Sentry (uncomment and configure if needed)

# SENTRY_DSN=your-sentry-dsn

# SENTRY_ENVIRONMENT={environment}

"""
    
    # Write .env file
    env_file.write_text(env_content, encoding="utf-8")
    
    print("βœ… .env file created successfully!")
    print()
    print("=" * 60)
    print("πŸŽ‰ Setup Complete!")
    print("=" * 60)
    print()
    print(f"πŸ“ Configuration saved to: {env_file}")
    print()
    print("πŸ“‹ Next Steps:")
    print("  1. Review the .env file and adjust if needed")
    print("  2. Install dependencies: cd backend && pip install -e '.[dev]'")
    print("  3. Initialize database: python scripts/init_db.py")
    print("  4. Start the backend: uvicorn app.main:app --reload")
    print()
    print("πŸ€— Your Hugging Face token is configured!")
    print("   Models will download automatically on first use.")
    print()
    print("🐼⚑ Ready to forge some audio!")


if __name__ == "__main__":
    try:
        main()
    except KeyboardInterrupt:
        print("\n\n❌ Setup cancelled by user.")
        sys.exit(1)
    except Exception as e:
        print(f"\n\n❌ Error during setup: {e}")
        sys.exit(1)