Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upload student notebook alongside submission API call #25

Merged
merged 3 commits into from
Oct 16, 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
15 changes: 9 additions & 6 deletions eduhelx_jupyterlab_student/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -247,28 +247,31 @@ async def post(self):
}))
return

current_assignment_path = student_repo.get_assignment_path(student_repo.current_assignment)
student_notebook_path = student_repo.current_assignment_path / student_repo.current_assignment["student_notebook_path"]
with open(student_notebook_path, "r") as f:
student_notebook_content = f.read()

rollback_id = get_head_commit_id(path=student_repo.repo_root)
stage_files(".", path=current_assignment_path)
stage_files(".", path=student_repo.current_assignment_path)

try:
commit_id = commit(
submission_summary,
submission_description if submission_description else None,
path=current_assignment_path
path=student_repo.current_assignment_path
)
except Exception as e:
# If the commit fails then unstage the assignment files.
git_reset(".", path=current_assignment_path)
git_reset(".", path=student_repo.current_assignment_path)
self.set_status(500)
self.finish(str(e))
return

try:
await self.api.create_submission(
student_repo.current_assignment["id"],
commit_id
commit_id,
student_notebook_content
)
except Exception as e:
# If the submission fails create in the API, rollback the local commit to the previous head.
Expand All @@ -281,7 +284,7 @@ async def post(self):
# so that we don't push the stages changes without actually creating a submission for the user
# (which would be very misleading)
try:
push(StudentClassRepo.ORIGIN_REMOTE_NAME, StudentClassRepo.MAIN_BRANCH_NAME, path=current_assignment_path)
push(StudentClassRepo.ORIGIN_REMOTE_NAME, StudentClassRepo.MAIN_BRANCH_NAME, path=student_repo.current_assignment_path)
self.finish()
except Exception as e:
# Need to rollback the commit if push failed too.
Expand Down
28 changes: 25 additions & 3 deletions eduhelx_jupyterlab_student/student_repo.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
class NotStudentClassRepositoryException(Exception):
pass

class NotInAnAssignmentException(Exception):
pass


""" Note: this class is naive to the fixed repo path. It is designed for
relative interaction with class repository filepaths WHILE inside the repository. """
Expand All @@ -28,18 +31,21 @@ def __init__(self, course, assignments, current_path):

self.repo_root = self._compute_repo_root(self.course["name"], self.current_path)
self.current_assignment = self._compute_current_assignment(self.assignments, self.repo_root, self.current_path)

@property
def current_assignment_path(self) -> Path | None:
if self.current_assignment is None: return None
return self.get_assignment_path(self.current_assignment)

def get_assignment_path(self, assignment):
return os.path.join(self.repo_root, assignment["directory_path"])
return self.repo_root / assignment["directory_path"]

def get_protected_file_paths(self, assignment) -> list[Path]:
files = []
for glob_pattern in assignment["protected_files"]:
files += self.get_assignment_path(assignment).glob(glob_pattern)
return files



@classmethod
def _compute_repo_root(cls, course_name, current_path: str | None = None):
""" Validates that user is in the repository root if current_path is provided """
Expand All @@ -65,3 +71,19 @@ def _compute_current_assignment(assignments, repo_root, current_path):
break

return current_assignment

@classmethod
def from_assignment_no_path(cls, course, assignments, assignment_id: int):
try:
assignment = [a for a in assignments if a["id"] == assignment_id][0]
except IndexError:
raise NotInAnAssignmentException

repo_root = cls._compute_repo_root(course["name"]).resolve()
assignment_path = repo_root / assignment["directory_path"]
frostyfan109 marked this conversation as resolved.
Show resolved Hide resolved

return cls(
course=course,
assignments=assignments,
current_path=assignment_path
)
Loading