converted addmin.py and page.py to DbSession and AppConfig

This commit is contained in:
2026-06-15 22:01:42 -04:00
parent 0c9583c1cc
commit 4640ebf8ce
2 changed files with 39 additions and 44 deletions
+25 -29
View File
@@ -6,12 +6,13 @@ import logging
from fastapi import APIRouter, Request from fastapi import APIRouter, Request
from fastapi.responses import HTMLResponse from fastapi.responses import HTMLResponse
from sqlalchemy.orm import Session
from python.ebook_search.api.bm25_tasks import schedule_bm25_refresh from python.ebook_search.api.bm25_tasks import schedule_bm25_refresh
from python.ebook_search.api.dependencies import AppConfig
from python.ebook_search.api.web import templates from python.ebook_search.api.web import templates
from python.ebook_search.embeddings import embed_missing_chunks, embedding_model_stats from python.ebook_search.embeddings import embed_missing_chunks, embedding_model_stats
from python.ebook_search.ingest import ingest_configured_paths from python.ebook_search.ingest import ingest_configured_paths
from python.fastapi_tools import DbSession
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -19,21 +20,19 @@ router = APIRouter(prefix="/admin")
@router.get("", response_class=HTMLResponse) @router.get("", response_class=HTMLResponse)
def admin(request: Request) -> HTMLResponse: def admin(request: Request, config: AppConfig, session: DbSession) -> HTMLResponse:
"""Render the admin page.""" """Render the admin page."""
with Session(request.app.state.engine) as session: stats = embedding_model_stats(session)
stats = embedding_model_stats(session)
logger.info("ebook_admin_page_loaded models=%s", len(stats)) logger.info("ebook_admin_page_loaded models=%s", len(stats))
return templates.TemplateResponse(request, "admin.html", {"config": request.app.state.config, "stats": stats}) return templates.TemplateResponse(request, "admin.html", {"config": config, "stats": stats})
@router.post("/scan", response_class=HTMLResponse) @router.post("/scan", response_class=HTMLResponse)
def scan_library(request: Request) -> HTMLResponse: def scan_library(request: Request, config: AppConfig, session: DbSession) -> HTMLResponse:
"""Scan configured library paths for EPUB changes.""" """Scan configured library paths for EPUB changes."""
try: try:
with Session(request.app.state.engine) as session: count = ingest_configured_paths(session, config)
count = ingest_configured_paths(session, request.app.state.config) session.commit()
session.commit()
except Exception as error: except Exception as error:
logger.exception("ebook_admin_scan_failed") logger.exception("ebook_admin_scan_failed")
return templates.TemplateResponse(request, "partials/error.html", {"message": str(error)}, status_code=500) return templates.TemplateResponse(request, "partials/error.html", {"message": str(error)}, status_code=500)
@@ -45,12 +44,11 @@ def scan_library(request: Request) -> HTMLResponse:
@router.post("/embed-missing", response_class=HTMLResponse) @router.post("/embed-missing", response_class=HTMLResponse)
def embed_missing(request: Request) -> HTMLResponse: def embed_missing(request: Request, config: AppConfig, session: DbSession) -> HTMLResponse:
"""Embed chunks missing vectors for the configured model.""" """Embed chunks missing vectors for the configured model."""
try: try:
with Session(request.app.state.engine) as session: count = embed_missing_chunks(session, config)
count = embed_missing_chunks(session, request.app.state.config) session.commit()
session.commit()
except Exception as error: except Exception as error:
logger.exception("ebook_admin_embed_missing_failed") logger.exception("ebook_admin_embed_missing_failed")
return templates.TemplateResponse(request, "partials/error.html", {"message": str(error)}, status_code=500) return templates.TemplateResponse(request, "partials/error.html", {"message": str(error)}, status_code=500)
@@ -64,26 +62,24 @@ def embed_missing(request: Request) -> HTMLResponse:
@router.post("/embed-all", response_class=HTMLResponse) @router.post("/embed-all", response_class=HTMLResponse)
def embed_all(request: Request) -> HTMLResponse: def embed_all(request: Request, config: AppConfig, session: DbSession) -> HTMLResponse:
"""Embed all chunks missing vectors in fixed-size batches.""" """Embed all chunks missing vectors in fixed-size batches."""
total = 0 total = 0
batches = 0 batches = 0
config = request.app.state.config
try: try:
with Session(request.app.state.engine) as session: while True:
while True: count = embed_missing_chunks(session, config)
count = embed_missing_chunks(session, config) if count == 0:
if count == 0: break
break session.commit()
session.commit() total += count
total += count batches += 1
batches += 1 logger.info(
logger.info( "ebook_admin_embed_all_batch_complete batch=%s chunks=%s total_chunks=%s",
"ebook_admin_embed_all_batch_complete batch=%s chunks=%s total_chunks=%s", batches,
batches, count,
count, total,
total, )
)
except Exception as error: except Exception as error:
logger.exception( logger.exception(
"ebook_admin_embed_all_failed batches=%s chunks=%s", "ebook_admin_embed_all_failed batches=%s chunks=%s",
+14 -15
View File
@@ -7,9 +7,10 @@ import logging
from fastapi import APIRouter, Request from fastapi import APIRouter, Request
from fastapi.responses import HTMLResponse from fastapi.responses import HTMLResponse
from sqlalchemy import select from sqlalchemy import select
from sqlalchemy.orm import Session
from python.ebook_search.api.dependencies import AppConfig
from python.ebook_search.api.web import templates from python.ebook_search.api.web import templates
from python.fastapi_tools import DbSession
from python.orm.richie import EbookSource from python.orm.richie import EbookSource
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -18,31 +19,29 @@ router = APIRouter()
@router.get("/", response_class=HTMLResponse) @router.get("/", response_class=HTMLResponse)
def index(request: Request) -> HTMLResponse: def index(request: Request, config: AppConfig) -> HTMLResponse:
"""Render the search page.""" """Render the search page."""
return templates.TemplateResponse(request, "search.html", {"config": request.app.state.config}) return templates.TemplateResponse(request, "search.html", {"config": config})
@router.get("/books", response_class=HTMLResponse) @router.get("/books", response_class=HTMLResponse)
def books(request: Request) -> HTMLResponse: def books(request: Request, session: DbSession) -> HTMLResponse:
"""Render the indexed books page.""" """Render the indexed books page."""
with Session(request.app.state.engine) as session: sources = list(session.scalars(select(EbookSource).order_by(EbookSource.title)).all())
sources = list(session.scalars(select(EbookSource).order_by(EbookSource.title)).all())
logger.info("ebook_books_page_loaded count=%s", len(sources)) logger.info("ebook_books_page_loaded count=%s", len(sources))
return templates.TemplateResponse(request, "books.html", {"sources": sources}) return templates.TemplateResponse(request, "books.html", {"sources": sources})
@router.get("/books/{source_id}", response_class=HTMLResponse) @router.get("/books/{source_id}", response_class=HTMLResponse)
def book_detail(source_id: int, request: Request) -> HTMLResponse: def book_detail(source_id: int, request: Request, session: DbSession) -> HTMLResponse:
"""Render details for one indexed book.""" """Render details for one indexed book."""
with Session(request.app.state.engine) as session: source = session.get(EbookSource, source_id)
source = session.get(EbookSource, source_id) if source is not None:
if source is not None: chapter_count = len(source.chapters)
chapter_count = len(source.chapters) chunk_count = len(source.chunks)
chunk_count = len(source.chunks) else:
else: chapter_count = 0
chapter_count = 0 chunk_count = 0
chunk_count = 0
logger.info( logger.info(
"ebook_book_detail_loaded source_id=%s found=%s chapters=%s chunks=%s", "ebook_book_detail_loaded source_id=%s found=%s chapters=%s chunks=%s",
source_id, source_id,