""" This file has been automatically generated at 2024-12-17T07:34:12.053Z Name: Jutge API Version: 2.0.0 Description: Jutge API """ # In order to use this module, you should install its dependencies using pip: # python3 -m pip install requests requests-toolbelt pyyaml rich pydantic from __future__ import annotations import requests, yaml, json, os, sys, re from datetime import datetime from dataclasses import dataclass from pydantic import BaseModel, TypeAdapter, Field from pydantic_core import to_jsonable_python from typing import Any, TypeVar, Type, Optional, Union, IO from requests_toolbelt.multipart import decoder # type: ignore from rich.prompt import Prompt from rich.prompt import Confirm from rich import print JUTGE_API_URL = os.environ.get("JUTGE_API_URL", "https://api.jutge.org/api") # global variable to store the meta information _meta: Any = None # exceptions class UnauthorizedException(Exception): pass class InfoException(Exception): pass class NotFoundException(Exception): pass class InputException(Exception): pass class ProtocolException(Exception): pass @dataclass class Download: content: bytes name: str type: str def _build(x, t): try: return t.model_validate(x) except: try: return TypeAdapter(t).validate_python(x) except: return x def _debuild(x: Any) -> Any: if isinstance(x, BaseModel): return x.model_dump() elif isinstance(x, list): return [_debuild(v) for v in x] elif isinstance(x, dict): return {k: _debuild(v) for k, v in x.items()} else: return x def _raiseException(error: dict[str, Any], operation_id: str | None) -> None: # TODO: do something with operation_id message = error.get("message", "Unknown error") if error["name"] == "UnauthorizedError": raise UnauthorizedException(message) if error["name"] == "InfoError": raise InfoException(message) if error["name"] == "NotFoundError": raise NotFoundException(message) if error["name"] == "InputError": raise InputException(message) raise Exception("Unknown error") def _execute( func: str, input: Any, ifiles: list[IO] | None = None ) -> tuple[Any, list[Download]]: """Function that sends a request to the API and returns the response""" data = {"func": func, "input": input, "meta": _meta} files = {} if ifiles is not None: for i, ifile in enumerate(ifiles): files["file_" + str(i)] = ifile response = requests.post( JUTGE_API_URL, data={"data": json.dumps(data)}, files=files ) content_type = response.headers.get("content-type", "").split(";")[0].lower() if content_type == "multipart/form-data": ofiles = [] answer = None multipart_data = decoder.MultipartDecoder.from_response(response) for part in multipart_data.parts: def get(x: bytes) -> str: """Helper function to get a header from a part and decode it without warnings""" return part.headers.get(x, "").decode("utf-8") # type: ignore if b"Content-Type" in part.headers: filenames = re.findall('filename="(.+)"', get(b"Content-Disposition")) if len(filenames) != 1: raise ProtocolException("The part does not have a filename") filename = filenames[0] type = get(b"Content-Type") ofiles.append(Download(part.content, filename, type)) else: if answer is not None: raise ProtocolException( "There are multiple parts with JSON content" ) answer = json.loads(part.content) if not isinstance(answer, dict): raise ProtocolException("The answer is not an object") output = None if answer is None else answer.get("output", None) operation_id = None if answer is None else answer.get("operation_id", None) if "error" in answer: _raiseException(answer["error"], operation_id) return output, ofiles else: raise ProtocolException("The content type is not multipart/form-data") def login(silent: bool = False) -> None: """ Login to the API. """ path = os.path.expanduser("~/.jutge-client.yml") if os.path.exists(path): if not silent: print(f"[green]Credentials file found at {path}[/green]") file = open(path) config = yaml.safe_load(file) email = config["email"] password = config["password"] else: if silent: raise Exception( f"Cannot log in. No credentials file found at {path} and silent login requested." ) print("[yellow]Please enter your credentials for Jutge.org[/yellow]") email = Prompt.ask("Email") password = Prompt.ask("Password", password=True) try: credentials, _ = _execute("auth.login", {"email": email, "password": password}) except: if silent: raise Exception(f"Cannot log in. Please check your credentials.") print("[red]Cannot log in. Please check your credentials.[/red]") sys.exit(1) if not silent: print(f"[green]Logged in as {email}[/green]") if not os.path.exists(path): if Confirm.ask( f"[yellow]Do you want to save your credentials [underline]stored in plain text[/underline] at {path}?[/yellow]" ): with open(path, "w") as file: yaml.dump({"email": email, "password": password}, file) global _meta _meta = { "token": credentials["token"], "exam": None, } def logout(silent: bool = False) -> None: """ Logout to the API. """ global _meta try: _execute("auth.logout", None) except UnauthorizedException: pass except Exception as e: if not silent: print("[red]Error at log out[/red]") else: raise e finally: _meta = None if not silent: print(f"[green]Logged out[/green]") class util: @staticmethod def from_json[T](s: str, t: Type[T]) -> T: """Parse a JSON string into a Python object""" return TypeAdapter(t).validate_json(s) @staticmethod def to_json(obj: Any) -> str: """Convert a Python object into a JSON string""" return json.dumps(obj, default=to_jsonable_python, ensure_ascii=False) @staticmethod def json_to_yaml(s: str) -> str: """Convert a JSON string into a YAML string""" return yaml.dump(json.loads(s), allow_unicode=True, indent=4) @staticmethod def yaml_to_json(s: str) -> str: """Convert a YAML string into a JSON string""" return json.dumps(yaml.safe_load(s), ensure_ascii=False) @staticmethod def to_yaml(obj: Any) -> str: """Convert a Python object into a YAML string""" return util.json_to_yaml(util.to_json(obj)) @staticmethod def from_yaml[T](s: str, t: Type[T]) -> T: """Convert a YAML string into a Python object""" return util.from_json(util.yaml_to_json(s), t) class CredentialsIn(BaseModel): email: str password: str class CredentialsOut(BaseModel): token: str expiration: datetime user_uid: str class Time(BaseModel): full_time: str int_timestamp: int float_timestamp: float time: str date: str class HomepageStats(BaseModel): users: int problems: int submissions: int class Language(BaseModel): language_id: str eng_name: str # English name of the language own_name: str # Name of the language in its own language type Languages = dict[str, Language] class Country(BaseModel): country_id: str eng_name: str # English name of the country type Countries = dict[str, Country] class Compiler(BaseModel): compiler_id: str name: str language: str extension: str description: Optional[str] version: Optional[str] flags1: Optional[str] flags2: Optional[str] type: Optional[str] warning: Optional[str] status: Optional[str] notes: Optional[str] type Compilers = dict[str, Compiler] class Driver(BaseModel): driver_id: str type Drivers = dict[str, Driver] class Verdict(BaseModel): verdict_id: str name: str description: str type Verdicts = dict[str, Verdict] class Proglang(BaseModel): proglang_id: str type Proglangs = dict[str, Proglang] class Tables(BaseModel): languages: Languages countries: Countries compilers: Compilers drivers: Drivers verdicts: Verdicts proglangs: Proglangs class BriefAbstractProblem(BaseModel): problem_nm: str author: Optional[str] author_email: Optional[str] public: Optional[int] official: Optional[int] compilers: Optional[str] driver_id: Optional[str] type: Optional[str] deprecation: Optional[str] class BriefProblem(BaseModel): problem_id: str problem_nm: str language_id: str title: str original_language_id: str translator: Optional[str] translator_email: Optional[str] checked: Optional[int] type BriefProblemDict = dict[str, BriefProblem] class AbstractProblem(BaseModel): problem_nm: str author: Optional[str] author_email: Optional[str] public: Optional[int] official: Optional[int] compilers: Optional[str] driver_id: Optional[str] type: Optional[str] deprecation: Optional[str] problems: BriefProblemDict class Problem(BaseModel): problem_id: str problem_nm: str language_id: str title: str original_language_id: str translator: Optional[str] translator_email: Optional[str] checked: Optional[int] abstract_problem: BriefAbstractProblem type AbstractProblems = dict[str, AbstractProblem] class AbstractProblemExtras(BaseModel): compilers_with_ac: list[str] proglangs_with_ac: list[str] class ProblemExtras(BaseModel): compilers_with_ac: list[str] proglangs_with_ac: list[str] official_solution_checks: dict[str, bool] handler: Any class Testcase(BaseModel): name: str input_b64: str correct_b64: str type Testcases = list[Testcase] class AllKeys(BaseModel): problems: list[str] enrolled_courses: list[str] available_courses: list[str] lists: list[str] class Profile(BaseModel): """ Profile """ user_uid: str email: str name: str username: Optional[str] nickname: Optional[str] webpage: Optional[str] description: Optional[str] affiliation: Optional[str] birth_year: int max_subsxhour: int max_subsxday: int administrator: int instructor: int parent_email: Optional[str] country_id: Optional[str] timezone_id: str compiler_id: Optional[str] language_id: Optional[str] class NewProfile(BaseModel): name: str birth_year: int nickname: str webpage: str affiliation: str description: str country_id: str timezone_id: str class PasswordUpdate(BaseModel): oldPassword: str newPassword: str class TypeA(BaseModel): a: str class TypeB(BaseModel): a: str class DateValue(BaseModel): date: int value: int type HeatmapCalendar = list[DateValue] type Distribution = dict[str, int] class Distributions(BaseModel): verdicts: Distribution compilers: Distribution proglangs: Distribution submissions_by_hour: Distribution submissions_by_weekday: Distribution type DashboardStats = dict[str, Union[int, str]] class Dashboard(BaseModel): stats: DashboardStats heatmap: HeatmapCalendar distributions: Distributions class Submission(BaseModel): problem_id: str submission_id: str compiler_id: str annotation: Optional[str] state: str time_in: datetime veredict: Optional[str] veredict_info: Optional[str] veredict_publics: Optional[str] ok_publics_but_wrong: int type Submissions = list[Submission] type DictSubmissions = dict[str, Submission] type DictDictSubmissions = dict[str, DictSubmissions] class SubmissionPostOut(BaseModel): submission_id: str class PublicProfile(BaseModel): email: str name: str username: Optional[str] class BriefCourse(BaseModel): course_nm: str title: Optional[str] description: Optional[str] annotation: Optional[str] public: int official: int type BriefCourses = dict[str, BriefCourse] class Course(BaseModel): course_nm: str title: Optional[str] description: Optional[str] annotation: Optional[str] public: int official: int owner: PublicProfile lists: list[str] class ListItem(BaseModel): problem_nm: Optional[str] description: Optional[str] type ListItems = list[ListItem] class BriefList(BaseModel): list_nm: str title: Optional[str] description: Optional[str] annotation: Optional[str] public: int official: int type BriefLists = dict[str, BriefList] class List(BaseModel): list_nm: str title: Optional[str] description: Optional[str] annotation: Optional[str] public: int official: int items: ListItems owner: PublicProfile class AbstractStatus(BaseModel): problem_nm: str nb_submissions: int nb_pending_submissions: int nb_accepted_submissions: int nb_rejected_submissions: int nb_scored_submissions: int status: str type AbstractStatuses = dict[str, AbstractStatus] class Status(BaseModel): problem_id: str problem_nm: str nb_submissions: int nb_pending_submissions: int nb_accepted_submissions: int nb_rejected_submissions: int nb_scored_submissions: int status: str class Award(BaseModel): award_id: str time: datetime type: str icon: str title: str info: str youtube: Optional[str] submission: Optional[Submission] class BriefAward(BaseModel): award_id: str time: datetime type: str icon: str title: str info: str youtube: Optional[str] type BriefAwards = dict[str, BriefAward] type TagsDict = dict[str, list[str]] class Document(BaseModel): document_nm: str # Document name title: str # The title of the document description: str = Field(default="", description="The description of the document") type Documents = list[Document] class InstructorList(BaseModel): list_nm: str # The name of the list title: str # The title of the list description: str = Field(default="", description="The description of the list") annotation: str = Field( default="", description="Additional private annotations for the list" ) official: int = Field( default=0, description="Indicates if the list is official (1) or not (0) TODO" ) public: int = Field( default=0, description="Indicates if the list is public (1) or private (0) TODO" ) type InstructorLists = list[InstructorList] class InstructorListItem(BaseModel): """ Provide a problem_nm or a description, not both or none """ problem_nm: Optional[str] description: Optional[str] type InstructorListItems = list[InstructorListItem] class InstructorListWithItems(BaseModel): list_nm: str # The name of the list title: str # The title of the list description: str = Field(default="", description="The description of the list") annotation: str = Field( default="", description="Additional private annotations for the list" ) official: int = Field( default=0, description="Indicates if the list is official (1) or not (0) TODO" ) public: int = Field( default=0, description="Indicates if the list is public (1) or private (0) TODO" ) items: InstructorListItems class InstructorCourse(BaseModel): course_nm: str # The name of the course title: str # The title of the course description: str = Field(default="", description="The description of the course") annotation: str = Field( default="", description="Additional private annotations for the course" ) official: int = Field( default=0, description="Indicates if the course is official (1) or not (0) TODO" ) public: int = Field( default=0, description="Indicates if the course is public (1) or private (0) TODO", ) type InstructorCourses = list[InstructorCourse] class CourseMembers(BaseModel): invited: list[str] enrolled: list[str] pending: list[str] class InstructorCourseWithItems(BaseModel): course_nm: str # The name of the course title: str # The title of the course description: str = Field(default="", description="The description of the course") annotation: str = Field( default="", description="Additional private annotations for the course" ) official: int = Field( default=0, description="Indicates if the course is official (1) or not (0) TODO" ) public: int = Field( default=0, description="Indicates if the course is public (1) or private (0) TODO", ) lists: list[str] students: CourseMembers tutors: CourseMembers class InstructorExam(BaseModel): exam_nm: str title: str place: Optional[str] description: Optional[str] code: Optional[str] time_start: Optional[datetime] exp_time_start: datetime running_time: int visible_submissions: int started_by: Optional[str] contest: int instructions: Optional[str] avatars: Optional[str] anonymous: int type InstructorExams = list[InstructorExam] class InstructorExamCourse(BaseModel): title: str description: str course_nm: str annotation: str class InstructorExamDocument(BaseModel): document_nm: str title: str description: str type InstructorExamDocuments = list[InstructorExamDocument] class InstructorExamProblem(BaseModel): problem_nm: str weight: Optional[float] icon: Optional[str] caption: Optional[str] type InstructorExamProblems = list[InstructorExamProblem] class InstructorExamStudent(BaseModel): email: str name: str code: Optional[str] restricted: int annotation: Optional[str] result: Optional[str] finished: int banned: int reason_ban: Optional[str] inc: Optional[int] reason_inc: Optional[str] taken_exam: int emergency_password: Optional[str] invited: int type InstructorExamStudents = list[InstructorExamStudent] class InstructorExamWithItems(BaseModel): exam_nm: str title: str place: Optional[str] description: Optional[str] code: Optional[str] time_start: Optional[datetime] exp_time_start: datetime running_time: int visible_submissions: int started_by: Optional[str] contest: int instructions: Optional[str] avatars: Optional[str] anonymous: int course: InstructorExamCourse documents: InstructorExamDocuments problems: InstructorExamProblems students: InstructorExamStudents class InstructorExamCreation(BaseModel): exam_nm: str course_nm: str title: str place: str = Field(default="") description: str = Field(default="") instructions: str = Field(default="") exp_time_start: str running_time: int contest: int = Field(default=0) class InstructorExamStudentPost(BaseModel): email: str invited: int = Field(default=0) restricted: int = Field(default=0) code: str = Field(default="") emergency_password: str = Field(default="") annotation: str = Field(default="") type InstructorExamStudentsPost = list[InstructorExamStudentPost] class InstructorExamSubmissionsOptions(BaseModel): problems: str = Field( default="all", description="Comma-separated list of problem names (without language). Use `all` to include all problems.", ) include_source: bool = Field(default=True, description="Include source code") include_pdf: bool = Field( default=True, description="Include source code formated in PDF" ) include_metadata: bool = Field( default=True, description="Include metadata in the code" ) only_last: bool = Field( default=True, description="Only include last submission of each problem for each student", ) class Pack(BaseModel): message: str href: str class SubmissionQuery(BaseModel): email: str problem_nm: str problem_id: str time: datetime ip: str verdict: str type SubmissionsQuery = list[SubmissionQuery] class UserCreation(BaseModel): email: str name: str username: str password: str administrator: float = Field(default=0) instructor: float = Field(default=0) class UpcomingExam(BaseModel): exam_nm: str title: str username: str exp_start_time: datetime duration: int name: str type UpcomingExams = list[UpcomingExam] class UserRankingEntry(BaseModel): user_id: str nickname: Optional[str] email: str name: str problems: int type UserRanking = list[UserRankingEntry] class TwoFloats(BaseModel): a: float b: float class TwoInts(BaseModel): a: int b: int class Name(BaseModel): name: str class auth: @staticmethod def login(data: CredentialsIn) -> CredentialsOut: """ Login: Get an access token """ output, ofiles = _execute("auth.login", _debuild(data)) return _build(output, CredentialsOut) @staticmethod def logout() -> None: """ Logout: Discard access token 🔐 Authenticated """ output, ofiles = _execute("auth.logout", None) return output class misc: @staticmethod def get_fortune() -> str: """ Get a fortune message """ output, ofiles = _execute("misc.getFortune", None) return output @staticmethod def get_time() -> Time: """ Get server time """ output, ofiles = _execute("misc.getTime", None) return _build(output, Time) @staticmethod def get_homepage_stats() -> HomepageStats: """ Get homepage stats """ output, ofiles = _execute("misc.getHomepageStats", None) return _build(output, HomepageStats) @staticmethod def get_logo() -> Download: """ Get Jutge.org logo as a PNG file """ output, ofiles = _execute("misc.getLogo", None) return ofiles[0] class tables: @staticmethod def get_languages() -> Languages: """ Returns all languages Returns all languages as a dictionary of objects, indexed by id. """ output, ofiles = _execute("tables.getLanguages", None) return _build(output, Languages) @staticmethod def get_countries() -> Countries: """ Returns all countries Returns all countries as a dictionary of objects, indexed by id. """ output, ofiles = _execute("tables.getCountries", None) return _build(output, Countries) @staticmethod def get_compilers() -> Compilers: """ Returns all compilers Returns all compilers as a dictionary of objects, indexed by id. """ output, ofiles = _execute("tables.getCompilers", None) return _build(output, Compilers) @staticmethod def get_drivers() -> Drivers: """ Returns all drivers Returns all drivers as a dictionary of objects, indexed by id. """ output, ofiles = _execute("tables.getDrivers", None) return _build(output, Drivers) @staticmethod def get_verdicts() -> Verdicts: """ Returns all verdicts Returns all verdicts as a dictionary of objects, indexed by id. """ output, ofiles = _execute("tables.getVerdicts", None) return _build(output, Verdicts) @staticmethod def get_proglangs() -> Proglangs: """ Returns all proglangs Returns all proglangs as a dictionary of objects, indexed by id. """ output, ofiles = _execute("tables.getProglangs", None) return _build(output, Proglangs) @staticmethod def get_all() -> Tables: """ Returns all tables Returns all compilers, countries, drivers, languages, proglangs, and verdicts in a single request. This data does not change often, so you should only request it once per session. """ output, ofiles = _execute("tables.getAll", None) return _build(output, Tables) class problems: @staticmethod def get_all_abstract_problems() -> AbstractProblems: """ Get all available abstract problems 🔐 Authenticated Includes problems. """ output, ofiles = _execute("problems.getAllAbstractProblems", None) return _build(output, AbstractProblems) @staticmethod def get_abstract_problems(problem_nms: str) -> AbstractProblems: """ Get available abstract problems whose keys are in `problem_nms` (comma separated list) 🔐 Authenticated Includes problems. """ output, ofiles = _execute("problems.getAbstractProblems", _debuild(problem_nms)) return _build(output, AbstractProblems) @staticmethod def get_abstract_problems_in_list(list_key: str) -> AbstractProblems: """ Get available abstract problems that belong to a list 🔐 Authenticated Includes problems. """ output, ofiles = _execute( "problems.getAbstractProblemsInList", _debuild(list_key) ) return _build(output, AbstractProblems) @staticmethod def get_abstract_problem(problem_nm: str) -> AbstractProblem: """ Get an abstract problem 🔐 Authenticated Includes owner and problems """ output, ofiles = _execute("problems.getAbstractProblem", _debuild(problem_nm)) return _build(output, AbstractProblem) @staticmethod def get_abstract_problem_extras(problem_nm: str) -> AbstractProblemExtras: """ Get extras of an abstract problem 🔐 Authenticated Includes accepted compilers and accepted proglangs """ output, ofiles = _execute( "problems.getAbstractProblemExtras", _debuild(problem_nm) ) return _build(output, AbstractProblemExtras) @staticmethod def get_problem(problem_id: str) -> Problem: """ Get a problem 🔐 Authenticated Includes abstract problem, which includes owner """ output, ofiles = _execute("problems.getProblem", _debuild(problem_id)) return _build(output, Problem) @staticmethod def get_problem_extras(problem_id: str) -> ProblemExtras: """ Get extras of a problem. 🔐 Authenticated Includes accepted compilers, accepted proglangs, official solutions checks and handler specifications """ output, ofiles = _execute("problems.getProblemExtras", _debuild(problem_id)) return _build(output, ProblemExtras) @staticmethod def get_sample_testcases(problem_id: str) -> Testcases: """ Get sample testcases of a problem. 🔐 Authenticated """ output, ofiles = _execute("problems.getSampleTestcases", _debuild(problem_id)) return _build(output, Testcases) @staticmethod def get_public_testcases(problem_id: str) -> Testcases: """ Get public testcases of a problem. 🔐 Authenticated Public testcases are like sample testcases, but are not meant to be show in the problem statatement, because of their long length. """ output, ofiles = _execute("problems.getPublicTestcases", _debuild(problem_id)) return _build(output, Testcases) @staticmethod def get_html_statement(problem_id: str) -> str: """ Get Html statement of a problem. 🔐 Authenticated Currently, this is suboptimal, but I already know how to improve it. """ output, ofiles = _execute("problems.getHtmlStatement", _debuild(problem_id)) return output @staticmethod def get_text_statement(problem_id: str) -> str: """ Get Text statement of a problem. 🔐 Authenticated """ output, ofiles = _execute("problems.getTextStatement", _debuild(problem_id)) return output @staticmethod def get_markdown_statement(problem_id: str) -> str: """ Get Markdown statement of a problem. 🔐 Authenticated """ output, ofiles = _execute("problems.getMarkdownStatement", _debuild(problem_id)) return output @staticmethod def get_pdf_statement(problem_id: str) -> Download: """ Get PDF statement of a problem. 🔐 Authenticated """ output, ofiles = _execute("problems.getPdfStatement", _debuild(problem_id)) return ofiles[0] @staticmethod def get_zip_statement(problem_id: str) -> Download: """ Get ZIP archive of a problem. 🔐 Authenticated """ output, ofiles = _execute("problems.getZipStatement", _debuild(problem_id)) return ofiles[0] class student: class keys: @staticmethod def get_all() -> AllKeys: """ Get problem, courses (enrolled and available) and list keys. 🔐 Authenticated """ output, ofiles = _execute("student.keys.getAll", None) return _build(output, AllKeys) @staticmethod def get_problems() -> list[str]: """ Get problem keys. 🔐 Authenticated """ output, ofiles = _execute("student.keys.getProblems", None) return output @staticmethod def get_enrolled_courses() -> list[str]: """ Get enrolled course keys. 🔐 Authenticated """ output, ofiles = _execute("student.keys.getEnrolledCourses", None) return output @staticmethod def get_available_courses() -> list[str]: """ Get available course keys. 🔐 Authenticated """ output, ofiles = _execute("student.keys.getAvailableCourses", None) return output @staticmethod def get_lists() -> list[str]: """ Get list keys. 🔐 Authenticated """ output, ofiles = _execute("student.keys.getLists", None) return output class profile: @staticmethod def get() -> Profile: """ Get the profile. 🔐 Authenticated """ output, ofiles = _execute("student.profile.get", None) return _build(output, Profile) @staticmethod def update(data: NewProfile) -> None: """ Update the profile 🔐 Authenticated """ output, ofiles = _execute("student.profile.update", _debuild(data)) return output @staticmethod def get_avatar() -> Download: """ Returns the avatar as a PNG file. 🔐 Authenticated """ output, ofiles = _execute("student.profile.getAvatar", None) return ofiles[0] @staticmethod def set_avatar(ifile: IO) -> None: """ Set a PNG file as avatar 🔐 Authenticated """ output, ofiles = _execute("student.profile.setAvatar", None, [ifile]) return output @staticmethod def change_password(data: PasswordUpdate) -> None: """ Change password 🔐 Authenticated Receives the old password and the new one, and changes the password if the old one is correct """ output, ofiles = _execute("student.profile.changePassword", _debuild(data)) return output class dashboard: @staticmethod def get_all_distributions() -> Distributions: """ Get all distributions 🔐 Authenticated """ output, ofiles = _execute("student.dashboard.getAllDistributions", None) return _build(output, Distributions) @staticmethod def get_compilers_distribution() -> Distribution: """ Get compilers distribution 🔐 Authenticated """ output, ofiles = _execute( "student.dashboard.getCompilersDistribution", None ) return _build(output, Distribution) @staticmethod def get_dashboard() -> Dashboard: """ Get dashboard 🔐 Authenticated """ output, ofiles = _execute("student.dashboard.getDashboard", None) return _build(output, Dashboard) @staticmethod def get_heatmap_calendar() -> HeatmapCalendar: """ Get heatmap calendar of submissions 🔐 Authenticated """ output, ofiles = _execute("student.dashboard.getHeatmapCalendar", None) return _build(output, HeatmapCalendar) @staticmethod def get_proglangs_distribution() -> Distribution: """ Get programming languages distribution 🔐 Authenticated """ output, ofiles = _execute( "student.dashboard.getProglangsDistribution", None ) return _build(output, Distribution) @staticmethod def get_stats() -> DashboardStats: """ Get dashboard stats 🔐 Authenticated """ output, ofiles = _execute("student.dashboard.getStats", None) return _build(output, DashboardStats) @staticmethod def get_submissions_by_hour() -> Distribution: """ Get submissions by hour distribution 🔐 Authenticated """ output, ofiles = _execute("student.dashboard.getSubmissionsByHour", None) return _build(output, Distribution) @staticmethod def get_submissions_by_week_day() -> Distribution: """ Get submissions by weekday distribution 🔐 Authenticated """ output, ofiles = _execute("student.dashboard.getSubmissionsByWeekDay", None) return _build(output, Distribution) @staticmethod def get_verdicts_distribution() -> Distribution: """ Get verdicts distribution 🔐 Authenticated """ output, ofiles = _execute("student.dashboard.getVerdictsDistribution", None) return _build(output, Distribution) class submissions: @staticmethod def get_all() -> Submissions: """ Get all submissions. 🔐 Authenticated Flat array of submissions in chronological order. """ output, ofiles = _execute("student.submissions.getAll", None) return _build(output, Submissions) @staticmethod def get_for_abstract_problem(problem_nm: str) -> DictDictSubmissions: """ Get all submissions for an abstract problem. 🔐 Authenticated Grouped by problem. """ output, ofiles = _execute( "student.submissions.getForAbstractProblem", _debuild(problem_nm) ) return _build(output, DictDictSubmissions) @staticmethod def get_for_problem(problem_id: str) -> DictSubmissions: """ Get all submissions for a problem. 🔐 Authenticated """ output, ofiles = _execute( "student.submissions.getForProblem", _debuild(problem_id) ) return _build(output, DictSubmissions) @staticmethod def get(problem_id: str, submission_id: str) -> Submission: """ Get a submission. 🔐 Authenticated """ data = {"problem_id": problem_id, "submission_id": submission_id} output, ofiles = _execute("student.submissions.get", _debuild(data)) return _build(output, Submission) @staticmethod def submit( problem_id: str, compiler_id: str, annotation: str, ifile: IO ) -> SubmissionPostOut: """ Perform a submission. 🔐 Authenticated """ data = { "problem_id": problem_id, "compiler_id": compiler_id, "annotation": annotation, } output, ofiles = _execute( "student.submissions.submit", _debuild(data), [ifile] ) return _build(output, SubmissionPostOut) class courses: @staticmethod def get_all_available() -> BriefCourses: """ Get all available courses. 🔐 Authenticated """ output, ofiles = _execute("student.courses.getAllAvailable", None) return _build(output, BriefCourses) @staticmethod def get_all_enrolled() -> BriefCourses: """ Get all enrolled courses. 🔐 Authenticated """ output, ofiles = _execute("student.courses.getAllEnrolled", None) return _build(output, BriefCourses) @staticmethod def get_available(course_key: str) -> Course: """ Get an available course. 🔐 Authenticated Includes owner and lists. """ output, ofiles = _execute( "student.courses.getAvailable", _debuild(course_key) ) return _build(output, Course) @staticmethod def get_enrolled(course_key: str) -> Course: """ Get an enrolled course. 🔐 Authenticated Includes owner and lists. """ output, ofiles = _execute( "student.courses.getEnrolled", _debuild(course_key) ) return _build(output, Course) @staticmethod def enroll(course_key: str) -> None: """ Enroll in an available course. 🔐 Authenticated """ output, ofiles = _execute("student.courses.enroll", _debuild(course_key)) return output @staticmethod def unenroll(course_key: str) -> None: """ Unenroll from an enrolled course. 🔐 Authenticated """ output, ofiles = _execute("student.courses.unenroll", _debuild(course_key)) return output class lists: @staticmethod def get_all() -> BriefLists: """ Get all lists. 🔐 Authenticated """ output, ofiles = _execute("student.lists.getAll", None) return _build(output, BriefLists) @staticmethod def get(list_key: str) -> List: """ Get a list. 🔐 Authenticated Includes items, owner. """ output, ofiles = _execute("student.lists.get", _debuild(list_key)) return _build(output, List) class statuses: @staticmethod def get_all() -> AbstractStatuses: """ Get statuses for all problems. 🔐 Authenticated """ output, ofiles = _execute("student.statuses.getAll", None) return _build(output, AbstractStatuses) @staticmethod def get_for_abstract_problem(problem_nm: str) -> AbstractStatus: """ Get status for an abstract problem. 🔐 Authenticated """ output, ofiles = _execute( "student.statuses.getForAbstractProblem", _debuild(problem_nm) ) return _build(output, AbstractStatus) @staticmethod def get_for_problem(problem_id: str) -> Status: """ Get status for a problem. 🔐 Authenticated """ output, ofiles = _execute( "student.statuses.getForProblem", _debuild(problem_id) ) return _build(output, Status) class awards: @staticmethod def get_all() -> BriefAwards: """ Get all awards. 🔐 Authenticated """ output, ofiles = _execute("student.awards.getAll", None) return _build(output, BriefAwards) @staticmethod def get(award_id: str) -> Award: """ Get an award. 🔐 Authenticated """ output, ofiles = _execute("student.awards.get", _debuild(award_id)) return _build(output, Award) class instructor: class tags: @staticmethod def get_all() -> list[str]: """ Get all tags 🔐 Authenticated """ output, ofiles = _execute("instructor.tags.getAll", None) return output @staticmethod def get_dict() -> TagsDict: """ Get all tags with their problems 🔐 Authenticated """ output, ofiles = _execute("instructor.tags.getDict", None) return _build(output, TagsDict) @staticmethod def get(tag: str) -> list[str]: """ Get all problems with a given tag 🔐 Authenticated """ output, ofiles = _execute("instructor.tags.get", _debuild(tag)) return output class documents: @staticmethod def index() -> Documents: """ Get index of all documents 🔐 Authenticated """ output, ofiles = _execute("instructor.documents.index", None) return _build(output, Documents) @staticmethod def get(document_nm: str) -> Document: """ Get a document (without PDF) 🔐 Authenticated """ output, ofiles = _execute("instructor.documents.get", _debuild(document_nm)) return _build(output, Document) @staticmethod def get_pdf(document_nm: str) -> Download: """ Get PDF of a document 🔐 Authenticated """ output, ofiles = _execute( "instructor.documents.getPdf", _debuild(document_nm) ) return ofiles[0] @staticmethod def create(data: Document, ifile: IO) -> None: """ Create a new document 🔐 Authenticated """ output, ofiles = _execute( "instructor.documents.create", _debuild(data), [ifile] ) return output @staticmethod def update(data: Document) -> None: """ Update a document (without PDF) 🔐 Authenticated """ output, ofiles = _execute("instructor.documents.update", _debuild(data)) return output @staticmethod def update_pdf(document_nm: str, ifile: IO) -> None: """ Update PDF of a document 🔐 Authenticated """ output, ofiles = _execute( "instructor.documents.updatePdf", _debuild(document_nm), [ifile] ) return output @staticmethod def remove(document_nm: str) -> None: """ Remove a document (including PDF) 🔐 Authenticated """ output, ofiles = _execute( "instructor.documents.remove", _debuild(document_nm) ) return output class lists: @staticmethod def index() -> InstructorLists: """ Get index of all lists 🔐 Authenticated """ output, ofiles = _execute("instructor.lists.index", None) return _build(output, InstructorLists) @staticmethod def get(list_nm: str) -> InstructorListWithItems: """ Get a list with its items 🔐 Authenticated """ output, ofiles = _execute("instructor.lists.get", _debuild(list_nm)) return _build(output, InstructorListWithItems) @staticmethod def get_items(list_nm: str) -> InstructorListItems: """ Get the items of a list 🔐 Authenticated """ output, ofiles = _execute("instructor.lists.getItems", _debuild(list_nm)) return _build(output, InstructorListItems) @staticmethod def create(data: InstructorList) -> None: """ Create a new list 🔐 Authenticated """ output, ofiles = _execute("instructor.lists.create", _debuild(data)) return output @staticmethod def update(data: InstructorList) -> None: """ Update an existing list 🔐 Authenticated """ output, ofiles = _execute("instructor.lists.update", _debuild(data)) return output @staticmethod def remove(list_nm: str) -> None: """ Delete an existing list 🔐 Authenticated """ output, ofiles = _execute("instructor.lists.remove", _debuild(list_nm)) return output @staticmethod def set_items(list_nm: str, items: InstructorListItems) -> None: """ Set the items of a list 🔐 Authenticated """ data = {"list_nm": list_nm, "items": items} output, ofiles = _execute("instructor.lists.setItems", _debuild(data)) return output class courses: @staticmethod def index() -> InstructorCourses: """ Get index of all courses 🔐 Authenticated """ output, ofiles = _execute("instructor.courses.index", None) return _build(output, InstructorCourses) @staticmethod def get(course_nm: str) -> InstructorCourseWithItems: """ Get a course with its items (lists, courses and tutors) 🔐 Authenticated """ output, ofiles = _execute("instructor.courses.get", _debuild(course_nm)) return _build(output, InstructorCourseWithItems) @staticmethod def get_lists(course_nm: str) -> list[str]: """ Get lists of a course 🔐 Authenticated """ output, ofiles = _execute( "instructor.courses.getLists", _debuild(course_nm) ) return output @staticmethod def get_students(course_nm: str) -> CourseMembers: """ Get students of a course 🔐 Authenticated """ output, ofiles = _execute( "instructor.courses.getStudents", _debuild(course_nm) ) return _build(output, CourseMembers) @staticmethod def get_tutors(course_nm: str) -> CourseMembers: """ Get tutors of a course 🔐 Authenticated """ output, ofiles = _execute( "instructor.courses.getTutors", _debuild(course_nm) ) return _build(output, CourseMembers) @staticmethod def create(data: InstructorCourse) -> None: """ Create a new course 🔐 Authenticated """ output, ofiles = _execute("instructor.courses.create", _debuild(data)) return output @staticmethod def update(data: InstructorCourse) -> None: """ Update an existing course 🔐 Authenticated """ output, ofiles = _execute("instructor.courses.update", _debuild(data)) return output @staticmethod def remove(course_nm: str) -> None: """ Delete an existing course 🔐 Authenticated Note: A course should not be deleted. Ask a system administrator to remove it. """ output, ofiles = _execute("instructor.courses.remove", _debuild(course_nm)) return output @staticmethod def set_lists(course_nm: str, lists: list[str]) -> None: """ Set lists of a course 🔐 Authenticated """ data = {"course_nm": course_nm, "lists": lists} output, ofiles = _execute("instructor.courses.set_lists", _debuild(data)) return output @staticmethod def invite_students(course_nm: str, emails: list[str]) -> None: """ Invite students to a course 🔐 Authenticated """ data = {"course_nm": course_nm, "emails": emails} output, ofiles = _execute( "instructor.courses.invite_students", _debuild(data) ) return output @staticmethod def invite_tutors(course_nm: str, emails: list[str]) -> None: """ Invite tutors to a course 🔐 Authenticated """ data = {"course_nm": course_nm, "emails": emails} output, ofiles = _execute( "instructor.courses.invite_tutors", _debuild(data) ) return output @staticmethod def remove_students(course_nm: str, emails: list[str]) -> None: """ Remove students from a course 🔐 Authenticated """ data = {"course_nm": course_nm, "emails": emails} output, ofiles = _execute( "instructor.courses.remove_students", _debuild(data) ) return output @staticmethod def remove_tutors(course_nm: str, emails: list[str]) -> None: """ Remove tutors from a course 🔐 Authenticated """ data = {"course_nm": course_nm, "emails": emails} output, ofiles = _execute( "instructor.courses.remove_tutors", _debuild(data) ) return output class exams: @staticmethod def index() -> InstructorExams: """ Get index of all exams 🔐 Authenticated """ output, ofiles = _execute("instructor.exams.index", None) return _build(output, InstructorExams) @staticmethod def get(exam_nm: str) -> InstructorExamWithItems: """ Get an exam with its items (course, problems, documents, students) 🔐 Authenticated """ output, ofiles = _execute("instructor.exams.get", _debuild(exam_nm)) return _build(output, InstructorExamWithItems) @staticmethod def create(data: InstructorExamCreation) -> None: """ Create a new exam 🔐 Authenticated """ output, ofiles = _execute("instructor.exams.create", _debuild(data)) return output @staticmethod def update(data: InstructorExamCreation) -> None: """ Update an existing exam 🔐 Authenticated """ output, ofiles = _execute("instructor.exams.update", _debuild(data)) return output @staticmethod def remove(exam_nm: str) -> None: """ Delete an existing exam 🔐 Authenticated Note: An exam can only be deleted if it has not started. """ output, ofiles = _execute("instructor.exams.remove", _debuild(exam_nm)) return output @staticmethod def get_documents(exam_nm: str) -> InstructorExamDocuments: """ Get documents of an exam 🔐 Authenticated """ output, ofiles = _execute( "instructor.exams.getDocuments", _debuild(exam_nm) ) return _build(output, InstructorExamDocuments) @staticmethod def get_course(exam_nm: str) -> InstructorExamCourse: """ Get course of an exam 🔐 Authenticated """ output, ofiles = _execute("instructor.exams.getCourse", _debuild(exam_nm)) return _build(output, InstructorExamCourse) @staticmethod def get_problems(exam_nm: str) -> InstructorExamProblems: """ Get problems of an exam 🔐 Authenticated """ output, ofiles = _execute("instructor.exams.getProblems", _debuild(exam_nm)) return _build(output, InstructorExamProblems) @staticmethod def get_students(exam_nm: str) -> InstructorExamStudents: """ Get students of an exam 🔐 Authenticated """ output, ofiles = _execute("instructor.exams.getStudents", _debuild(exam_nm)) return _build(output, InstructorExamStudents) @staticmethod def get_student(exam_nm: str, email: str) -> InstructorExamStudent: """ Get an student of an exam 🔐 Authenticated """ data = {"exam_nm": exam_nm, "email": email} output, ofiles = _execute("instructor.exams.getStudent", _debuild(data)) return _build(output, InstructorExamStudent) @staticmethod def get_submissions( exam_nm: str, options: InstructorExamSubmissionsOptions ) -> Pack: """ Get submissions of an exam 🔐 Authenticated This endpoint prepares a ZIP file to download the submissions of an exam. Preparing the ZIP file takes some time, an href link to the ZIP will be returned. This ZIP file will be available for download for a limited time. """ data = {"exam_nm": exam_nm, "options": options} output, ofiles = _execute("instructor.exams.getSubmissions", _debuild(data)) return _build(output, Pack) @staticmethod def set_documents(exam_nm: str, document_nms: list[str]) -> None: """ Set documents of an exam 🔐 Authenticated """ data = {"exam_nm": exam_nm, "document_nms": document_nms} output, ofiles = _execute("instructor.exams.setDocuments", _debuild(data)) return output @staticmethod def set_problems(exam_nm: str, problems: InstructorExamProblems) -> None: """ Set problems of an exam 🔐 Authenticated """ data = {"exam_nm": exam_nm, "problems": problems} output, ofiles = _execute("instructor.exams.setProblems", _debuild(data)) return output @staticmethod def set_students(exam_nm: str, students: InstructorExamStudentsPost) -> None: """ Set students of an exam 🔐 Authenticated """ data = {"exam_nm": exam_nm, "students": students} output, ofiles = _execute("instructor.exams.setStudents", _debuild(data)) return output @staticmethod def add_students(exam_nm: str, students: InstructorExamStudentsPost) -> None: """ Add students to an exam 🔐 Authenticated """ data = {"exam_nm": exam_nm, "students": students} output, ofiles = _execute("instructor.exams.addStudents", _debuild(data)) return output @staticmethod def remove_students(exam_nm: str, emails: list[str]) -> None: """ Remove students from an exam 🔐 Authenticated """ data = {"exam_nm": exam_nm, "emails": emails} output, ofiles = _execute("instructor.exams.removeStudents", _debuild(data)) return output class queries: @staticmethod def ricard01(course_nm: str, problem_nm: str) -> SubmissionsQuery: """ The old and venerable ricard01 query. 😀 🔐 Authenticated Returns a list of submissions for a given problem for all students of a given course. Each submission includes the email, time, problem name, problem id, verdict, and IP address. The list is ordered by email and time. """ data = {"course_nm": course_nm, "problem_nm": problem_nm} output, ofiles = _execute("instructor.queries.ricard01", _debuild(data)) return _build(output, SubmissionsQuery) @staticmethod def ricard02(course_nm: str, list_nm: str) -> SubmissionsQuery: """ The old and venerable ricard02 query. 😀 🔐 Authenticated Returns a list of submissions for all problems in a given list for all students of a given course. Each submission includes the email, time, problem name, problem id, verdict, and IP address. The list is ordered by email, problem id and time. """ data = {"course_nm": course_nm, "list_nm": list_nm} output, ofiles = _execute("instructor.queries.ricard02", _debuild(data)) return _build(output, SubmissionsQuery) class problems: @staticmethod def get_passcode(problem_nm: str) -> str: """ Get the passcode of a problem. 🔐 Authenticated Returns an empty string if the problem has no passcode. """ output, ofiles = _execute( "instructor.problems.getPasscode", _debuild(problem_nm) ) return output @staticmethod def set_passcode(problem_nm: str, passcode: str) -> None: """ Set or update the passcode of a problem. 🔐 Authenticated The passcode must be at least 8 characters long and contain only alphanumeric characters. The passcode will be stored in the database in plain text. """ data = {"problem_nm": problem_nm, "passcode": passcode} output, ofiles = _execute("instructor.problems.setPasscode", _debuild(data)) return output @staticmethod def remove_passcode(problem_nm: str) -> None: """ Remove passcode of a problem. 🔐 Authenticated """ output, ofiles = _execute( "instructor.problems.removePasscode", _debuild(problem_nm) ) return output @staticmethod def deprecate(problem_nm: str, reason: str) -> None: """ Deprecate a problem. 🔐 Authenticated """ data = {"problem_nm": problem_nm, "reason": reason} output, ofiles = _execute("instructor.problems.deprecate", _debuild(data)) return output @staticmethod def undeprecate(problem_nm: str) -> None: """ Undeprecate a problem. 🔐 Authenticated """ output, ofiles = _execute( "instructor.problems.undeprecate", _debuild(problem_nm) ) return output @staticmethod def download(problem_nm: str) -> Download: """ Download a problem. 🔐 Authenticated Quick and dirty implementation, should be improved. Returns a zip file with the abstract problem and all its problems. """ output, ofiles = _execute( "instructor.problems.download", _debuild(problem_nm) ) return ofiles[0] class admin: class users: @staticmethod def count() -> float: """ Count users 🔐 Authenticated """ output, ofiles = _execute("admin.users.count", None) return output @staticmethod def create(data: UserCreation) -> None: """ Create a user 🔐 Authenticated """ output, ofiles = _execute("admin.users.create", _debuild(data)) return output @staticmethod def remove(email: str) -> None: """ Remove a user 🔐 Authenticated """ output, ofiles = _execute("admin.users.remove", _debuild(email)) return output @staticmethod def set_password(email: str, password: str) -> None: """ Set a password for a user 🔐 Authenticated """ data = {"email": email, "password": password} output, ofiles = _execute("admin.users.setPassword", _debuild(data)) return output class tasks: @staticmethod def purge_auth_tokens() -> None: """ Purge expired access tokens 🔐 Authenticated Purge expired access tokens (call it from time to time, it does not hurt) """ output, ofiles = _execute("admin.tasks.purge-auth-tokens", None) return output @staticmethod def clear_caches() -> None: """ Clear all memoization caches 🔐 Authenticated """ output, ofiles = _execute("admin.tasks.clear-caches", None) return output class stats: @staticmethod def get_counters() -> Distribution: """ Get counters 🔐 Authenticated """ output, ofiles = _execute("admin.stats.getCounters", None) return _build(output, Distribution) @staticmethod def get_distribution_of_verdicts() -> Distribution: """ Get distribution of verdicts 🔐 Authenticated """ output, ofiles = _execute("admin.stats.getDistributionOfVerdicts", None) return _build(output, Distribution) @staticmethod def get_distribution_of_verdicts_by_year() -> Distribution: """ Get distribution of verdicts by year 🔐 Authenticated """ output, ofiles = _execute( "admin.stats.getDistributionOfVerdictsByYear", None ) return _build(output, Distribution) @staticmethod def get_distribution_of_compilers() -> Distribution: """ Get distribution of compilers 🔐 Authenticated """ output, ofiles = _execute("admin.stats.getDistributionOfCompilers", None) return _build(output, Distribution) @staticmethod def get_distribution_of_proglangs() -> Distribution: """ Get distribution of proglangs 🔐 Authenticated """ output, ofiles = _execute("admin.stats.getDistributionOfProglangs", None) return _build(output, Distribution) @staticmethod def get_distribution_of_users_by_year() -> Distribution: """ Get distribution of registered users by year 🔐 Authenticated """ output, ofiles = _execute("admin.stats.getDistributionOfUsersByYear", None) return _build(output, Distribution) @staticmethod def get_distribution_of_users_by_country() -> Distribution: """ Get distribution of registered users by country 🔐 Authenticated """ output, ofiles = _execute( "admin.stats.getDistributionOfUsersByCountry", None ) return _build(output, Distribution) @staticmethod def get_distribution_of_users_by_submissions(data: int) -> Distribution: """ Get distribution of registered users by submissions using a custom bucket size 🔐 Authenticated """ output, ofiles = _execute( "admin.stats.getDistributionOfUsersBySubmissions", _debuild(data) ) return _build(output, Distribution) @staticmethod def get_ranking_of_users(data: Union[str, float]) -> UserRanking: """ Get ranking of users 🔐 Authenticated ❌ Warning: Input type is not correct """ output, ofiles = _execute("admin.stats.getRankingOfUsers", _debuild(data)) return _build(output, UserRanking) @staticmethod def get_distribution_of_submissions_by_hour() -> Distribution: """ Get distribution of submissions by hour 🔐 Authenticated """ output, ofiles = _execute( "admin.stats.getDistributionOfSubmissionsByHour", None ) return _build(output, Distribution) @staticmethod def get_distribution_of_submissions_by_proglang() -> Distribution: """ Get distribution of submissions by proglang 🔐 Authenticated """ output, ofiles = _execute( "admin.stats.getDistributionOfSubmissionsByProglang", None ) return _build(output, Distribution) @staticmethod def get_distribution_of_submissions_by_compiler() -> Distribution: """ Get distribution of submissions by compiler 🔐 Authenticated """ output, ofiles = _execute( "admin.stats.getDistributionOfSubmissionsByCompiler", None ) return _build(output, Distribution) @staticmethod def get_distribution_of_submissions_by_weekday() -> Distribution: """ Get distribution of submissions by weekday 🔐 Authenticated """ output, ofiles = _execute( "admin.stats.getDistributionOfSubmissionsByWeekday", None ) return _build(output, Distribution) @staticmethod def get_distribution_of_submissions_by_year() -> Distribution: """ Get distribution of submissions by year 🔐 Authenticated """ output, ofiles = _execute( "admin.stats.getDistributionOfSubmissionsByYear", None ) return _build(output, Distribution) @staticmethod def get_distribution_of_submissions_by_year_for_proglang( proglang: str, ) -> Distribution: """ Get distribution of submissions by year for a proglang 🔐 Authenticated """ output, ofiles = _execute( "admin.stats.getDistributionOfSubmissionsByYearForProglang", _debuild(proglang), ) return _build(output, Distribution) @staticmethod def get_distribution_of_submissions_by_day() -> Distribution: """ Get distribution of submissions by day 🔐 Authenticated """ output, ofiles = _execute( "admin.stats.getDistributionOfSubmissionsByDay", None ) return _build(output, Distribution) @staticmethod def get_heatmap_calendar_of_submissions() -> HeatmapCalendar: """ Get heatmap calendar of submissions 🔐 Authenticated Data is provided as required by https://cal-heatmap.com """ output, ofiles = _execute( "admin.stats.getHeatmapCalendarOfSubmissions", None ) return _build(output, HeatmapCalendar) @staticmethod def get_upcoming_exams() -> UpcomingExams: """ Get upcoming exams 🔐 Authenticated """ output, ofiles = _execute("admin.stats.getUpcomingExams", None) return _build(output, UpcomingExams) class problems: @staticmethod def get_problem_solution(problem_id: str, proglang: str) -> str: """ Get official solution for a problem for a proglang 🔐 Authenticated ❌ Warning: TODO """ data = {"problem_id": problem_id, "proglang": proglang} output, ofiles = _execute( "admin.problems.getProblemSolution", _debuild(data) ) return output class check: @staticmethod def check_user() -> None: """ Checks that query actor is a user 🔐 Authenticated """ output, ofiles = _execute("check.checkUser", None) return output @staticmethod def check_instructor() -> None: """ Checks that query actor is an instructor 🔐 Authenticated """ output, ofiles = _execute("check.checkInstructor", None) return output @staticmethod def check_admin() -> None: """ Checks that query actor is an admin 🔐 Authenticated """ output, ofiles = _execute("check.checkAdmin", None) return output @staticmethod def throw_error(exception: str) -> None: """ Throw an exception of the given type """ output, ofiles = _execute("check.throwError", _debuild(exception)) return output class playground: @staticmethod def upload(data: Name, ifile: IO) -> str: """ Upload a file """ output, ofiles = _execute("playground.upload", _debuild(data), [ifile]) return output @staticmethod def negate(ifile: IO) -> Download: """ Get negative of an image """ output, ofiles = _execute("playground.negate", None, [ifile]) return ofiles[0] @staticmethod def download(data: Name) -> Download: """ Download a file """ output, ofiles = _execute("playground.download", _debuild(data)) return ofiles[0] @staticmethod def download2(data: Name) -> tuple[str, Download]: """ Download a file with a string """ output, ofiles = _execute("playground.download2", _debuild(data)) return output, ofiles[0] @staticmethod def ping() -> str: """ Ping the server to get a pong string """ output, ofiles = _execute("playground.ping", None) return output @staticmethod def to_upper_case(s: str) -> str: """ Returns the given string in uppercase """ output, ofiles = _execute("playground.toUpperCase", _debuild(s)) return output @staticmethod def add2i(data: TwoInts) -> int: """ Returns the sum of two integers """ output, ofiles = _execute("playground.add2i", _debuild(data)) return output @staticmethod def add2f(data: TwoFloats) -> float: """ Returns the sum of two floats """ output, ofiles = _execute("playground.add2f", _debuild(data)) return output @staticmethod def inc(data: TwoInts) -> TwoInts: """ increment two numbers """ output, ofiles = _execute("playground.inc", _debuild(data)) return _build(output, TwoInts) @staticmethod def add3i(a: int, b: int, c: int) -> int: """ Returns the sum of three integers """ data = {"a": a, "b": b, "c": c} output, ofiles = _execute("playground.add3i", _debuild(data)) return output