rtm-class-ai / src /api /lkpd_routes.py
nbintang
initialize projects
62516b8
Raw
History Blame Contribute Delete
2.67 kB
from __future__ import annotations
from fastapi import APIRouter, Depends, File, Form, Request, UploadFile
from fastapi.responses import FileResponse
from src.agent.jobs import MaterialJobStore
from src.agent.lkpd_storage import LkpdFileStorage
from src.agent.types import LkpdAsyncSubmitRequest
from src.auth import require_jwt
from src.config import settings
from src.core.api_response import ApiSuccessResponse
from src.core.exceptions import ServiceError
from src.api.job_submission import (
build_job_accepted_response,
enqueue_uploaded_job,
validate_submit_request,
)
from src.api.schemas import JobAcceptedData
def build_lkpd_router(job_store: MaterialJobStore, lkpd_storage: LkpdFileStorage) -> APIRouter:
router = APIRouter(tags=["lkpd"])
lkpd_scopes = list(settings.jwt_required_scopes.get("/api/lkpd", ()))
lkpd_file_scopes = list(
settings.jwt_required_scopes.get("/api/lkpd/files/{file_id}", ())
)
@router.post(
"/api/lkpd",
response_model=ApiSuccessResponse[JobAcceptedData],
response_model_exclude_none=True,
status_code=202,
dependencies=[Depends(require_jwt(lkpd_scopes))],
)
async def webhook_lkpd(
http_request: Request,
user_id: str = Form(...),
file: UploadFile = File(...),
callback_url: str = Form(...),
activity_count: int = Form(default=settings.lkpd_default_activity_count),
) -> ApiSuccessResponse[JobAcceptedData]:
submit_request = validate_submit_request(
LkpdAsyncSubmitRequest,
user_id=user_id,
callback_url=callback_url,
activity_count=activity_count,
)
job_id = await enqueue_uploaded_job(
job_store=job_store,
job_kind="lkpd",
submit_request=submit_request,
file=file,
failure_log_message="Failed to enqueue LKPD job",
failure_public_message="Failed to enqueue LKPD job",
)
return build_job_accepted_response(
request=http_request,
job_id=job_id,
message="LKPD queued for async processing.",
)
@router.get(
"/api/lkpd/files/{file_id}",
dependencies=[Depends(require_jwt(lkpd_file_scopes))],
)
async def get_lkpd_file(file_id: str) -> FileResponse:
path = lkpd_storage.get_pdf_path(file_id)
if path is None:
raise ServiceError("LKPD file not found or expired.", status_code=404)
return FileResponse(
path=path,
media_type="application/pdf",
filename=f"{file_id}.pdf",
)
return router