Files
sdb-back/app/__init__.py

128 lines
4.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_COOKIE_SAMESITE"] = "Lax" # Allow cross-origin requests
app.config["JWT_ACCESS_COOKIE_PATH"] = "/api/" # Restrict to API paths only
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,
path="/api/socket.io/", # Use /api prefix for Socket.IO
)
# 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()
# Initialize stream processing service
from app.services.stream_processing_service import StreamProcessingService
StreamProcessingService.initialize(app)
# Initialize music player service
from app.services.music_player_service import music_player_service
music_player_service.app = app # Store app instance for Flask context
music_player_service.start_vlc_instance()
# Register blueprints
from app.routes import (
admin,
admin_sounds,
auth,
main,
player,
referential,
soundboard,
sounds,
stream,
)
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, url_prefix="/api/admin/sounds")
app.register_blueprint(referential.bp, url_prefix="/api/referential")
app.register_blueprint(soundboard.bp, url_prefix="/api/soundboard")
app.register_blueprint(sounds.bp, url_prefix="/api/sounds")
app.register_blueprint(stream.bp, url_prefix="/api/stream")
app.register_blueprint(player.bp, url_prefix="/api/player")
# Shutdown services when app is torn down
@app.teardown_appcontext
def shutdown_services(exception):
"""Stop services when app context is torn down."""
if exception:
scheduler_service.stop()
# music_player_service.stop_vlc_instance()
return app