service base

This commit is contained in:
John Lancaster
2026-06-27 10:38:17 -05:00
parent 96cbadd56e
commit e75ca4c79a
3 changed files with 40 additions and 18 deletions
+26
View File
@@ -0,0 +1,26 @@
import asyncio
from abc import ABC
from sqlalchemy.ext.asyncio import async_sessionmaker
from sqlmodel.ext.asyncio.session import AsyncSession
from ..config import Settings
from ..config import get_settings
from ..db.runtime import get_session_factory
class ServiceBase(ABC):
"""Thin service class for managing documents in the database."""
settings: Settings
session_factory: async_sessionmaker[AsyncSession]
queue: asyncio.Queue
def __init__(
self,
session_factory: async_sessionmaker[AsyncSession] | None = None,
queue: asyncio.Queue | None = None,
):
self.settings = get_settings()
self.session_factory = session_factory or get_session_factory()
self.queue = queue or asyncio.Queue()
+12 -9
View File
@@ -1,23 +1,22 @@
from collections.abc import Sequence from collections.abc import Sequence
from pathlib import Path
from uuid import UUID from uuid import UUID
from sqlalchemy.ext.asyncio import async_sessionmaker
from sqlalchemy.orm import selectinload from sqlalchemy.orm import selectinload
from sqlmodel import select from sqlmodel import select
from sqlmodel.ext.asyncio.session import AsyncSession
from ..db.runtime import get_session_factory from ..errors import AppError
from ..models import Document from ..models import Document
from .base import ServiceBase
class DocumentService: class MissingImageError(AppError):
"""Raised when a required image is missing."""
class DocumentService(ServiceBase):
"""Thin service class for managing documents in the database.""" """Thin service class for managing documents in the database."""
session_factory: async_sessionmaker[AsyncSession]
def __init__(self, session_factory: async_sessionmaker[AsyncSession] | None = None):
self.session_factory = session_factory or get_session_factory()
async def create_document(self, document: Document) -> Document: async def create_document(self, document: Document) -> Document:
"""Create a new document in the database.""" """Create a new document in the database."""
async with self.session_factory() as session: async with self.session_factory() as session:
@@ -39,6 +38,10 @@ class DocumentService:
) )
if document is None: if document is None:
raise ValueError(f"Document with id {document_id} not found") raise ValueError(f"Document with id {document_id} not found")
elif not Path(document.file_path).exists():
raise MissingImageError(
f"Document with id {document_id} is missing its image file in {self.settings.upload_dir:!s}"
)
return document return document
async def update_document(self, document: Document) -> Document: async def update_document(self, document: Document) -> Document:
+2 -9
View File
@@ -1,24 +1,17 @@
from collections.abc import Sequence from collections.abc import Sequence
from uuid import UUID from uuid import UUID
from sqlalchemy.ext.asyncio import async_sessionmaker
from sqlalchemy.orm import selectinload from sqlalchemy.orm import selectinload
from sqlmodel import select from sqlmodel import select
from sqlmodel.ext.asyncio.session import AsyncSession
from ..db.runtime import get_session_factory
from ..models import Job from ..models import Job
from ..models import JobStatus from ..models import JobStatus
from .base import ServiceBase
class JobService: class JobService(ServiceBase):
"""Thin service class for managing jobs in the database.""" """Thin service class for managing jobs in the database."""
session_factory: async_sessionmaker[AsyncSession]
def __init__(self, session_factory: async_sessionmaker[AsyncSession] | None = None):
self.session_factory = session_factory or get_session_factory()
async def create_job(self, job: Job) -> Job: async def create_job(self, job: Job) -> Job:
"""Create a new job in the database.""" """Create a new job in the database."""
async with self.session_factory() as session: async with self.session_factory() as session: