document-processor/app/routes/ingest.py

211 lines
6.7 KiB
Python

from pathlib import Path
from fastapi import APIRouter, Depends, File, Form, Request, UploadFile
from fastapi.responses import HTMLResponse, RedirectResponse
from fastapi.templating import Jinja2Templates
from sqlalchemy.orm import Session
from app.core.ingest_settings import browse_directory, get_default_ingest_root, reset_default_ingest_root, set_default_ingest_root
from app.db.deps import get_db
from app.logic.ingest import ingest_directory, ingest_file, ingest_inbox, ingest_uploaded_file
router = APIRouter(prefix="/ingest", tags=["ingest"])
BASE_DIR = Path(__file__).resolve().parent.parent
templates = Jinja2Templates(directory=str(BASE_DIR / "templates"))
@router.get("/", response_class=HTMLResponse)
def ingest_home(request: Request, browse_path: str = ""):
default_ingest_root = get_default_ingest_root()
current_browse_path = browse_path.strip() or default_ingest_root
browser = browse_directory(current_browse_path)
return templates.TemplateResponse(
request=request,
name="ingest/index.html",
context={
"request": request,
"default_ingest_root": default_ingest_root,
"current_browse_path": current_browse_path,
"browser": browser,
"active_page": "ingest",
},
)
@router.post("/set-default-root", response_class=RedirectResponse)
def set_default_root(directory_path: str = Form("")):
chosen = Path(directory_path).expanduser().resolve()
if chosen.exists() and chosen.is_dir():
saved = set_default_ingest_root(str(chosen))
return RedirectResponse(url=f"/ingest/?browse_path={saved}", status_code=303)
fallback = get_default_ingest_root()
return RedirectResponse(url=f"/ingest/?browse_path={fallback}", status_code=303)
@router.post("/reset-default-root", response_class=RedirectResponse)
def reset_default_root():
saved = reset_default_ingest_root()
return RedirectResponse(url=f"/ingest/?browse_path={saved}", status_code=303)
@router.post("/upload-files", response_class=HTMLResponse)
async def ingest_upload_files(
request: Request,
uploaded_files: list[UploadFile] = File(...),
db: Session = Depends(get_db),
):
documents = []
errors = []
for uploaded_file in uploaded_files:
try:
file_bytes = await uploaded_file.read()
document = ingest_uploaded_file(
db=db,
filename=uploaded_file.filename or "upload.pdf",
file_bytes=file_bytes,
source_system="upload_ingest",
)
documents.append(document)
except Exception as e:
errors.append(f"{uploaded_file.filename}: {e}")
if errors and not documents:
return templates.TemplateResponse(
request=request,
name="ingest/result.html",
context={
"request": request,
"message": "Upload failed.",
"documents": [],
"errors": errors,
},
status_code=400,
)
message = f"Ingested {len(documents)} uploaded file(s)."
if errors:
message += f" {len(errors)} file(s) had errors."
return templates.TemplateResponse(
request=request,
name="ingest/result.html",
context={
"request": request,
"message": message,
"documents": documents,
"errors": errors,
},
)
@router.post("/server-file", response_class=HTMLResponse)
def ingest_server_file(
request: Request,
file_path: str = Form(...),
db: Session = Depends(get_db),
):
try:
document = ingest_file(
db=db,
file_path=file_path,
source_system="server_file_ingest",
)
return templates.TemplateResponse(
request=request,
name="ingest/result.html",
context={
"request": request,
"message": f"Ingested server file successfully: {document.document_id}",
"documents": [document],
"errors": [],
},
)
except Exception as e:
return templates.TemplateResponse(
request=request,
name="ingest/result.html",
context={
"request": request,
"message": f"Error ingesting server file: {e}",
"documents": [],
"errors": [],
},
status_code=400,
)
@router.post("/server-directory", response_class=HTMLResponse)
def ingest_server_directory(
request: Request,
directory_path: str = Form(...),
recursive: str | None = Form(None),
db: Session = Depends(get_db),
):
try:
docs = ingest_directory(
db=db,
directory_path=directory_path,
recursive=recursive is not None,
source_system="server_directory_ingest",
)
return templates.TemplateResponse(
request=request,
name="ingest/result.html",
context={
"request": request,
"message": f"Ingested {len(docs)} file(s) from server directory.",
"documents": docs,
"errors": [],
},
)
except Exception as e:
return templates.TemplateResponse(
request=request,
name="ingest/result.html",
context={
"request": request,
"message": f"Error ingesting server directory: {e}",
"documents": [],
"errors": [],
},
status_code=400,
)
@router.post("/inbox", response_class=HTMLResponse)
def ingest_inbox_route(request: Request, db: Session = Depends(get_db)):
default_ingest_root = get_default_ingest_root()
try:
docs = ingest_directory(
db=db,
directory_path=default_ingest_root,
recursive=False,
source_system="default_root_ingest",
)
return templates.TemplateResponse(
request=request,
name="ingest/result.html",
context={
"request": request,
"message": f"Ingested {len(docs)} file(s) from default ingest root: {default_ingest_root}",
"documents": docs,
"errors": [],
},
)
except Exception as e:
return templates.TemplateResponse(
request=request,
name="ingest/result.html",
context={
"request": request,
"message": f"Error ingesting default ingest root ({default_ingest_root}): {e}",
"documents": [],
"errors": [],
},
status_code=400,
)