Skip to content

Commit e9bf699

Browse files
committed
Refactor packaging
1 parent f95dd57 commit e9bf699

File tree

7 files changed

+147
-125
lines changed

7 files changed

+147
-125
lines changed

services/question-service/app/core/__init__.py

Whitespace-only changes.

services/question-service/app/crud.py renamed to services/question-service/app/core/crud.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import uuid
22
from typing import List, Dict, Optional
3-
from app.utils import get_conn, upload_to_s3, get_from_s3, delete_from_s3
3+
from utils import get_conn, upload_to_s3, get_from_s3, delete_from_s3
44
from app.models.exceptions import QuestionNotFoundException
55

66
def list_difficulties_and_topics() -> Dict[str, List[str]]:
Lines changed: 5 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -1,130 +1,11 @@
1-
from fastapi import FastAPI, HTTPException, Query
1+
from fastapi import FastAPI
22
from dotenv import load_dotenv
3-
from app.models.endpoint_models import QuestionBase64Images
4-
from app.models.exceptions import QuestionNotFoundException
5-
from app.utils import batch_convert_base64_to_bytes, batch_convert_bytes_to_base64
6-
from app.crud import (
7-
add_difficulty,
8-
delete_difficulty,
9-
add_topic,
10-
delete_topic,
11-
create_question,
12-
get_question,
13-
get_random_question_by_difficulty_and_topic,
14-
override_question,
15-
delete_question,
16-
list_difficulties_and_topics
17-
)
18-
3+
from app.routers import questions_router, metadata_router
194

205
load_dotenv()
216

227
app = FastAPI()
238

24-
@app.post("/questions")
25-
def create_question_endpoint(q: QuestionBase64Images):
26-
# Convert images and call CRUD with primitive types
27-
images_bytes = batch_convert_base64_to_bytes(q.images)
28-
29-
new_qid = create_question(
30-
name=q.name,
31-
description=q.description,
32-
difficulty=q.difficulty,
33-
topic=q.topic,
34-
images=images_bytes
35-
)
36-
37-
# Get the created question and convert to response model
38-
return {
39-
"id": new_qid,
40-
"message": "Created successfully"
41-
}
42-
43-
44-
@app.get("/questions/{qid}", response_model=QuestionBase64Images)
45-
def get_question_endpoint(qid: str):
46-
try:
47-
question_dict = get_question(qid)
48-
except QuestionNotFoundException as e:
49-
raise HTTPException(status_code=404, detail=f"Question {e.question_id} not found")
50-
question_dict['images'] = batch_convert_bytes_to_base64(question_dict['images'])
51-
return question_dict
52-
53-
54-
@app.get("/questions/random")
55-
def get_random_question_endpoint(
56-
difficulty: str = Query(..., description="The difficulty level to filter by"),
57-
topic: str = Query(..., description="The topic to filter by")
58-
):
59-
"""Get a random question by difficulty and topic"""
60-
try:
61-
question_dict = get_random_question_by_difficulty_and_topic(difficulty, topic)
62-
except QuestionNotFoundException as e:
63-
raise HTTPException(status_code=404, detail=str(e))
64-
question_dict['images'] = batch_convert_bytes_to_base64(question_dict['images'])
65-
return question_dict
66-
67-
68-
@app.put("/questions/{qid}")
69-
def update_question_endpoint(qid: str, q: QuestionBase64Images):
70-
images_bytes = batch_convert_base64_to_bytes(q.images)
71-
72-
try:
73-
override_question(
74-
qid=qid,
75-
name=q.name,
76-
description=q.description,
77-
difficulty=q.difficulty,
78-
topic=q.topic,
79-
images=images_bytes
80-
)
81-
except QuestionNotFoundException as e:
82-
raise HTTPException(status_code=404, detail=str(e))
83-
84-
return {
85-
"message": "Updated successfully"
86-
}
87-
88-
89-
@app.delete("/questions/{qid}")
90-
def delete_question_endpoint(qid: str):
91-
try:
92-
delete_question(qid)
93-
except QuestionNotFoundException as e:
94-
raise HTTPException(status_code=404, detail=str(e))
95-
return {
96-
"message": "Deleted successfully"
97-
}
98-
99-
100-
@app.get("/difficulties-topics")
101-
def get_difficulties_topics():
102-
return list_difficulties_and_topics()
103-
104-
@app.post("/difficulties")
105-
def add_difficulty_endpoint(difficulty: str = Query(..., description="The difficulty level to add")):
106-
add_difficulty(difficulty)
107-
return {
108-
"message": f"Difficulty '{difficulty}' added successfully"
109-
}
110-
111-
@app.delete("/difficulties")
112-
def delete_difficulty_endpoint(difficulty: str = Query(..., description="The difficulty level to delete")):
113-
delete_difficulty(difficulty)
114-
return {
115-
"message": f"Difficulty '{difficulty}' deleted successfully"
116-
}
117-
118-
@app.post("/topics")
119-
def add_topic_endpoint(topic: str = Query(..., description="The topic to add")):
120-
add_topic(topic)
121-
return {
122-
"message": f"Topic '{topic}' added successfully"
123-
}
124-
125-
@app.delete("/topics")
126-
def delete_topic_endpoint(topic: str = Query(..., description="The topic to delete")):
127-
delete_topic(topic)
128-
return {
129-
"message": f"Topic '{topic}' deleted successfully"
130-
}
9+
# Include routers
10+
app.include_router(questions_router)
11+
app.include_router(metadata_router)

services/question-service/app/models/__init__.py

Whitespace-only changes.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Router imports for the question service
2+
from .questions import router as questions_router
3+
from .metadata import router as metadata_router
4+
5+
__all__ = ["questions_router", "metadata_router"]
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
from fastapi import APIRouter, Query
2+
from app.core.crud import (
3+
add_difficulty,
4+
delete_difficulty,
5+
add_topic,
6+
delete_topic,
7+
list_difficulties_and_topics
8+
)
9+
10+
router = APIRouter(
11+
prefix="/metadata",
12+
tags=["metadata"]
13+
)
14+
15+
@router.get("/difficulties-topics")
16+
def get_difficulties_topics():
17+
return list_difficulties_and_topics()
18+
19+
@router.post("/difficulties")
20+
def add_difficulty_endpoint(difficulty: str = Query(..., description="The difficulty level to add")):
21+
add_difficulty(difficulty)
22+
return {
23+
"message": f"Difficulty '{difficulty}' added successfully"
24+
}
25+
26+
@router.delete("/difficulties")
27+
def delete_difficulty_endpoint(difficulty: str = Query(..., description="The difficulty level to delete")):
28+
delete_difficulty(difficulty)
29+
return {
30+
"message": f"Difficulty '{difficulty}' deleted successfully"
31+
}
32+
33+
@router.post("/topics")
34+
def add_topic_endpoint(topic: str = Query(..., description="The topic to add")):
35+
add_topic(topic)
36+
return {
37+
"message": f"Topic '{topic}' added successfully"
38+
}
39+
40+
@router.delete("/topics")
41+
def delete_topic_endpoint(topic: str = Query(..., description="The topic to delete")):
42+
delete_topic(topic)
43+
return {
44+
"message": f"Topic '{topic}' deleted successfully"
45+
}
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
from fastapi import APIRouter, HTTPException, Query
2+
from app.models.endpoint_models import QuestionBase64Images
3+
from app.models.exceptions import QuestionNotFoundException
4+
from app.utils import batch_convert_base64_to_bytes, batch_convert_bytes_to_base64
5+
from app.core.crud import (
6+
create_question,
7+
get_question,
8+
get_random_question_by_difficulty_and_topic,
9+
override_question,
10+
delete_question,
11+
)
12+
13+
router = APIRouter(
14+
prefix="/questions",
15+
tags=["questions"]
16+
)
17+
18+
@router.post("")
19+
def create_question_endpoint(q: QuestionBase64Images):
20+
# Convert images and call CRUD with primitive types
21+
images_bytes = batch_convert_base64_to_bytes(q.images)
22+
23+
new_qid = create_question(
24+
name=q.name,
25+
description=q.description,
26+
difficulty=q.difficulty,
27+
topic=q.topic,
28+
images=images_bytes
29+
)
30+
31+
# Get the created question and convert to response model
32+
return {
33+
"id": new_qid,
34+
"message": "Created successfully"
35+
}
36+
37+
38+
@router.get("/random")
39+
def get_random_question_endpoint(
40+
difficulty: str = Query(..., description="The difficulty level to filter by"),
41+
topic: str = Query(..., description="The topic to filter by")
42+
):
43+
"""Get a random question by difficulty and topic"""
44+
try:
45+
question_dict = get_random_question_by_difficulty_and_topic(difficulty, topic)
46+
except QuestionNotFoundException as e:
47+
raise HTTPException(status_code=404, detail=str(e))
48+
question_dict['images'] = batch_convert_bytes_to_base64(question_dict['images'])
49+
return question_dict
50+
51+
52+
@router.get("/{qid}", response_model=QuestionBase64Images)
53+
def get_question_endpoint(qid: str):
54+
try:
55+
question_dict = get_question(qid)
56+
except QuestionNotFoundException as e:
57+
raise HTTPException(status_code=404, detail=f"Question {e.question_id} not found")
58+
question_dict['images'] = batch_convert_bytes_to_base64(question_dict['images'])
59+
return question_dict
60+
61+
62+
@router.put("/{qid}")
63+
def update_question_endpoint(qid: str, q: QuestionBase64Images):
64+
images_bytes = batch_convert_base64_to_bytes(q.images)
65+
66+
try:
67+
override_question(
68+
qid=qid,
69+
name=q.name,
70+
description=q.description,
71+
difficulty=q.difficulty,
72+
topic=q.topic,
73+
images=images_bytes
74+
)
75+
except QuestionNotFoundException as e:
76+
raise HTTPException(status_code=404, detail=str(e))
77+
78+
return {
79+
"message": "Updated successfully"
80+
}
81+
82+
83+
@router.delete("/{qid}")
84+
def delete_question_endpoint(qid: str):
85+
try:
86+
delete_question(qid)
87+
except QuestionNotFoundException as e:
88+
raise HTTPException(status_code=404, detail=str(e))
89+
return {
90+
"message": "Deleted successfully"
91+
}

0 commit comments

Comments
 (0)