arxplorer / src /controller /source.py
Subhadeep Mandal
Fresh deploy
54eb2ce
Raw
History Blame Contribute Delete
4.29 kB
from sqlalchemy import select
from sqlalchemy.exc import SQLAlchemyError, DBAPIError
from fastapi import HTTPException
from typing import List
from ..database.db import session_pool
from ..errors import DatabaseConnectionError
from ..model.source import Source
from ..schema.source import SourceCreate, SourceResponse
from ..core.logger import SingletonLogger
logger = SingletonLogger().get_logger()
async def create_sources(sources: List[SourceCreate]) -> List[SourceResponse]:
"""Create multiple sources for a message in bulk."""
if not sources:
return []
try:
async with session_pool() as session:
source_objects = [
Source(
message_id=source.message_id,
source_text=source.source_text,
source_type=source.source_type,
source_url=source.source_url,
source_metadata=source.metadata,
)
for source in sources
]
session.add_all(source_objects)
await session.flush() # Flush to get IDs
# Get IDs of created sources to re-query them
source_ids = [source_obj.id for source_obj in source_objects]
await session.commit()
# Re-query sources from database to ensure all fields are properly loaded
result = await session.execute(
select(Source).where(Source.id.in_(source_ids))
)
persisted_sources = result.scalars().all()
return [
SourceResponse(
id=source.id,
message_id=source.message_id,
source_text=source.source_text,
source_type=source.source_type,
source_url=source.source_url,
metadata=source.source_metadata,
created_at=source.created_at,
updated_at=source.updated_at,
)
for source in persisted_sources
]
except DBAPIError as e:
logger.exception(f"Database connection error creating sources: {str(e)}")
raise DatabaseConnectionError(str(e))
except SQLAlchemyError as e:
logger.error(f"Database error creating sources: {str(e)}")
raise HTTPException(status_code=500, detail="Failed to create sources")
except Exception as e:
logger.error(f"Unexpected error creating sources: {str(e)}")
raise HTTPException(status_code=500, detail="Internal server error")
async def get_sources_by_message(message_id: int) -> List[SourceResponse]:
"""Retrieve all sources for a specific message."""
try:
async with session_pool() as session:
result = await session.execute(
select(Source)
.where(Source.message_id == message_id)
.order_by(Source.created_at)
)
sources = result.scalars().all()
return [
SourceResponse(
id=source.id,
message_id=source.message_id,
source_text=source.source_text,
source_type=source.source_type,
source_url=source.source_url,
metadata=source.source_metadata,
created_at=source.created_at,
updated_at=source.updated_at,
)
for source in sources
]
except DBAPIError as e:
logger.exception(
f"Database connection error retrieving sources for message_id={message_id}: {str(e)}"
)
raise DatabaseConnectionError(str(e))
except SQLAlchemyError as e:
logger.error(
f"Database error retrieving sources for message_id={message_id}: {str(e)}"
)
raise HTTPException(status_code=500, detail="Failed to retrieve sources")
except Exception as e:
logger.error(
f"Unexpected error retrieving sources for message_id={message_id}: {str(e)}"
)
raise HTTPException(status_code=500, detail="Internal server error")