100 lines
3.1 KiB
Python
100 lines
3.1 KiB
Python
import os
|
|
from datetime import timedelta
|
|
|
|
from flask import Flask
|
|
from flask_cors import CORS
|
|
from flask_jwt_extended import JWTManager
|
|
from flask_socketio import SocketIO
|
|
|
|
from app.database import init_db
|
|
from app.services.auth_service import AuthService
|
|
from app.services.scheduler_service import scheduler_service
|
|
|
|
# Global service instances
|
|
auth_service = AuthService()
|
|
socketio = SocketIO()
|
|
|
|
|
|
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"] = "/" # Allow access to all paths including SocketIO
|
|
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 SocketIO
|
|
socketio.init_app(
|
|
app,
|
|
cors_allowed_origins="http://localhost:3000",
|
|
cors_credentials=True,
|
|
)
|
|
|
|
# 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 SocketIO service (import after socketio is initialized)
|
|
from app.services.socketio_service import socketio_service # noqa: F401
|
|
|
|
# Initialize scheduler service with app
|
|
scheduler_service.app = app
|
|
|
|
# Start scheduler for background tasks
|
|
scheduler_service.start()
|
|
|
|
# Register blueprints
|
|
from app.routes import admin, admin_sounds, auth, main, soundboard
|
|
|
|
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")
|
|
app.register_blueprint(admin_sounds.bp)
|
|
app.register_blueprint(soundboard.bp)
|
|
|
|
# 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
|