Expose Jellyfin library and index controls over API

This commit is contained in:
Sleeps
2026-10-06 17:55:52 +01:00
parent 24d05a9bc0
commit 20b153df00
+59
View File
@@ -5,9 +5,11 @@ from pathlib import Path
from fastapi import Depends, FastAPI, Header, HTTPException, Query
from fastapi.responses import FileResponse
from pydantic import BaseModel, Field
from .config import settings
from .database import connect, init_db
from .index_jobs import IndexJobManager
from .search_service import SearchService
app = FastAPI(
@@ -16,6 +18,12 @@ app = FastAPI(
)
_service: SearchService | None = None
_index_jobs: IndexJobManager | None = None
class IndexRequest(BaseModel):
library_ids: list[str] = Field(min_length=1)
force: bool = False
def get_search_service() -> SearchService:
@@ -33,6 +41,13 @@ def get_search_service() -> SearchService:
return _service
def get_index_jobs() -> IndexJobManager:
global _index_jobs
if _index_jobs is None:
_index_jobs = IndexJobManager(get_search_service())
return _index_jobs
def require_api_key(
authorization: str | None = Header(default=None),
x_scene_search_key: str | None = Header(default=None),
@@ -60,6 +75,12 @@ def search(
scene_limit: int = Query(default=50, ge=1, le=100),
item_limit: int = Query(default=20, ge=1, le=50),
) -> dict:
if get_index_jobs().running:
raise HTTPException(
status_code=503,
detail="Jellyfin indexing is currently using the embedding model",
)
try:
return get_search_service().search(
q,
@@ -73,6 +94,44 @@ def search(
raise HTTPException(status_code=503, detail=str(exc)) from exc
@app.get(
"/api/jellyfin/libraries",
dependencies=[Depends(require_api_key)],
)
def jellyfin_libraries() -> dict:
try:
return {"libraries": get_index_jobs().libraries()}
except Exception as exc:
raise HTTPException(status_code=503, detail=str(exc)) from exc
@app.post(
"/api/jellyfin/index",
dependencies=[Depends(require_api_key)],
status_code=202,
)
def jellyfin_index(request: IndexRequest) -> dict:
try:
return get_index_jobs().start(
request.library_ids,
force=request.force,
)
except RuntimeError as exc:
message = str(exc)
status = 409 if "already running" in message else 400
raise HTTPException(status_code=status, detail=message) from exc
except Exception as exc:
raise HTTPException(status_code=503, detail=str(exc)) from exc
@app.get(
"/api/jellyfin/index/status",
dependencies=[Depends(require_api_key)],
)
def jellyfin_index_status() -> dict:
return get_index_jobs().status()
@app.get(
"/api/frames/{frame_id}/thumbnail",
dependencies=[Depends(require_api_key)],