import os from datetime import timedelta from flask import Flask from flask_cors import CORS from flask_jwt_extended import JWTManager from app.database import init_db from app.services.auth_service import AuthService from app.services.scheduler_service import scheduler_service # Global auth service instance auth_service = AuthService() def create_app(): """Create and configure the Flask application.""" app = Flask(__name__) # Configure Flask secret key (required for sessions used by OAuth) app.config["SECRET_KEY"] = os.environ.get("SECRET_KEY", "dev-secret-key") # Configure SQLAlchemy database database_url = os.environ.get("DATABASE_URL", "sqlite:///soundboard.db") app.config["SQLALCHEMY_DATABASE_URI"] = database_url app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False # Configure Flask-JWT-Extended app.config["JWT_SECRET_KEY"] = os.environ.get( "JWT_SECRET_KEY", "jwt-secret-key", ) app.config["JWT_ACCESS_TOKEN_EXPIRES"] = timedelta(minutes=15) app.config["JWT_REFRESH_TOKEN_EXPIRES"] = timedelta(days=7) app.config["JWT_TOKEN_LOCATION"] = ["cookies"] app.config["JWT_COOKIE_SECURE"] = False # Set to True in production app.config["JWT_COOKIE_CSRF_PROTECT"] = False app.config["JWT_ACCESS_COOKIE_PATH"] = "/api/" app.config["JWT_REFRESH_COOKIE_PATH"] = "/api/auth/refresh" # Initialize CORS CORS( app, origins=["http://localhost:3000"], # Frontend URL supports_credentials=True, # Allow cookies allow_headers=["Content-Type", "Authorization"], methods=["GET", "POST", "PATCH", "PUT", "DELETE", "OPTIONS"], ) # Initialize JWT manager jwt = JWTManager(app) # Initialize database init_db(app) # Initialize database tables and seed data with app.app_context(): from app.database_init import init_database init_database() # Initialize authentication service with app auth_service.init_app(app) # Initialize scheduler service with app scheduler_service.app = app # Start scheduler for background tasks scheduler_service.start() # Register blueprints from app.routes import admin, auth, main app.register_blueprint(main.bp, url_prefix="/api") app.register_blueprint(auth.bp, url_prefix="/api/auth") app.register_blueprint(admin.bp, url_prefix="/api/admin") # Shutdown scheduler when app is torn down @app.teardown_appcontext def shutdown_scheduler(exception): """Stop scheduler when app context is torn down.""" if exception: scheduler_service.stop() return app