Skip to content
This repository has been archived by the owner on Jan 22, 2025. It is now read-only.

Fix for issue 102. Submissions get now returns summary information instead of only url #147

Merged
merged 2 commits into from
Mar 28, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 41 additions & 61 deletions backend/project/endpoints/submissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,15 @@
from project.utils.files import filter_files, all_files_uploaded, zip_files
from project.utils.user import is_valid_user
from project.utils.project import is_valid_project
from project.utils.query_agent import query_selected_from_model, delete_by_id_from_model
from project.utils.authentication import authorize_submission_request, \
authorize_submissions_request, authorize_grader, \
authorize_student_submission, authorize_submission_author

load_dotenv()
API_HOST = getenv("API_HOST")
UPLOAD_FOLDER = getenv("UPLOAD_FOLDER")
BASE_URL = urljoin(f"{API_HOST}/", "/submissions")

submissions_bp = Blueprint("submissions", __name__)

Expand All @@ -36,39 +38,37 @@ def get(self) -> dict[str, any]:
"""

data = {
"url": urljoin(f"{API_HOST}/", "/submissions")
"url": BASE_URL
}
try:
with db.session() as session:
query = session.query(Submission)

# Filter by uid
uid = request.args.get("uid")
if uid is not None:
if session.get(User, uid) is not None:
query = query.filter_by(uid=uid)
else:
data["message"] = f"Invalid user (uid={uid})"
return data, 400

# Filter by project_id
project_id = request.args.get("project_id")
if project_id is not None:
if not project_id.isdigit() or session.get(Project, int(project_id)) is None:
data["message"] = f"Invalid project (project_id={project_id})"
return data, 400
query = query.filter_by(project_id=int(project_id))

# Get the submissions
data["message"] = "Successfully fetched the submissions"
data["data"] = [
urljoin(f"{API_HOST}/", f"/submissions/{s.submission_id}") for s in query.all()
]
return data, 200

# Filter by uid
uid = request.args.get("uid")
if uid is not None and (not uid.isdigit() or not User.query.filter_by(uid=uid).first()):
data["message"] = f"Invalid user (uid={uid})"
return data, 400

# Filter by project_id
project_id = request.args.get("project_id")
if project_id is not None and (not project_id.isdigit() or not Project.query.filter_by(project_id=project_id).first()):
data["message"] = f"Invalid project (project_id={project_id})"
return data, 400
except exc.SQLAlchemyError:
data["message"] = "An error occurred while fetching the submissions"
return data, 500

return query_selected_from_model(
Submission,
urljoin(f"{API_HOST}/", "/submissions"),
select_values=[
"submission_id", "uid",
"project_id", "grading",
"submission_time", "submission_status"],
url_mapper={
"submission_id": BASE_URL,
"project_id": urljoin(f"{API_HOST}/", "projects"),
"uid": urljoin(f"{API_HOST}/", "users")},
filters=request.args
)

@authorize_student_submission
def post(self) -> dict[str, any]:
Expand All @@ -79,7 +79,7 @@ def post(self) -> dict[str, any]:
"""

data = {
"url": urljoin(f"{API_HOST}/", "/submissions")
"url": BASE_URL
}
try:
with db.session() as session:
Expand Down Expand Up @@ -129,12 +129,11 @@ def post(self) -> dict[str, any]:
data["message"] = "Successfully fetched the submissions"
data["url"] = urljoin(f"{API_HOST}/", f"/submissions/{submission.submission_id}")
data["data"] = {
"id": submission.submission_id,
"id": urljoin(f"{BASE_URL}/", submission.submission_id),
"user": urljoin(f"{API_HOST}/", f"/users/{submission.uid}"),
"project": urljoin(f"{API_HOST}/", f"/projects/{submission.project_id}"),
"grading": submission.grading,
"time": submission.submission_time,
"path": submission.submission_path,
"status": submission.submission_status
}
return data, 201
Expand All @@ -159,7 +158,7 @@ def get(self, submission_id: int) -> dict[str, any]:
"""

data = {
"url": urljoin(f"{API_HOST}/", f"/submissions/{submission_id}")
"url": urljoin(f"{BASE_URL}/", str(submission_id))
}
try:
with db.session() as session:
Expand All @@ -171,12 +170,11 @@ def get(self, submission_id: int) -> dict[str, any]:

data["message"] = "Successfully fetched the submission"
data["data"] = {
"id": submission.submission_id,
"id": urljoin(f"{BASE_URL}/", str(submission.submission_id)),
"user": urljoin(f"{API_HOST}/", f"/users/{submission.uid}"),
"project": urljoin(f"{API_HOST}/", f"/projects/{submission.project_id}"),
"grading": submission.grading,
"time": submission.submission_time,
"path": submission.submission_path,
"status": submission.submission_status
}
return data, 200
Expand All @@ -198,7 +196,7 @@ def patch(self, submission_id:int) -> dict[str, any]:
"""

data = {
"url": urljoin(f"{API_HOST}/", f"/submissions/{submission_id}")
"url": urljoin(f"{BASE_URL}/", str(submission_id))
}
try:
with db.session() as session:
Expand Down Expand Up @@ -227,14 +225,13 @@ def patch(self, submission_id:int) -> dict[str, any]:
session.commit()

data["message"] = f"Submission (submission_id={submission_id}) patched"
data["url"] = urljoin(f"{API_HOST}/", f"/submissions/{submission.submission_id}")
data["url"] = urljoin(f"{BASE_URL}/", str(submission.submission_id))
data["data"] = {
"id": submission.submission_id,
"id": urljoin(f"{BASE_URL}/", str(submission.submission_id)),
"user": urljoin(f"{API_HOST}/", f"/users/{submission.uid}"),
"project": urljoin(f"{API_HOST}/", f"/projects/{submission.project_id}"),
"grading": submission.grading,
"time": submission.submission_time,
"path": submission.submission_path,
"status": submission.submission_status
}
return data, 200
Expand All @@ -256,29 +253,12 @@ def delete(self, submission_id: int) -> dict[str, any]:
dict[str, any]: A message
"""

data = {
"url": urljoin(f"{API_HOST}/", "/submissions")
}
try:
with db.session() as session:
submission = session.get(Submission, submission_id)
if submission is None:
data["url"] = urljoin(f"{API_HOST}/", "/submissions")
data["message"] = f"Submission (submission_id={submission_id}) not found"
return data, 404

# Delete the submission
session.delete(submission)
session.commit()

data["message"] = f"Submission (submission_id={submission_id}) deleted"
return data, 200

except exc.SQLAlchemyError:
db.session.rollback()
data["message"] = \
f"An error occurred while deleting submission (submission_id={submission_id})"
return data, 500
return delete_by_id_from_model(
Submission,
"submission_id",
submission_id,
BASE_URL
)

submissions_bp.add_url_rule("/submissions", view_func=SubmissionsEndpoint.as_view("submissions"))
submissions_bp.add_url_rule(
Expand Down
8 changes: 3 additions & 5 deletions backend/tests/endpoints/submissions_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,11 @@ def test_get_submission_correct(self, client: FlaskClient, session: Session):
assert response.status_code == 200
assert data["message"] == "Successfully fetched the submission"
assert data["data"] == {
"id": submission.submission_id,
"id": f"{API_HOST}/submissions/{submission.submission_id}",
"user": f"{API_HOST}/users/student01",
"project": f"{API_HOST}/projects/{project.project_id}",
"grading": 16,
"time": "Thu, 14 Mar 2024 12:00:00 GMT",
"path": "/submissions/1",
"status": 'SUCCESS'
}

Expand Down Expand Up @@ -117,12 +116,11 @@ def test_patch_submission_correct_teacher(self, client: FlaskClient, session: Se
assert data["message"] == f"Submission (submission_id={submission.submission_id}) patched"
assert data["url"] == f"{API_HOST}/submissions/{submission.submission_id}"
assert data["data"] == {
"id": submission.submission_id,
"id": f"{API_HOST}/submissions/{submission.submission_id}",
"user": f"{API_HOST}/users/student02",
"project": f"{API_HOST}/projects/{project.project_id}",
"grading": 20,
"time": 'Thu, 14 Mar 2024 23:59:59 GMT',
"path": "/submissions/2",
"status": 'FAIL'
}

Expand All @@ -144,7 +142,7 @@ def test_delete_submission_correct(self, client: FlaskClient, session: Session):
headers={"Authorization":"student01"})
data = response.json
assert response.status_code == 200
assert data["message"] == f"Submission (submission_id={submission.submission_id}) deleted"
assert data["message"] == "Resource deleted successfully"
assert submission.submission_id not in list(map(
lambda s: s.submission_id, session.query(Submission).all()
))
Loading