Spaces:
Sleeping
Sleeping
| from __future__ import annotations | |
| from typing import Literal | |
| from fastapi import APIRouter, Depends, File, Form, Request, UploadFile | |
| from src.agent.jobs import MaterialJobStore | |
| from src.agent.types import GenerateType, MaterialAsyncSubmitRequest | |
| from src.auth import require_jwt | |
| from src.config import settings | |
| from src.core.api_response import ApiSuccessResponse | |
| from src.api.job_submission import ( | |
| build_job_accepted_response, | |
| enqueue_uploaded_job, | |
| validate_submit_request, | |
| ) | |
| from src.api.schemas import JobAcceptedData | |
| GENERATION_MESSAGE: dict[GenerateType, str] = { | |
| "mcq": "MCQ queued for async processing.", | |
| "essay": "Essay queued for async processing.", | |
| "summary": "Summary queued for async processing.", | |
| } | |
| def _build_submit_request( | |
| *, | |
| user_id: str, | |
| callback_url: str, | |
| generate_types: list[GenerateType], | |
| mcq_count: int, | |
| essay_count: int, | |
| summary_max_words: int, | |
| mcp_enabled: bool, | |
| ) -> MaterialAsyncSubmitRequest: | |
| return validate_submit_request( | |
| MaterialAsyncSubmitRequest, | |
| user_id=user_id, | |
| callback_url=callback_url, | |
| generate_types=generate_types, | |
| mcq_count=mcq_count, | |
| essay_count=essay_count, | |
| summary_max_words=summary_max_words, | |
| mcp_enabled=mcp_enabled, | |
| ) | |
| async def _enqueue_from_submit_request( | |
| *, | |
| job_store: MaterialJobStore, | |
| request: Request, | |
| submit_request: MaterialAsyncSubmitRequest, | |
| file: UploadFile, | |
| message: str, | |
| ) -> ApiSuccessResponse[JobAcceptedData]: | |
| job_id = await enqueue_uploaded_job( | |
| job_store=job_store, | |
| job_kind="material", | |
| submit_request=submit_request, | |
| file=file, | |
| failure_log_message="Failed to enqueue material job", | |
| failure_public_message="Failed to enqueue material job", | |
| ) | |
| return build_job_accepted_response( | |
| request=request, | |
| job_id=job_id, | |
| message=message, | |
| ) | |
| async def enqueue_material_job( | |
| *, | |
| job_store: MaterialJobStore, | |
| request: Request, | |
| user_id: str, | |
| file: UploadFile, | |
| callback_url: str, | |
| generate_type: Literal["mcq", "essay", "summary"], | |
| mcq_count: int | None, | |
| essay_count: int | None, | |
| summary_max_words: int | None, | |
| mcp_enabled: bool, | |
| ) -> ApiSuccessResponse[JobAcceptedData]: | |
| submit_request = _build_submit_request( | |
| user_id=user_id, | |
| callback_url=callback_url, | |
| generate_types=[generate_type], | |
| mcq_count=settings.default_mcq_count if mcq_count is None else mcq_count, | |
| essay_count=settings.default_essay_count if essay_count is None else essay_count, | |
| summary_max_words=( | |
| settings.default_summary_max_words | |
| if summary_max_words is None | |
| else summary_max_words | |
| ), | |
| mcp_enabled=mcp_enabled, | |
| ) | |
| return await _enqueue_from_submit_request( | |
| job_store=job_store, | |
| request=request, | |
| submit_request=submit_request, | |
| message=GENERATION_MESSAGE[generate_type], | |
| file=file, | |
| ) | |
| def build_material_router(job_store: MaterialJobStore) -> APIRouter: | |
| router = APIRouter(tags=["material"]) | |
| material_scopes = list(settings.jwt_required_scopes.get("/api/material", ())) | |
| mcq_scopes = list(settings.jwt_required_scopes.get("/api/mcq", material_scopes)) | |
| essay_scopes = list(settings.jwt_required_scopes.get("/api/essay", material_scopes)) | |
| summary_scopes = list(settings.jwt_required_scopes.get("/api/summary", material_scopes)) | |
| async def webhook_material( | |
| http_request: Request, | |
| user_id: str = Form(...), | |
| file: UploadFile = File(...), | |
| callback_url: str = Form(...), | |
| generate_types: list[GenerateType] = Form(...), | |
| mcq_count: int = Form(default=settings.default_mcq_count), | |
| essay_count: int = Form(default=settings.default_essay_count), | |
| summary_max_words: int = Form(default=settings.default_summary_max_words), | |
| mcp_enabled: bool = Form(default=True), | |
| ) -> ApiSuccessResponse[JobAcceptedData]: | |
| submit_request = _build_submit_request( | |
| user_id=user_id, | |
| callback_url=callback_url, | |
| generate_types=generate_types, | |
| mcq_count=mcq_count, | |
| essay_count=essay_count, | |
| summary_max_words=summary_max_words, | |
| mcp_enabled=mcp_enabled, | |
| ) | |
| return await _enqueue_from_submit_request( | |
| job_store=job_store, | |
| request=http_request, | |
| submit_request=submit_request, | |
| file=file, | |
| message="Material queued for async processing.", | |
| ) | |
| async def webhook_mcq( | |
| http_request: Request, | |
| user_id: str = Form(...), | |
| file: UploadFile = File(...), | |
| callback_url: str = Form(...), | |
| mcq_count: int = Form(default=settings.default_mcq_count), | |
| mcp_enabled: bool = Form(default=True), | |
| ) -> ApiSuccessResponse[JobAcceptedData]: | |
| return await enqueue_material_job( | |
| job_store=job_store, | |
| request=http_request, | |
| user_id=user_id, | |
| file=file, | |
| callback_url=callback_url, | |
| generate_type="mcq", | |
| mcq_count=mcq_count, | |
| essay_count=None, | |
| summary_max_words=None, | |
| mcp_enabled=mcp_enabled, | |
| ) | |
| async def webhook_essay( | |
| http_request: Request, | |
| user_id: str = Form(...), | |
| file: UploadFile = File(...), | |
| callback_url: str = Form(...), | |
| essay_count: int = Form(default=settings.default_essay_count), | |
| mcp_enabled: bool = Form(default=True), | |
| ) -> ApiSuccessResponse[JobAcceptedData]: | |
| return await enqueue_material_job( | |
| job_store=job_store, | |
| request=http_request, | |
| user_id=user_id, | |
| file=file, | |
| callback_url=callback_url, | |
| generate_type="essay", | |
| mcq_count=None, | |
| essay_count=essay_count, | |
| summary_max_words=None, | |
| mcp_enabled=mcp_enabled, | |
| ) | |
| async def webhook_summary( | |
| http_request: Request, | |
| user_id: str = Form(...), | |
| file: UploadFile = File(...), | |
| callback_url: str = Form(...), | |
| summary_max_words: int = Form(default=settings.default_summary_max_words), | |
| mcp_enabled: bool = Form(default=True), | |
| ) -> ApiSuccessResponse[JobAcceptedData]: | |
| return await enqueue_material_job( | |
| job_store=job_store, | |
| request=http_request, | |
| user_id=user_id, | |
| file=file, | |
| callback_url=callback_url, | |
| generate_type="summary", | |
| mcq_count=None, | |
| essay_count=None, | |
| summary_max_words=summary_max_words, | |
| mcp_enabled=mcp_enabled, | |
| ) | |
| return router | |