feat: working on quiz
This commit is contained in:
parent
019eb2ecc9
commit
7a521b9ca2
|
@ -4,22 +4,46 @@ from dependency_injector.wiring import inject, Provide
|
|||
from controllers import QuizController
|
||||
|
||||
|
||||
quiz_bp = Blueprint(
|
||||
"quiz",
|
||||
__name__,
|
||||
)
|
||||
quiz_bp = Blueprint("quiz", __name__, url_prefix="/quiz")
|
||||
|
||||
|
||||
@quiz_bp.route("/quiz", methods=["POST"])
|
||||
@quiz_bp.route("/", methods=["POST"])
|
||||
@inject
|
||||
def create_quiz(controller: QuizController = Provide[Container.quiz_controller]):
|
||||
reqBody = request.get_json()
|
||||
return controller.create_quiz(reqBody)
|
||||
|
||||
|
||||
@quiz_bp.route("/quiz/<quiz_id>", methods=["GET"])
|
||||
@quiz_bp.route("/<quiz_id>", methods=["GET"])
|
||||
@inject
|
||||
def get_quiz(
|
||||
quiz_id: str, controller: QuizController = Provide[Container.quiz_controller]
|
||||
):
|
||||
return controller.get_quiz(quiz_id)
|
||||
|
||||
|
||||
@quiz_bp.route("/answer", methods=["POST"])
|
||||
@inject
|
||||
def submit_answer(controller: QuizController = Provide[Container.quiz_controller]):
|
||||
req_body = request.get_json()
|
||||
return controller.submit_answer(req_body)
|
||||
|
||||
|
||||
@quiz_bp.route("/answer", methods=["GET"])
|
||||
@inject
|
||||
def get_answer(controller: QuizController = Provide[Container.quiz_controller]):
|
||||
quiz_id = request.args.get("quiz_id")
|
||||
user_id = request.args.get("user_id")
|
||||
session_id = request.args.get("session_id")
|
||||
|
||||
return controller.get_answer(
|
||||
quiz_id=quiz_id, user_id=user_id, session_id=session_id
|
||||
)
|
||||
|
||||
|
||||
@quiz_bp.route("/recomendation", methods=["GET"])
|
||||
@inject
|
||||
def get_quiz_recommendation(
|
||||
controller: QuizController = Provide[Container.quiz_controller],
|
||||
):
|
||||
return controller.get_quiz_recommendation()
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
from flask import jsonify
|
||||
from pydantic import ValidationError
|
||||
from schemas.requests import QuizCreateSchema
|
||||
from schemas.requests import QuizCreateSchema, UserAnswerSchema
|
||||
from schemas.response import QuizCreationResponse
|
||||
from services import QuizService
|
||||
from services import QuizService, AnswerService
|
||||
from helpers import make_response, make_error_response
|
||||
|
||||
|
||||
class QuizController:
|
||||
def __init__(self, quiz_service: QuizService):
|
||||
def __init__(self, quiz_service: QuizService, answer_service: AnswerService):
|
||||
self.quiz_service = quiz_service
|
||||
self.answer_service = answer_service
|
||||
|
||||
def get_quiz(self, quiz_id):
|
||||
try:
|
||||
|
@ -50,3 +51,34 @@ class QuizController:
|
|||
if not success:
|
||||
return jsonify({"error": "Quiz not found"}), 400
|
||||
return jsonify({"message": "Quiz deleted"}), 200
|
||||
|
||||
def quiz_recomendation(self):
|
||||
try:
|
||||
result = self.quiz_service.get_quiz_recommendation()
|
||||
if not result:
|
||||
return make_response(message="Quiz not found", status_code=404)
|
||||
return make_response(message="Quiz Found", data=result.dict())
|
||||
except Exception as e:
|
||||
return make_error_response(e)
|
||||
|
||||
def submit_answer(self, answer_data):
|
||||
try:
|
||||
# Assuming answer_data is a dictionary with the necessary fields
|
||||
answer_obj = UserAnswerSchema(**answer_data)
|
||||
answer_id = self.answer_service.create_answer(answer_obj)
|
||||
return make_response(
|
||||
message="Answer submitted",
|
||||
data={"answer_id": answer_id},
|
||||
status_code=201,
|
||||
)
|
||||
except ValidationError as e:
|
||||
return make_response(e.errors(), status_code=400)
|
||||
except Exception as e:
|
||||
return make_error_response(e)
|
||||
|
||||
def get_answer(self, quiz_id, user_id, session_id):
|
||||
try:
|
||||
# self.answer_service.
|
||||
print("yps")
|
||||
except Exception as e:
|
||||
return make_error_response(e)
|
||||
|
|
|
@ -1,12 +1,7 @@
|
|||
from dependency_injector import containers, providers
|
||||
from controllers import UserController
|
||||
from repositories.user_repository import UserRepository
|
||||
from services import UserService, AuthService
|
||||
from controllers import AuthController
|
||||
from flask_pymongo import PyMongo
|
||||
from repositories import QuizRepository
|
||||
from services import QuizService
|
||||
from controllers import QuizController
|
||||
from controllers import UserController, AuthController, QuizController
|
||||
from repositories import UserRepository, QuizRepository, UserAnswerRepository
|
||||
from services import UserService, AuthService, QuizService, AnswerService
|
||||
|
||||
|
||||
class Container(containers.DeclarativeContainer):
|
||||
|
@ -17,13 +12,15 @@ class Container(containers.DeclarativeContainer):
|
|||
# repository
|
||||
user_repository = providers.Factory(UserRepository, mongo.provided.db)
|
||||
quiz_repository = providers.Factory(QuizRepository, mongo.provided.db)
|
||||
answer_repository = providers.Factory(UserAnswerRepository, mongo.provided.db)
|
||||
|
||||
# services
|
||||
auth_service = providers.Factory(AuthService, user_repository)
|
||||
user_service = providers.Factory(UserService, user_repository)
|
||||
quiz_service = providers.Factory(QuizService, quiz_repository)
|
||||
answer_service = providers.Factory(AnswerService, answer_repository)
|
||||
|
||||
# controllers
|
||||
auth_controller = providers.Factory(AuthController, user_service, auth_service)
|
||||
user_controller = providers.Factory(UserController, user_service)
|
||||
quiz_controller = providers.Factory(QuizController, quiz_service)
|
||||
quiz_controller = providers.Factory(QuizController, quiz_service, answer_service)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# app/models/__init__.py
|
||||
from .entities import UserEntity, QuizEntity, QuestionItemEntity
|
||||
from .entities import UserEntity, QuizEntity, QuestionItemEntity, UserAnswerEntity
|
||||
from .login import UserResponseModel
|
||||
|
||||
|
||||
|
@ -9,4 +9,5 @@ __all__ = [
|
|||
"UserResponseModel",
|
||||
"QuizEntity",
|
||||
"QuestionItemEntity",
|
||||
"UserAnswerEntity",
|
||||
]
|
||||
|
|
|
@ -2,10 +2,12 @@ from .user_entity import UserEntity
|
|||
from .base import PyObjectId
|
||||
from .quiz_entity import QuizEntity
|
||||
from .question_item_entity import QuestionItemEntity
|
||||
from .user_answer_entity import UserAnswerEntity
|
||||
|
||||
__all__ = [
|
||||
"UserEntity",
|
||||
"PyObjectId",
|
||||
"QuizEntity",
|
||||
"QuestionItemEntity",
|
||||
"UserAnswerEntity",
|
||||
]
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
from pydantic import BaseModel
|
||||
|
||||
|
||||
class AnswerItemEntity(BaseModel):
|
||||
question_index: int
|
||||
question: str
|
||||
answer: str
|
||||
correct_answer: str
|
||||
is_correct: bool
|
||||
duration: int
|
||||
time_spent: float
|
|
@ -1,8 +1,10 @@
|
|||
from bson import ObjectId
|
||||
from pydantic import GetJsonSchemaHandler
|
||||
from pydantic.json_schema import JsonSchemaValue
|
||||
|
||||
|
||||
class PyObjectId(ObjectId):
|
||||
"""Custom ObjectId type for Pydantic to handle MongoDB _id"""
|
||||
"""Custom ObjectId type for Pydantic v2 to handle MongoDB _id"""
|
||||
|
||||
@classmethod
|
||||
def __get_validators__(cls):
|
||||
|
@ -15,5 +17,7 @@ class PyObjectId(ObjectId):
|
|||
return ObjectId(v)
|
||||
|
||||
@classmethod
|
||||
def __modify_schema__(cls, field_schema):
|
||||
field_schema.update(type="string")
|
||||
def __get_pydantic_json_schema__(
|
||||
cls, schema: JsonSchemaValue, handler: GetJsonSchemaHandler
|
||||
) -> JsonSchemaValue:
|
||||
return {"type": "string"}
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
from typing import List, Optional
|
||||
from pydantic import BaseModel, Field
|
||||
from datetime import datetime
|
||||
from bson import ObjectId
|
||||
|
||||
from .answer_item import AnswerItemEntity
|
||||
from .base import PyObjectId
|
||||
|
||||
|
||||
class UserAnswerEntity(BaseModel):
|
||||
_id: Optional[PyObjectId] = None
|
||||
session_id: Optional[PyObjectId]
|
||||
quiz_id: PyObjectId
|
||||
user_id: str
|
||||
answered_at: datetime
|
||||
answers: List[AnswerItemEntity]
|
||||
total_score: int
|
||||
total_correct: int
|
||||
total_questions: int
|
||||
|
||||
class Config:
|
||||
allow_population_by_field_name = True
|
||||
arbitrary_types_allowed = True
|
||||
json_encoders = {ObjectId: str}
|
|
@ -1,8 +1,9 @@
|
|||
from .user_repository import UserRepository
|
||||
from .quiz_repositroy import QuizRepository
|
||||
|
||||
from .answer_repository import UserAnswerRepository
|
||||
|
||||
__all__ = [
|
||||
"UserRepository",
|
||||
"QuizRepository",
|
||||
"UserAnswerRepository",
|
||||
]
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
from pymongo.collection import Collection
|
||||
from bson import ObjectId
|
||||
from typing import Optional, List
|
||||
from models import UserAnswerEntity
|
||||
|
||||
|
||||
class UserAnswerRepository:
|
||||
def __init__(self, db):
|
||||
self.collection: Collection = db.user_answers
|
||||
|
||||
def create(self, answer_session: UserAnswerEntity) -> str:
|
||||
data = answer_session.model_dump(by_alias=True)
|
||||
result = self.collection.insert_one(data)
|
||||
return str(result.inserted_id)
|
||||
|
||||
def get_by_id(self, id: str) -> Optional[dict]:
|
||||
result = self.collection.find_one({"_id": ObjectId(id)})
|
||||
return result
|
||||
|
||||
def get_by_user_and_quiz(self, user_id: str, quiz_id: str) -> List[dict]:
|
||||
result = self.collection.find(
|
||||
{"user_id": user_id, "quiz_id": ObjectId(quiz_id)}
|
||||
)
|
||||
return list(result)
|
||||
|
||||
def get_by_session(self, session_id: str) -> List[dict]:
|
||||
result = self.collection.find({"session_id": ObjectId(session_id)})
|
||||
return list(result)
|
||||
|
||||
def delete_by_id(self, id: str) -> bool:
|
||||
result = self.collection.delete_one({"_id": ObjectId(id)})
|
||||
return result.deleted_count > 0
|
|
@ -5,9 +5,14 @@ from .quiz import (
|
|||
QuizCreateSchema,
|
||||
)
|
||||
|
||||
from .answer.answer_request_schema import UserAnswerSchema
|
||||
from .answer.answer_item_request_schema import AnswerItemSchema
|
||||
|
||||
|
||||
__all__ = [
|
||||
"RegisterSchema",
|
||||
"QuestionItemSchema",
|
||||
"QuizCreateSchema",
|
||||
"UserAnswerSchema",
|
||||
"AnswerItemSchema",
|
||||
]
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
from pydantic import BaseModel
|
||||
|
||||
|
||||
class AnswerItemSchema(BaseModel):
|
||||
question_index: int
|
||||
question: str
|
||||
answer: str
|
||||
correct_answer: str
|
||||
is_correct: bool
|
||||
duration: int
|
||||
time_spent: float
|
|
@ -0,0 +1,15 @@
|
|||
from typing import List, Optional
|
||||
from pydantic import BaseModel, Field
|
||||
from datetime import datetime
|
||||
from .answer_item_request_schema import AnswerItemSchema
|
||||
|
||||
|
||||
class UserAnswerSchema(BaseModel):
|
||||
session_id: Optional[str] = None
|
||||
quiz_id: str
|
||||
user_id: str
|
||||
answered_at: datetime
|
||||
total_score: int
|
||||
total_correct: int
|
||||
total_questions: int
|
||||
answers: List[AnswerItemSchema]
|
|
@ -1,10 +1,12 @@
|
|||
from .auth_service import AuthService
|
||||
from .user_service import UserService
|
||||
from .quiz_service import QuizService
|
||||
from .answer_service import AnswerService
|
||||
|
||||
|
||||
__all__ = [
|
||||
"AuthService",
|
||||
"UserService",
|
||||
"QuizService",
|
||||
"AnswerService",
|
||||
]
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
from repositories import UserAnswerRepository
|
||||
|
||||
|
||||
class AnswerService:
|
||||
def __init__(self, answer_repository: UserAnswerRepository):
|
||||
self.answer_repository = answer_repository
|
||||
|
||||
def get_answer_by_id(self, answer_id):
|
||||
return self.answer_repository.get_answer_by_id(answer_id)
|
||||
|
||||
def get_answer(self, quiz_id, user_id, session_id):
|
||||
if quiz_id is not None:
|
||||
return self.answer_repository
|
||||
|
||||
def create_answer(self, answer_data):
|
||||
return self.answer_repository.create(answer_data)
|
||||
|
||||
def update_answer(self, answer_id, answer_data):
|
||||
return self.answer_repository.update(answer_id, answer_data)
|
||||
|
||||
def delete_answer(self, answer_id):
|
||||
return self.answer_repository.delete_by_id(answer_id)
|
|
@ -23,3 +23,10 @@ class QuizService:
|
|||
|
||||
def delete_quiz(self, quiz_id):
|
||||
return self.quiz_repository.delete(quiz_id)
|
||||
|
||||
def quiz_recommendation(self):
|
||||
data = self.quiz_repository
|
||||
if data is None:
|
||||
raise DataNotFoundException("Quiz not found")
|
||||
|
||||
return map_quiz_entity_to_schema(data)
|
||||
|
|
Loading…
Reference in New Issue