Source code for pykubegrader.initialize

import hashlib
import os
import shutil
from pathlib import Path
from typing import Optional

import panel as pn
import requests
from IPython.core.getipython import get_ipython

from .telemetry import ensure_responses, log_variable, telemetry, update_responses
from .utils import api_base_url


# TODO: could cleanup to remove redundant imports
[docs] def initialize_assignment( name: str, week: str, assignment_type: str, verbose: bool = False, assignment_points: Optional[float] = None, assignment_tag: Optional[str] = None, ) -> dict: """ Initialize an assignment in a Jupyter environment. Args: name (str): The name of the assignment. url (str): The URL of the API server. verbose (bool): Whether to print detailed initialization information. Returns: dict: The responses dictionary after initialization. Raises: Exception: If the environment is unsupported or initialization fails. """ if assignment_tag is None: assignment_tag = f"{week}-{assignment_type}" ipython = get_ipython() if ipython is None: raise Exception("Setup unsuccessful. Are you in a Jupyter environment?") try: move_dotfiles() ipython.events.register("pre_run_cell", telemetry) except Exception as e: raise Exception(f"Failed to register telemetry: {e}") jhub_user = os.getenv("JUPYTERHUB_USER") if jhub_user is None: raise Exception("Setup unsuccessful. Are you on JupyterHub?") try: seed = username_to_seed(jhub_user) % 1000 update_responses(key="seed", value=seed) update_responses(key="week", value=week) update_responses(key="assignment_type", value=assignment_type) update_responses(key="assignment", value=name) update_responses(key="jhub_user", value=jhub_user) # TODO: Check whether this is called correctly log_variable("Student Info", jhub_user, seed) responses = ensure_responses() # TODO: Add more checks here? assert isinstance(responses.get("seed"), int), "Seed not set" pn.extension(silent=True) # Check connection to API server if not api_base_url: raise Exception("Environment variable for API URL not set") params = {"jhub_user": responses["jhub_user"]} response = requests.get(api_base_url, params=params) if verbose: print(f"status code: {response.status_code}") data = response.json() for k, v in data.items(): print(f"{k}: {v}") except Exception as e: raise Exception(f"Failed to initialize assignment: {e}") log_variable("total-points", f"{assignment_tag}, {name}", assignment_points) print("Assignment successfully initialized") if verbose: print(f"Assignment: {name}") print(f"Username: {jhub_user}") return responses
# # Helper functions #
[docs] def move_dotfiles(): """ Move essential dotfiles from a fixed source directory to the current working directory. Raises: FileNotFoundError: If a source file is missing. Exception: If copying fails for any other reason. """ source_dir = Path("/opt/dotfiles") target_dir = Path.cwd() files_to_copy = [".client_private_key.bin", ".server_public_key.bin"] for file_name in files_to_copy: source_file = source_dir / file_name target_file = target_dir / file_name if not source_file.exists(): raise FileNotFoundError(f"Key file not found: {source_file}") try: shutil.copy2(source_file, target_file) except Exception as e: raise Exception(f"Failed to copy {source_file} to {target_file}: {e}")
[docs] def username_to_seed(username: str, mod: int = 1000) -> int: hash_object = hashlib.sha256(username.encode()) hash_hex = hash_object.hexdigest() hash_int = int(hash_hex, 16) return hash_int % mod