MyPal / app /services /documents.py
KhaledSalehKL1's picture
Deploy 9XAIPal: Gradio+FastAPI app, backend, React build
1086e43 verified
Raw
History Blame Contribute Delete
1.86 kB
"""Document service: lifecycle operations."""
import shutil
from uuid import UUID
from pathlib import Path
from typing import Optional
from sqlalchemy.ext.asyncio import AsyncSession
from app.core.paths import documents_dir
from app.database.repositories import documents as doc_repo
async def create_document(
session: AsyncSession,
*,
filename: str,
original_filename: str,
file_size_bytes: Optional[int] = None,
doc_kind: str = "paper",
) -> dict:
"""Create a document record."""
return await doc_repo.create_document(
session,
filename=filename,
original_filename=original_filename,
file_size_bytes=file_size_bytes,
doc_kind=doc_kind,
)
async def get_document(session: AsyncSession, document_id: UUID) -> Optional[dict]:
"""Get a document by ID."""
return await doc_repo.get_document(session, document_id)
async def list_documents(session: AsyncSession, limit: int = 50, offset: int = 0) -> list[dict]:
"""List all documents."""
return await doc_repo.list_documents(session, limit=limit, offset=offset)
async def count_documents(session: AsyncSession) -> int:
"""Total number of documents in the library (across all pages)."""
return await doc_repo.count_documents(session)
async def delete_document(session: AsyncSession, document_id: UUID) -> Optional[dict]:
"""Delete a document row (cascades to chunks, embeddings, assets, turns).
Returns the deleted document's metadata so the caller can clean up
on-disk artefacts (raw PDFs, MinerU output, extracted images). Returns
``None`` if the document does not exist.
"""
doc = await doc_repo.get_document(session, document_id)
if not doc:
return None
deleted = await doc_repo.delete_document(session, document_id)
return doc if deleted else None