mirror of https://github.com/Nezreka/SoulSync.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
86 lines
2.8 KiB
86 lines
2.8 KiB
"""
|
|
SoulSync Public REST API (v1)
|
|
|
|
Blueprint factory + rate-limiter initialisation.
|
|
"""
|
|
|
|
from flask import Blueprint
|
|
from flask_limiter import Limiter
|
|
from flask_limiter.util import get_remote_address
|
|
|
|
from utils.logging_config import get_logger
|
|
from .helpers import api_error
|
|
|
|
logger = get_logger("api_v1")
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Rate limiter (initialised with the app in web_server.py via limiter.init_app)
|
|
# ---------------------------------------------------------------------------
|
|
limiter = Limiter(
|
|
key_func=get_remote_address,
|
|
default_limits=[], # No global default — limits are applied per-blueprint
|
|
storage_uri="memory://",
|
|
)
|
|
|
|
|
|
def create_api_blueprint():
|
|
"""Build and return the /api/v1 Blueprint with all sub-modules registered."""
|
|
|
|
bp = Blueprint("api_v1", __name__)
|
|
|
|
# ---- import & register sub-module routes ----
|
|
from .library import register_routes as reg_library
|
|
from .system import register_routes as reg_system
|
|
from .search import register_routes as reg_search
|
|
from .wishlist import register_routes as reg_wishlist
|
|
from .watchlist import register_routes as reg_watchlist
|
|
from .downloads import register_routes as reg_downloads
|
|
from .playlists import register_routes as reg_playlists
|
|
from .settings import register_routes as reg_settings
|
|
from .discover import register_routes as reg_discover
|
|
from .profiles import register_routes as reg_profiles
|
|
from .retag import register_routes as reg_retag
|
|
from .listenbrainz import register_routes as reg_listenbrainz
|
|
from .cache import register_routes as reg_cache
|
|
|
|
# ---- rate-limit only /api/v1 routes (not the whole app) ----
|
|
limiter.limit("60 per minute")(bp)
|
|
|
|
reg_library(bp)
|
|
reg_system(bp)
|
|
reg_search(bp)
|
|
reg_wishlist(bp)
|
|
reg_watchlist(bp)
|
|
reg_downloads(bp)
|
|
reg_playlists(bp)
|
|
reg_settings(bp)
|
|
reg_discover(bp)
|
|
reg_profiles(bp)
|
|
reg_retag(bp)
|
|
reg_listenbrainz(bp)
|
|
reg_cache(bp)
|
|
|
|
# ---- error handlers (scoped to this Blueprint) ----
|
|
@bp.errorhandler(400)
|
|
def _bad_request(e):
|
|
return api_error("BAD_REQUEST", str(e), 400)
|
|
|
|
@bp.errorhandler(404)
|
|
def _not_found(e):
|
|
return api_error("NOT_FOUND", "Resource not found.", 404)
|
|
|
|
@bp.errorhandler(429)
|
|
def _rate_limited(e):
|
|
return api_error("RATE_LIMITED", "Too many requests. Please slow down.", 429)
|
|
|
|
@bp.errorhandler(500)
|
|
def _internal(e):
|
|
return api_error("INTERNAL_ERROR", "An internal server error occurred.", 500)
|
|
|
|
@bp.errorhandler(Exception)
|
|
def _unhandled(e):
|
|
logger.error(f"Unhandled API error: {e}", exc_info=True)
|
|
return api_error("INTERNAL_ERROR", "An unexpected error occurred.", 500)
|
|
|
|
return bp
|