Skip to content

Commit

Permalink
omr mode in session
Browse files Browse the repository at this point in the history
  • Loading branch information
suryabulusu committed Oct 7, 2024
1 parent fe00455 commit e8b7ce5
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 10 deletions.
1 change: 1 addition & 0 deletions app/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,7 @@ class Session(BaseModel):
created_at: datetime = Field(default_factory=datetime.utcnow)
events: List[Event] = []
has_quiz_ended: bool = False
omr_mode: bool = False
metrics: Optional[SessionMetrics] = None # gets updated when quiz ends

class Config:
Expand Down
12 changes: 6 additions & 6 deletions app/routers/quizzes.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from fastapi import APIRouter, status, HTTPException
from fastapi import APIRouter, status, HTTPException, Query
from fastapi.responses import JSONResponse
from fastapi.encoders import jsonable_encoder
from database import client
Expand Down Expand Up @@ -139,8 +139,8 @@ async def create_quiz(quiz: Quiz):


@router.get("/{quiz_id}", response_model=GetQuizResponse)
async def get_quiz(quiz_id: str):
logger.info(f"Starting to get quiz: {quiz_id}")
async def get_quiz(quiz_id: str, omr_mode: bool = Query(False)):
logger.info(f"Starting to get quiz: {quiz_id} with omr_mode={omr_mode}")
quiz_collection = client.quiz.quizzes

if (quiz := quiz_collection.find_one({"_id": quiz_id})) is None:
Expand All @@ -151,19 +151,19 @@ async def get_quiz(quiz_id: str):

update_quiz_for_backwards_compatibility(quiz_collection, quiz_id, quiz)

if (
if omr_mode is False and (
"metadata" not in quiz
or quiz["metadata"] is None
or "quiz_type" not in quiz["metadata"]
or quiz["metadata"]["quiz_type"] != QuizType.omr.value
):
logger.warning(
f"Quiz {quiz_id} does not have metadata or is not an OMR quiz, skipping option count calculation"
f"omr_mode is False and Quiz {quiz_id} does not have metadata or is not an OMR quiz, skipping option count calculation"
)

else:
logger.info(
f"Quiz is an OMR type, calculating options count for quiz: {quiz_id}"
f"Quiz has to be rendered in OMR Mode, calculating options count for quiz: {quiz_id}"
)
question_set_ids = [
question_set["_id"] for question_set in quiz["question_sets"]
Expand Down
20 changes: 17 additions & 3 deletions app/routers/sessions.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,20 @@ async def create_session(session: Session):
logger.info(
f"No meaningful event has occurred in last_session. Returning this session which has id {last_session['_id']}"
)
# copy the omr mode value if changed (changes when toggled in UI)
if last_session["omr_mode"] != session.omr_mode:
last_session["omr_mode"] = session.omr_mode
logger.info("Updating omr_mode value in last_session")
update_result = client.quiz.sessions.update_one(
{"_id": last_session["_id"]}, {"$set": last_session}
)
if not update_result.acknowledged:
logger.error("Failed to update last session's omr_mode value")
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="Failed to update last session's omr_mode value",
)

return JSONResponse(
status_code=status.HTTP_201_CREATED, content=last_session
)
Expand All @@ -111,7 +125,7 @@ async def create_session(session: Session):
# so, we HAVE to distinguish between current_session and last_session by creating
# a new session for current_session
logger.info(
f"Some meaningful event has occurred in last_session, creating new session for user: {session.user_id} and quiz: {session.quiz_id}"
f"Some meaningful event has occurred in last_session, creating new session for user: {session.user_id} and quiz: {session.quiz_id} with {session.omr_mode} as omr_mode"
)
current_session["is_first"] = False
current_session["events"] = last_session.get("events", [])
Expand Down Expand Up @@ -139,11 +153,11 @@ async def create_session(session: Session):
result = client.quiz.sessions.insert_one(current_session)
if result.acknowledged:
logger.info(
f"Created new session with id {result.inserted_id} for user: {session.user_id} and quiz: {session.quiz_id}"
f"Created new session with id {result.inserted_id} for user: {session.user_id} and quiz: {session.quiz_id} with {session.omr_mode} as omr_mode"
)
else:
logger.error(
f"Failed to insert new session for user: {session.user_id} and quiz: {session.quiz_id}"
f"Failed to insert new session for user: {session.user_id} and quiz: {session.quiz_id} and omr_mode: {session.omr_mode}"
)
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
Expand Down
33 changes: 33 additions & 0 deletions app/scripts/update_session_for_omr_quizzes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
from pymongo import MongoClient
import os

if __name__ == "__main__":
if "MONGO_AUTH_CREDENTIALS" not in os.environ:
from dotenv import load_dotenv
load_dotenv("../../.env")

# Connect to MongoDB
client = MongoClient(os.getenv("MONGO_AUTH_CREDENTIALS"))

# Collections
quiz_collection = client.quiz.quizzes
session_collection = client.quiz.sessions

# Find all quiz IDs where metadata.quiz_type is "omr-assessment"
omr_assessment_quizzes = quiz_collection.find({"metadata.quiz_type": "omr-assessment"}, {"_id": 1})

# Extract quiz IDs from the query result
omr_quiz_ids = [quiz["_id"] for quiz in omr_assessment_quizzes]
print(f"Found {len(omr_quiz_ids)} quizzes with 'omr-assessment' type.")

session_count = session_collection.count_documents({"quiz_id": {"$in": omr_quiz_ids}})

print(f"Found {session_count} sessions that need to be updated.")

# Update all sessions with these quiz_ids, setting omr_mode to true
result = session_collection.update_many(
{"quiz_id": {"$in": omr_quiz_ids}},
{"$set": {"omr_mode": True}}
)

print(f"Updated {result.modified_count} sessions to set 'omr_mode' to True.")
11 changes: 11 additions & 0 deletions app/tests/test_quizzes.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,17 @@ def test_get_quiz_if_id_valid(self):
== self.short_homework_quiz_questions_length
)

def test_get_quiz_if_id_valid_and_omr_mode_in_params(self):
response = self.client.get(
f"{quizzes.router.prefix}/{self.multi_qset_quiz_id}",
params={"omr_mode": True},
)
assert response.status_code == 200
response = response.json()
assert self.multi_qset_quiz_lengths == [
len(response["question_sets"][i]["questions"]) for i in range(2)
]

def test_get_quiz_returns_error_if_id_invalid(self):
response = self.client.get(f"{quizzes.router.prefix}/00")
assert response.status_code == 404
Expand Down
16 changes: 15 additions & 1 deletion app/tests/test_sessions.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def test_gets_session_with_valid_id(self):
)
assert response.status_code == 200
session = response.json()
for key in ["quiz_id", "user_id"]:
for key in ["quiz_id", "user_id", "omr_mode"]:
assert session[key] == self.homework_session[key]

def test_get_session_returns_error_if_id_invalid(self):
Expand Down Expand Up @@ -79,6 +79,20 @@ def test_create_session_with_previous_session_and_no_event(self):

assert len(response["events"]) == 0
assert response["is_first"] is True
assert response["omr_mode"] is False

def test_create_session_with_previous_session_and_change_in_omr_mode(self):
# second session with no start-quiz event in first session
# but with a different omr_mode value
response = self.client.post(
sessions.router.prefix + "/",
json={"quiz_id": self.timed_quiz["_id"], "user_id": 1, "omr_mode": True},
).json()

assert len(response["events"]) == 0
assert response["is_first"] is True
assert response["omr_mode"] is True
# despite change in omr_mode, since no event has occurred, same session is returned

def test_create_session_with_previous_session_and_start_event(self):
session_updates = {"event": EventType.start_quiz.value}
Expand Down

0 comments on commit e8b7ce5

Please sign in to comment.