This commit is contained in:
2025-10-03 11:34:48 -04:00
parent fb94750b46
commit a61970d298
3 changed files with 20 additions and 4 deletions

1
.gitignore vendored
View File

@@ -30,6 +30,7 @@ job_review.py
check_missing.py check_missing.py
**/auth/* **/auth/*
**/radio_api/* **/radio_api/*
**/test/*
test/db_stats.py test/db_stats.py
test/report/* test/report/*
.gitignore .gitignore

View File

@@ -4,7 +4,10 @@ A modern FastAPI-based backend providing various endpoints for media, authentica
## Overview ## Overview
This server is built with [FastAPI](https://fastapi.tiangolo.com/) and provides a comprehensive API for multiple services. The interactive API documentation is available at the [Swagger UI](https://api.codey.lol/docs). This server is built with [FastAPI](https://fastapi.tiangolo.com/) and provides a comprehensive API for multiple services. API documentation is available in three formats:
- **Swagger UI**: [https://api.codey.lol/docs](https://api.codey.lol/docs) - Classic interactive API explorer with "Try it out" functionality
- **Scalar**: [https://api.codey.lol/scalar](https://api.codey.lol/scalar) - Modern, fast interactive API documentation (recommended)
- **ReDoc**: [https://api.codey.lol/redoc](https://api.codey.lol/redoc) - Clean, read-only documentation with better visual design
## API Endpoints ## API Endpoints

16
base.py
View File

@@ -7,6 +7,7 @@ import asyncio
from typing import Any from typing import Any
from fastapi import FastAPI, Request from fastapi import FastAPI, Request
from fastapi.middleware.cors import CORSMiddleware from fastapi.middleware.cors import CORSMiddleware
from scalar_fastapi import get_scalar_api_reference
from lyric_search.sources import redis_cache from lyric_search.sources import redis_cache
logging.basicConfig(level=logging.INFO) logging.basicConfig(level=logging.INFO)
@@ -21,6 +22,8 @@ app = FastAPI(
contact={"name": "codey"}, contact={"name": "codey"},
redirect_slashes=False, redirect_slashes=False,
loop=loop, loop=loop,
docs_url="/docs", # Swagger UI (default)
redoc_url="/redoc", # ReDoc UI (default, but explicitly set)
) )
constants = importlib.import_module("constants").Constants() constants = importlib.import_module("constants").Constants()
@@ -43,6 +46,13 @@ app.add_middleware(
allow_headers=["*"], allow_headers=["*"],
) # type: ignore ) # type: ignore
# Add Scalar API documentation endpoint (before blacklist routes)
@app.get("/scalar", include_in_schema=False)
def scalar_docs():
return get_scalar_api_reference(
openapi_url="/openapi.json",
title="codey.lol API"
)
""" """
Blacklisted routes Blacklisted routes
@@ -62,10 +72,13 @@ def base_head():
@app.get("/{path}", include_in_schema=False) @app.get("/{path}", include_in_schema=False)
def disallow_get_any(request: Request, var: Any = None): def disallow_get_any(request: Request, var: Any = None):
path = request.path_params["path"] path = request.path_params["path"]
allowed_paths = ["widget", "misc/no", "docs", "redoc", "scalar", "openapi.json"]
logging.info(f"Checking path: {path}, allowed: {path in allowed_paths or path.split('/', maxsplit=1)[0] in allowed_paths}")
if not ( if not (
isinstance(path, str) isinstance(path, str)
and (path.split("/", maxsplit=1) == "widget" or path == "misc/no") and (path.split("/", maxsplit=1)[0] in allowed_paths or path in allowed_paths)
): ):
logging.error(f"BLOCKED path: {path}")
return util.get_blocked_response() return util.get_blocked_response()
else: else:
logging.info("OK, %s", path) logging.info("OK, %s", path)
@@ -117,7 +130,6 @@ if radio_endpoint:
End Actionable Routes End Actionable Routes
""" """
""" """
Startup Startup
""" """