docs: Added misc comments

This commit is contained in:
2026-06-29 17:52:25 +05:30
parent 40881b4773
commit 2e556173d4
4 changed files with 30 additions and 0 deletions

View File

@@ -13,6 +13,10 @@ async def upload_csv(
file: UploadFile = File(...),
service: JobService = Depends(get_job_service),
):
"""
Accepts a CSV file upload. Validates it, creates a job record in the database
with status=pending, enqueues the processing task, and returns the job_id immediately.
"""
if not file.filename.endswith(".csv"):
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
@@ -35,6 +39,10 @@ async def get_job_status(
job_id: str,
service: JobService = Depends(get_job_service),
):
"""
Returns the current status of the job: pending, processing, completed, or failed.
If completed, also includes a summary field with high-level stats.
"""
try:
job = await service.get_job_status(job_id)
return job
@@ -50,6 +58,10 @@ async def get_job_result(
job_id: str,
service: JobService = Depends(get_job_service),
):
"""
Returns the full structured output: cleaned transactions list, flagged anomalies,
per-category spend breakdown, and the LLM-generated narrative summary.
"""
try:
job = await service.get_job_results(job_id)
return job
@@ -65,4 +77,8 @@ async def get_all_jobs(
status: Optional[str] = Query(None, description="Filter jobs by status"),
service: JobService = Depends(get_job_service),
):
"""
Lists all jobs with their status, filename, row count, and created_at timestamp.
Supports filtering via ?status= query parameter.
"""
return await service.list_jobs(status=status)

View File

@@ -33,6 +33,7 @@ class Job(Base):
onupdate=func.now(),
nullable=False,
)
# JSON summaries and results
summary: Mapped[Optional[Dict[str, Any]]] = mapped_column(
JSON,
nullable=True,

View File

@@ -2,6 +2,7 @@ from typing import AsyncGenerator
from sqlalchemy.ext.asyncio import create_async_engine, async_sessionmaker, AsyncSession
from app.core.config import settings
# Create async database engine
engine = create_async_engine(
settings.DATABASE_URL,
echo=False,
@@ -10,6 +11,7 @@ engine = create_async_engine(
max_overflow=20,
)
# Async session factory
AsyncSessionLocal = async_sessionmaker(
bind=engine,
class_=AsyncSession,
@@ -18,6 +20,7 @@ AsyncSessionLocal = async_sessionmaker(
async def get_db() -> AsyncGenerator[AsyncSession, None]:
"""Dependency for obtaining an asynchronous database session"""
async with AsyncSessionLocal() as session:
try:
yield session

View File

@@ -9,16 +9,21 @@ from app.db.session import engine
@asynccontextmanager
async def lifespan(app: FastAPI):
# Startup: Create tables if they don't exist
async with engine.begin() as conn:
await conn.run_sync(Base.metadata.create_all)
yield
# Shutdown: Clean up pool
await engine.dispose()
app = FastAPI(
title=settings.PROJECT_NAME,
openapi_url=f"{settings.API_V1_STR}/openapi.json",
lifespan=lifespan,
)
# CORS Middleware
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
@@ -26,7 +31,12 @@ app.add_middleware(
allow_methods=["*"],
allow_headers=["*"],
)
# Include API Router
app.include_router(jobs_router, prefix=settings.API_V1_STR)
# Root healthcheck endpoint
@app.get("/health", tags=["health"])
def health_check():
return {"status": "ok", "project": settings.PROJECT_NAME}