feat(backend): 更新 API 端点实现
- 更新 Chunks API 端点 - 更新 Datasets API 端点 - 更新 Evaluation API 端点 - 更新 Files API 端点 - 更新 Projects API 端点 - 更新 Questions API 端点 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -3,37 +3,38 @@ Questions API Router
|
||||
"""
|
||||
from typing import List, Optional
|
||||
from uuid import UUID
|
||||
from pydantic import BaseModel
|
||||
from fastapi import APIRouter, Depends, HTTPException, Query
|
||||
from pydantic import BaseModel, Field
|
||||
from fastapi import APIRouter, Depends, Query
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy import select
|
||||
|
||||
from app.api.response import ApiResponse, PaginatedResponse
|
||||
from app.core.database import get_db
|
||||
from app.core.exceptions import NotFoundException, ValidationException
|
||||
from app.core.crud import CRUDBase
|
||||
from app.models.models import Question, Chunk
|
||||
from app.schemas.base import QuestionCreate, QuestionResponse
|
||||
from app.schemas.question import QuestionResponse
|
||||
from app.schemas.question import QuestionCreateSchema
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
# Initialize CRUD
|
||||
question_crud = CRUDBase(Question)
|
||||
|
||||
|
||||
class GenerateRequest(BaseModel):
|
||||
"""Request model for generating questions"""
|
||||
chunk_ids: List[UUID] = []
|
||||
count: int = 5
|
||||
chunk_ids: List[UUID] = Field(..., min_length=1)
|
||||
count: int = Field(5, ge=1, le=50)
|
||||
question_types: List[str] = ["fact", "summary"]
|
||||
|
||||
|
||||
@router.post("/generate", response_model=dict)
|
||||
@router.post("/generate", response_model=ApiResponse)
|
||||
async def generate_questions(
|
||||
project_id: UUID,
|
||||
request: GenerateRequest,
|
||||
db: AsyncSession = Depends(get_db)
|
||||
):
|
||||
"""Generate questions from chunks using LLM"""
|
||||
# TODO: Implement LLM-based question generation
|
||||
# This is a placeholder that creates sample questions
|
||||
|
||||
if not request.chunk_ids:
|
||||
raise HTTPException(status_code=400, detail="chunk_ids is required")
|
||||
|
||||
# Get chunks
|
||||
result = await db.execute(
|
||||
select(Chunk).where(Chunk.id.in_(request.chunk_ids), Chunk.project_id == project_id)
|
||||
@@ -41,9 +42,9 @@ async def generate_questions(
|
||||
chunks = result.scalars().all()
|
||||
|
||||
if not chunks:
|
||||
raise HTTPException(status_code=404, detail="No chunks found")
|
||||
raise ValidationException("No valid chunks found", field="chunk_ids")
|
||||
|
||||
# Create sample questions (placeholder)
|
||||
# Create sample questions (placeholder for LLM-based generation)
|
||||
created_questions = []
|
||||
for chunk in chunks:
|
||||
for i in range(request.count):
|
||||
@@ -60,63 +61,73 @@ async def generate_questions(
|
||||
|
||||
await db.commit()
|
||||
|
||||
return {
|
||||
"questions": len(created_questions),
|
||||
"message": f"Successfully generated {len(created_questions)} questions"
|
||||
}
|
||||
return ApiResponse.ok(
|
||||
data={"questions": len(created_questions)},
|
||||
message=f"Successfully generated {len(created_questions)} questions"
|
||||
)
|
||||
|
||||
|
||||
@router.get("/", response_model=dict)
|
||||
@router.get("", response_model=ApiResponse)
|
||||
async def list_questions(
|
||||
project_id: UUID,
|
||||
chunk_id: Optional[UUID] = Query(None),
|
||||
page: int = Query(1, ge=1),
|
||||
page_size: int = Query(20, ge=1, le=100),
|
||||
db: AsyncSession = Depends(get_db)
|
||||
):
|
||||
"""List questions for a project"""
|
||||
query = select(Question).where(Question.project_id == project_id)
|
||||
|
||||
filters = {"project_id": project_id}
|
||||
if chunk_id:
|
||||
query = query.where(Question.chunk_id == chunk_id)
|
||||
filters["chunk_id"] = chunk_id
|
||||
|
||||
result = await db.execute(query)
|
||||
questions = result.scalars().all()
|
||||
skip = (page - 1) * page_size
|
||||
questions, total = await question_crud.get_multi(
|
||||
db,
|
||||
skip=skip,
|
||||
limit=page_size,
|
||||
filters=filters,
|
||||
order_by="created_at",
|
||||
descending=True
|
||||
)
|
||||
|
||||
return {"questions": [QuestionResponse.model_validate(q) for q in questions]}
|
||||
question_responses = [QuestionResponse.model_validate(q) for q in questions]
|
||||
return PaginatedResponse.ok(
|
||||
items=question_responses,
|
||||
page=page,
|
||||
page_size=page_size,
|
||||
total=total
|
||||
)
|
||||
|
||||
|
||||
@router.put("/{question_id}", response_model=dict)
|
||||
@router.put("/{question_id}", response_model=ApiResponse)
|
||||
async def update_question(
|
||||
project_id: UUID,
|
||||
question_id: UUID,
|
||||
question: QuestionCreate,
|
||||
question: QuestionCreateSchema,
|
||||
db: AsyncSession = Depends(get_db)
|
||||
):
|
||||
"""Update question"""
|
||||
result = await db.execute(
|
||||
select(Question).where(Question.id == question_id, Question.project_id == project_id)
|
||||
db_question = await question_crud.get(db, question_id)
|
||||
if not db_question or db_question.project_id != project_id:
|
||||
raise NotFoundException("Question", question_id)
|
||||
|
||||
updated_question = await question_crud.update(db, db_question, question)
|
||||
return ApiResponse.ok(
|
||||
data=QuestionResponse.model_validate(updated_question),
|
||||
message="Question updated successfully"
|
||||
)
|
||||
db_question = result.scalar_one_or_none()
|
||||
if not db_question:
|
||||
raise HTTPException(status_code=404, detail="Question not found")
|
||||
|
||||
for key, value in question.model_dump(exclude_unset=True).items():
|
||||
setattr(db_question, key, value)
|
||||
|
||||
await db.commit()
|
||||
await db.refresh(db_question)
|
||||
return QuestionResponse.model_validate(db_question)
|
||||
|
||||
|
||||
@router.delete("/{question_id}", response_model=dict)
|
||||
async def delete_question(project_id: UUID, question_id: UUID, db: AsyncSession = Depends(get_db)):
|
||||
@router.delete("/{question_id}", response_model=ApiResponse)
|
||||
async def delete_question(
|
||||
project_id: UUID,
|
||||
question_id: UUID,
|
||||
db: AsyncSession = Depends(get_db)
|
||||
):
|
||||
"""Delete question"""
|
||||
result = await db.execute(
|
||||
select(Question).where(Question.id == question_id, Question.project_id == project_id)
|
||||
)
|
||||
question = result.scalar_one_or_none()
|
||||
if not question:
|
||||
raise HTTPException(status_code=404, detail="Question not found")
|
||||
question = await question_crud.get(db, question_id)
|
||||
if not question or question.project_id != project_id:
|
||||
raise NotFoundException("Question", question_id)
|
||||
|
||||
await db.delete(question)
|
||||
await db.commit()
|
||||
return {"message": "Question deleted successfully"}
|
||||
await question_crud.delete(db, question_id)
|
||||
return ApiResponse.ok(message="Question deleted successfully")
|
||||
|
||||
Reference in New Issue
Block a user