Skip to content

Commit 8767ac9

Browse files
authored
Merge pull request #181 from CS3219-AY2425S1/add-get-random-question-api
QuestionService: Add fetch random question endpoint
2 parents ff1ceae + 92c793e commit 8767ac9

File tree

3 files changed

+43
-0
lines changed

3 files changed

+43
-0
lines changed

question-service/app/crud/questions.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from bson import ObjectId
22
from bson.errors import InvalidId
33
from dotenv import load_dotenv
4+
from random import randint
45
import motor.motor_asyncio
56
import os
67
from typing import List
@@ -10,6 +11,7 @@
1011
QuestionNotFoundError,
1112
BatchUploadFailedError,
1213
InvalidQuestionIdError,
14+
RandomQuestionNotFoundError
1315
)
1416
from models.questions import (
1517
CategoryEnum,
@@ -100,6 +102,24 @@ async def batch_create_questions(
100102
"message": f"{len(result.inserted_ids)} questions added successfully."
101103
})
102104

105+
async def fetch_random_question(
106+
category: CategoryEnum | None,
107+
complexity: ComplexityEnum | None,
108+
) -> QuestionModel:
109+
query = {}
110+
if category:
111+
query["categories"] = category
112+
if complexity:
113+
query["complexity"] = complexity
114+
115+
count = await question_collection.count_documents(query)
116+
if count == 0:
117+
raise RandomQuestionNotFoundError(category, complexity)
118+
119+
random_index = randint(0, count - 1)
120+
random_question = await question_collection.find(query).skip(random_index).limit(1).to_list(1)
121+
return QuestionModel.parse_obj(random_question[0])
122+
103123
def get_question_categories() -> List[CategoryEnum]:
104124
return [category for category in CategoryEnum]
105125

question-service/app/exceptions/questions_exceptions.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,13 @@ class QuestionNotFoundError(Exception):
1515
def __init__(self, question_id):
1616
self.question_id = question_id
1717
super().__init__(f"Question with ID '{question_id}' not found.")
18+
19+
class RandomQuestionNotFoundError(Exception):
20+
"""Raised when a question with the given ID is not found."""
21+
def __init__(self, category, complexity):
22+
self.category = category
23+
self.complexity = complexity
24+
super().__init__(f"Question with category '{category}' and complexity '{complexity}' not found.")
1825

1926
class BatchUploadFailedError(Exception):
2027
"""Raised when batch upload fails to upload any questions successfully"""

question-service/app/routers/questions.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,14 @@
99
get_question_categories,
1010
get_question_complexities,
1111
update_question_by_id,
12+
fetch_random_question,
1213
)
1314
from exceptions.questions_exceptions import (
1415
DuplicateQuestionError,
1516
QuestionNotFoundError,
1617
BatchUploadFailedError,
1718
InvalidQuestionIdError,
19+
RandomQuestionNotFoundError,
1820
)
1921
from fastapi import APIRouter, HTTPException, Query
2022
from models.questions import (
@@ -29,6 +31,20 @@
2931

3032
router = APIRouter()
3133

34+
@router.get("/random",
35+
response_description="Get a random question based on category and complexity",
36+
response_model=QuestionModel
37+
)
38+
async def get_random_question(
39+
category: CategoryEnum | None = None,
40+
complexity: ComplexityEnum | None = None,
41+
):
42+
try:
43+
question = await fetch_random_question(category, complexity)
44+
return question
45+
except RandomQuestionNotFoundError as e:
46+
raise HTTPException(status_code=404, detail=str(e))
47+
3248
@router.post("/",
3349
response_description="Create new question",
3450
response_model=QuestionModel,

0 commit comments

Comments
 (0)