mirror of
https://github.com/sortedcord/alemno-payments.git
synced 2026-07-22 04:02:49 +05:30
docs: Added misc comments
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
10
app/main.py
10
app/main.py
@@ -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}
|
||||
|
||||
Reference in New Issue
Block a user