inginious.frontend package

Package that implements a webapp for INGInious

Subpackages

Submodules

inginious.frontend.accessible_time module

Contains AccessibleTime, class that represents the period of time when a course/task is accessible

class inginious.frontend.accessible_time.AccessibleTime(val=None)[source]

Bases: object

represents the period of time when a course/task is accessible

after_start(when=None)[source]

Returns True if the task/course is or have been accessible in the past

before_start(when=None)[source]

Returns True if the task/course is not yet accessible

get_end_date()[source]

Return a datetime object, representing the deadline for accessibility

get_soft_end_date()[source]

Return a datetime object, representing the soft deadline for accessibility

get_start_date()[source]

Return a datetime object, representing the date when the task/course become accessible

get_std_end_date()[source]

If the date is custom, return the end datetime in ISO format. Else, returns “”.

get_std_soft_end_date()[source]

If the date is custom, return the soft datetime in ISO format. Else, returns “”.

get_std_start_date()[source]

If the date is custom, return the start datetime in ISO format. Else, returns “”.

is_always_accessible()[source]

Returns true if the course/task is always accessible

is_never_accessible()[source]

Returns true if the course/task is never accessible

is_open(when=None)[source]

Returns True if the course/task is still open

is_open_with_soft_deadline(when=None)[source]

Returns True if the course/task is still open with the soft deadline

inginious.frontend.accessible_time.parse_date(date, default=None)[source]

Parse a valid date

inginious.frontend.arch_helper module

inginious.frontend.arch_helper.create_arch(configuration, context)[source]

Helper that can start a simple complete INGInious arch locally if needed, or a client to a remote backend. Intended to be used on command line, makes uses of exit() and the logger inginious.frontend. :type configuration: :param configuration: configuration dict :type context: :param context: a ZMQ context :param is_testing: boolean :return: a Client object

inginious.frontend.arch_helper.start_asyncio_and_zmq(debug_asyncio=False)[source]

Init asyncio and ZMQ. Starts a daemon thread in which the asyncio loops run. :return: a ZMQ context and a Thread object (as a tuple)

inginious.frontend.app module

Starts the webapp

inginious.frontend.app.get_app(config)[source]
Parameters:

config – the configuration dict

Returns:

A new app

inginious.frontend.courses module

A course class with some modification for users

class inginious.frontend.courses.Course(courseid, content)[source]

Bases: object

A course with some modification for users

allow_preview()[source]
allow_unregister(plugin_override=True)[source]

Returns True if students can unregister from course

can_students_choose_group()[source]

Returns True if the students can choose their groups

delete()[source]

Erase the content of the course folder

classmethod get(courseid)[source]

Fetch a course with id courseid from the specified course filesystem

Return type:

Course

get_access_control_accept()[source]

Returns either True (accept) or False (deny), depending on the control type used to verify that users can register to the course

get_access_control_list()[source]

Returns the list of all users/emails/binding methods/… (see get_access_control_method) allowed by the AC list

Return type:

List[str]

get_access_control_method()[source]

Returns either None, “username”, “binding”, or “email”, depending on the method used to verify that users can register to the course

get_accessibility(plugin_override=True)[source]

Return the AccessibleTime object associated with the accessibility of this course

get_admins()[source]

Returns a list containing the usernames of the administrators of this course

classmethod get_all()[source]

Returns a dictionnary with courseid=>Course mapping

Return type:

dict[str, Course]

get_archiving_date()[source]

Returns the date at which the course was archived as a string (None if not archived)

get_description(language)[source]

Returns the course description

get_descriptor()[source]

Get (a copy) the description of the course

get_fs()[source]

Returns a FileSystemProvider which points to the folder of this course

get_id()[source]

Return the _id of this course

get_name(language)[source]

Return the name of this course

get_readable_tasks()[source]

Returns the list of all available tasks in a course

get_registration_accessibility()[source]

Return the AccessibleTime object associated with the registration

get_registration_password()[source]

Returns the password needed for registration (None if there is no password)

get_staff()[source]

Returns a list containing the usernames of all the staff users

get_tags()[source]
get_task(taskid)[source]

Returns a Task object

get_task_dispenser()[source]
Returns:

the structure of the course

get_tasks()[source]

Returns

Return type:

dict[str, Task]

get_translation_obj(language)[source]
get_tutors()[source]

Returns a list containing the usernames of the tutors assigned to this course

gettext(language, text)[source]
is_archive()[source]

Returns true if the course is an archive

is_lti()[source]

True if the current course is in LTI mode

is_open_to_non_staff()[source]

Returns true if the course is accessible by users that are not administrator of this course

is_password_needed_for_registration()[source]

Returns true if a password is needed for registration

is_registration_possible(user_info)[source]

Returns true if users can register for this course

is_user_accepted_by_access_control(user_info)[source]

Returns True if the user is allowed by the ACL

lti_config()[source]

LTI Tool config dictionary. Specs are at https://github.com/dmitry-viskov/pylti1.3/blob/master/README.rst?plain=1#L70-L98

lti_keys()[source]

{name: key} for the LTI customers

lti_keyset_hash(issuer, client_id)[source]
Return type:

str

lti_platform_instances_ids()[source]

Set of LTI Platform instance ids registered for this course.

Return type:

Iterable[str]

lti_send_back_grade()[source]

True if the current course should send back grade to the LTI Tool Consumer

lti_tool()[source]

LTI Tool object.

Return type:

ToolConfDict

lti_url()[source]

Returns the URL to the external platform the course is hosted on

save()[source]

Saves the Course into the filesystem

set_descriptor_element(key, value)[source]
set_translations(translations)[source]

inginious.frontend.installer module

Custom installer for the web app

class inginious.frontend.installer.Installer(config_path=None, default=False)[source]

Bases: object

Custom installer for the WebApp frontend

ask_backend()[source]

Ask the user to choose the backend

configuration_filename()[source]

Returns the name of the configuration file

configure_authentication()[source]

Configure the authentication

configure_misc()[source]

Configure various things

configure_mongodb()[source]

Configure MongoDB

configure_task_directory()[source]

Configure task directory

ldap_plugin()[source]

Configures the LDAP plugin

run()[source]

Run the installator

select_containers_to_build()[source]
support_remote_debugging()[source]

Returns True if the frontend supports remote debugging, False else

test_local_docker_conf()[source]

Test to connect to a local Docker daemon

try_mongodb_opts(host='localhost', database_name='INGInious')[source]

Try MongoDB configuration

inginious.frontend.parsable_text module

Tools to parse text

class inginious.frontend.parsable_text.CustomAdmonition(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine)[source]

Bases: CustomBaseAdmonition

A custom admonition with a specific class if needed

node_class

alias of admonition

required_arguments = 1

Number of required directive arguments.

class inginious.frontend.parsable_text.CustomBaseAdmonition(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine)[source]

Bases: BaseAdmonition

A custom admonition that can have a title

option_spec = {'class': <function class_option>, 'name': <function unchanged>, 'title': <function unchanged>}

Mapping of option names to validator functions.

class inginious.frontend.parsable_text.EmptiableCodeBlock(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine)[source]

Bases: CodeBlock

run()[source]
class inginious.frontend.parsable_text.HiddenUntilDirective(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine)[source]

Bases: Directive, object

has_content = True

May the directive have content?

option_spec = {}

Mapping of option names to validator functions.

optional_arguments = 1

Number of optional arguments after the required arguments.

required_arguments = 1

Number of required directive arguments.

run()[source]
class inginious.frontend.parsable_text.ParsableText(content, mode='rst', show_everything=False)[source]

Bases: object

Allow to parse a string with different parsers

classmethod html(string, show_everything=False)[source]

Parses HTML

original_content()[source]

Returns the original content

parse(debug=False)[source]

Returns parsed text

classmethod rst(string, show_everything=False, initial_header_level=3, debug=False)[source]

Parses reStructuredText

class inginious.frontend.parsable_text.time(rawsource='', text='', *children, **attributes)[source]

Bases: Inline, TextElement

inginious.frontend.parsable_text.time_role(name, rawtext, text, lineno, inliner, options={}, content=[])[source]

inginious.frontend.plugins.plugin_manager module

Plugin Manager

class inginious.frontend.plugins.plugin_manager.PluginManager[source]

Bases: object

Registers an manage plugins. The init method inits only the Hook Manager; you have to call the method load() to start the plugins

add_hook(name, callback, prio=0)[source]

Add a new hook that can be called with the call_hook function. prio is the priority. Higher priority hooks are called before lower priority ones. This function does not enforce a particular order between hooks with the same priorities.

add_page(pattern, classname_or_viewfunc)[source]

Add a new page to the web application. Only available after that the Plugin Manager is loaded

add_template_prefix(prefix, folder)[source]

Adds a template folder served for all templates prefixed by indicated prefix :type prefix: str :param prefix: prefix the template folder is served from. :type folder: str :param folder: abolute path to the template folder.

call_hook(name, **kwargs)[source]

Call all hooks registered with this name. Returns a list of the returns values of the hooks (in the order the hooks were added)

call_hook_recursive(name, **kwargs)[source]

Call all hooks registered with this name. Each hook receives as arguments the return value of the previous hook call, or the initial params for the first hook. As such, each hook must return a dictionary with the received (eventually modified) args. Returns the modified args.

get_submission_manager()[source]

Returns the submission manager

get_user_manager()[source]

Returns the user manager

load(client, flask_app, user_manager, submission_manager, config)[source]

Loads the plugin manager. Must be done after the initialisation of the client

register_auth_method(auth_method)[source]

Registers a new authentication method :type auth_method: AuthMethod :param auth_method: a AuthMethod-based class

inginious.frontend.submission_manager module

Manages submissions

class inginious.frontend.submission_manager.WebAppSubmissionManager(client, user_manager, lti_score_publishers)[source]

Bases: object

Manages submissions. Communicates with the database and the client.

add_job(course, task, inputdata, task_dispenser, debug=False)[source]

Add a job in the queue and returns a submission id. :type task: :param task: Task instance :type task: inginious.frontend.tasks.Task :type inputdata: :param inputdata: the input as a dictionary :type inputdata: dict :type debug: :param debug: If debug is true, more debug data will be saved :type debug: bool or string :returns: the new submission id and the removed submission id

get_available_environments()[source]

:return a list of available environments

Return type:

Dict[str, List[str]]

get_feedback_from_submission(submission, only_feedback=False, show_everything=False)[source]

Get the input of a submission. If only_input is False, returns the full submissions with a dictionnary object at the key “input”. Else, returns only the dictionnary.

If show_everything is True, feedback normally hidden is shown.

get_input_from_submission(submission, only_input=False)[source]

Get the input of a submission. If only_input is False, returns the full submissions with a dictionnary object at the key “input”. Else, returns only the dictionnary.

get_job_queue_info(jobid)[source]

Get job queue info :type jobid: :param jobid: the JOB id (not the submission id!). You should retrieve it before calling this function by calling get_submission(...)["job_id"]. :return: If the submission is in the queue, then returns a tuple (nb tasks before running (or -1 if running), approx wait time in seconds) Else, returns None

get_job_queue_snapshot()[source]

Get a snapshot of the remote backend job queue. May be a cached version. May not contain recent jobs. May return None if no snapshot is available

Returns:

a tuple of two lists (None, None):

  • jobs_running : a list of tuples in the form (job_id, is_current_client_job, info, launcher, started_at, max_time) where

    • job_id is a job id. It may be from another client.

    • is_current_client_job is a boolean indicating if the client that asked the request has started the job

    • agent_name is the agent name

    • info is “courseid/taskid”

    • launcher is the name of the launcher, which may be anything

    • started_at the time (in seconds since UNIX epoch) at which the job started

    • max_time the maximum time that can be used, or -1 if no timeout is set

  • jobs_waiting : a list of tuples in the form (job_id, is_current_client_job, info, launcher, max_time) where

    • job_id is a job id. It may be from another client.

    • is_current_client_job is a boolean indicating if the client that asked the request has started the job

    • info is “courseid/taskid”

    • launcher is the name of the launcher, which may be anything

    • max_time the maximum time that can be used, or -1 if no timeout is set

get_submission(submissionid, user_check=True)[source]

Get a submission from the database

get_submission_archive(course, submissions, sub_folders, archive_file=None, simplify=False)[source]
Parameters:
  • course – the course object linked to the submission

  • submissions – a list of submissions

  • sub_folders

    a list of folders in which to place the submission. For example, [“taskid”, “submissionid”] place each submission inside a folder taskid/submissionid/ (with taskid replaced with the actual task id, the same being true for submissionid). The possible values are: - “taskid”: replaced by the task id - “submissionid”: replaced by the submission id - “audience”: replaced by the name of the audience “audiencedesc_(audienceid)” - “group”: replaced by the list of username who submitted - “username”: replaced by the username Some of these (like “username” and “audience”) are not unique for a submission. If they are multiple answers possible, the files are duplicated at multiple locations.

    For example: given a submission #9083081 by the group [“a”, “b”], and a sub_folders value of [“username”, “submissionid”], the archive will contain two folders: - a/9083081/ - b/9083081/

Returns:

a file-like object containing a tgz archive of all the submissions

get_user_last_submissions(limit=5, query=None)[source]

Get last submissions of a user

get_user_submissions(course, task)[source]

Get all the user’s submissions for a given task

is_done(submissionid_or_submission, user_check=True)[source]

Tells if a submission is done and its result is available

is_running(submissionid, user_check=True)[source]

Tells if a submission is running/in queue

kill_running_submission(submissionid, user_check=True)[source]

Attempt to kill the remote job associated with this submission id. :type submissionid: :param submissionid: :type user_check: :param user_check: Check if the current user owns this submission :return: True if the message asking to kill the job was sent, False if an error occurred

replay_job(course, task, submission, task_dispenser, copy=False, debug=False)[source]

Replay a submission: add the same job in the queue, keeping submission id, submission date and input data :type submission: :param submission: Submission to replay :type copy: :param copy: If copy is true, the submission will be copied to admin submissions before replay :type debug: :param debug: If debug is true, more debug data will be saved

user_is_submission_owner(submission)[source]

Returns true if the current user is the owner of this jobid, false else

inginious.frontend.task_problems module

Displayable problems

class inginious.frontend.task_problems.DisplayableCodeProblem(problemid, content, translations, taskfs)[source]

Bases: CodeProblem, DisplayableProblem

A basic class to display all BasicCodeProblem derivatives

adapt_input_for_backend(input_data)[source]

Adapt the input from web.py for the inginious.backend

classmethod get_type_name(language)[source]
classmethod show_editbox(key, language)[source]

get the edit box html for this problem

classmethod show_editbox_templates(key, language)[source]
show_input(language, seed)[source]

Show BasicCodeProblem and derivatives

class inginious.frontend.task_problems.DisplayableCodeSingleLineProblem(problemid, content, translations, taskfs)[source]

Bases: CodeSingleLineProblem, DisplayableProblem

A displayable single code line problem

adapt_input_for_backend(input_data)[source]

Adapt the input from web.py for the inginious.backend

classmethod get_type_name(language)[source]
classmethod show_editbox(key, language)[source]

get the edit box html for this problem

classmethod show_editbox_templates(key, language)[source]
show_input(language, seed)[source]

Show InputBox

class inginious.frontend.task_problems.DisplayableFileProblem(problemid, content, translations, taskfs)[source]

Bases: FileProblem, DisplayableProblem

A displayable code problem

adapt_input_for_backend(input_data)[source]

Adapt the input from web.py for the inginious.backend

classmethod get_type_name(language)[source]
classmethod show_editbox(key, language)[source]

get the edit box html for this problem

classmethod show_editbox_templates(key, language)[source]
show_input(language, seed)[source]

Show FileBox

class inginious.frontend.task_problems.DisplayableMatchProblem(problemid, content, translations, taskfs)[source]

Bases: MatchProblem, DisplayableProblem

A displayable match problem

classmethod get_type_name(language)[source]
classmethod show_editbox(key, language)[source]

get the edit box html for this problem

classmethod show_editbox_templates(key, language)[source]
show_input(language, seed)[source]

Show MatchProblem

class inginious.frontend.task_problems.DisplayableMultipleChoiceProblem(problemid, content, translations, taskfs)[source]

Bases: MultipleChoiceProblem, DisplayableProblem

A displayable multiple choice problem

classmethod get_type_name(language)[source]
classmethod show_editbox(key, language)[source]

get the edit box html for this problem

classmethod show_editbox_templates(key, language)[source]
show_input(language, seed)[source]

Show multiple choice problems

class inginious.frontend.task_problems.DisplayableProblem(problemid, content, translations, taskfs)[source]

Bases: Problem

Basic problem

adapt_input_for_backend(input_data)[source]

Adapt the input from web.py for the inginious.backend

abstract classmethod get_type_name(language)[source]
abstract classmethod show_editbox(key, language)[source]

get the edit box html for this problem

abstract classmethod show_editbox_templates(key, language)[source]
abstract show_input(language, seed)[source]

get the html for this problem

inginious.frontend.task_problems.get_default_displayable_problem_types()[source]

Get the mapping of default DisplayableProblem types available by inspecting the current module.

Return type:

dict

Returns:

The mapping of problem name and problem class.

inginious.frontend.task_problems.inspect_displayable_problem_types(name)[source]

Get the mapping of DisplayableProblem types available by inspecting a given module.

Parameters:

name (str) – The name of the module to inspect.

Return type:

dict

Returns:

The mapping of problem name and problem class.

inginious.frontend.tasks module

Classes modifying basic tasks, problems and boxes classes

class inginious.frontend.tasks.Task(courseid, taskid, content)[source]

Bases: object

A task that stores additional context information, specific to the web app

adapt_input_for_backend(input_data)[source]

Adapt the input from web.py for the inginious.backend

delete()[source]

Erase the content of the task folder

drop_legacy_fields(legacy_fields)[source]
classmethod get(courseid, taskid)[source]

Fetch a task with id taskid from the specified course filesystem

get_authors(language)[source]

Return the list of this task’s authors

get_contact_url(_language)[source]

Return the contact link format string for this task

get_context(language)[source]

Get the context(description) of this task

get_dispenser_settings(fields)[source]

Fetch the legacy config fields now used by task dispensers

get_environment_id()[source]

Returns the environment in which the agent have to launch this task

get_environment_parameters()[source]

Returns the raw environment parameters, which is a dictionnary that is envtype dependent.

get_environment_type()[source]

Returns the environment type in which the agent have to launch this task

get_fs()[source]

Returns a FileSystemProvider which points to the folder of this task

get_id()[source]

Get the id of this task

get_name(language)[source]

Returns the name of this task

get_number_input_random()[source]

Return the number of random inputs

get_problems()[source]

Get problems contained in this task

get_problems_dict()[source]

Get problems dict contained in this task

get_translation_obj(language)[source]
gettext(language, text)[source]
input_is_consistent(task_input, default_allowed_extension, default_max_size)[source]

Check if an input for a task is consistent. Return true if this is case, false else

regenerate_input_random()[source]

Indicates if random inputs should be regenerated

save()[source]

Saves the Task into the filesystem

set_translations(translations)[source]

inginious.frontend.user_manager module

Manages users data and session

exception inginious.frontend.user_manager.AuthInvalidInputException[source]

Bases: Exception

exception inginious.frontend.user_manager.AuthInvalidMethodException[source]

Bases: Exception

class inginious.frontend.user_manager.AuthMethod[source]

Bases: object

abstract callback(auth_storage)[source]
Parameters:

auth_storage – The session auth method storage dict

Returns:

User tuple and , or None, if failed

Parameters:

auth_storage – The session auth method storage dict

Returns:

The authentication link

abstract get_id()[source]
Returns:

The auth method id

Returns:

The image link

abstract get_name()[source]
Returns:

The name of the auth method, to be displayed publicly

class inginious.frontend.user_manager.UserInfo(realname, email, username, bindings, language, code_indentation, activated)

Bases: tuple

activated

Alias for field number 6

bindings

Alias for field number 3

code_indentation

Alias for field number 5

email

Alias for field number 1

language

Alias for field number 4

realname

Alias for field number 0

username

Alias for field number 2

class inginious.frontend.user_manager.UserManager(superadmins)[source]

Bases: object

activate_user(activate_hash)[source]

Active a user based on his/her activation hash :type activate_hash: :param activate_hash: The activation hash of a user :return A boolean if the user was found and updated

auth_user(username, password, do_connect=True)[source]

Authenticate the user in database :type username: :param username: Username/Login :type password: :param password: User password :type do_connect: :param do_connect: indicates if the user must be connected after authentification, True by default :return: Returns a dict representing the user, or None if the authentication was not successful

bind_user(auth_id, user)[source]

Add a binding method to a user :type auth_id: :param auth_id: The binding method id :type user: :param user: User object :return: Boolean if method has been add

connect_user(user)[source]

Opens a session for the user

:param usera dict representing the user, it contains the data of the user.

It must at least contain the following fields: - realname - email - username

course_is_open_to_user(course, username=None, lti=None, return_reason=False)[source]

Checks if a user is can access a course

Parameters:
  • course – a Course object

  • username – The username of the user that we want to check. If None, uses session.username

  • lti

    indicates if the user is currently in a LTI session or not.

    • None to ignore the check

    • True to indicate the user is in a LTI session

    • False to indicate the user is not in a LTI session

    • ”auto” to enable the check and take the information from the current session

  • return_reason

    instead of False, returns a string indicating for which reason the course is not open to the user. Reasons may be :

    • ”closed” if the course is not open

    • ”unregistered_not_previewable” user is not registered and course is not previewable

    • ”lti_only” the current session is not a LTI session and this course requires at LTI session

    • ”lti_not_registered” this LTI course can be accessed outside an LTI session only if the user register first via the LTI interface

Returns:

True if the user can access the course, False (or the reason if return_reason is True) otherwise

course_is_user_registered(course, username=None)[source]

Checks if a user is registered

Parameters:
  • course – a Course object

  • username – The username of the user that we want to check. If None, uses session.username

Returns:

True if the user is registered, False else

course_register_user(course, username=None, password=None, force=False)[source]

Register a user to the course

Parameters:
  • course – a Course object

  • username – The username of the user that we want to register. If None, uses session.username

  • password – Password for the course. Needed if course.is_password_needed_for_registration() and force != True

  • force – Force registration

Returns:

True if the registration succeeded, False else

course_unregister_user(course_id, username=None)[source]

Unregister a user to the course :type course_id: :param course_id: a course id :type username: :param username: The username of the user that we want to unregister. If None, uses session.username

create_user(values)[source]

Create a new user :type values: :param values: Dictionary of fields :return: An error message if something went wrong else None

delete_user(username, confirmation_email=None)[source]

Delete a user based on username :type username: :param username: the username of the user :type confirmation_email: :param confirmation_email: An email to confirm suppression. May be None :return a boolean if a user was deleted

disconnect_user()[source]

Disconnects the user currently logged-in

classmethod generate_api_key()[source]
get_auth_method(auth_method_id)[source]

:param the auth method id, as provided by get_auth_methods_inputs() :return: AuthMethod if it exists, otherwise None

get_auth_methods()[source]
Returns:

The auth methods dict

get_course_audiences(course)[source]

Returns a list of the course audiences

get_course_audiences_per_student(course)[source]

Returns a dictionnary mapping student -> list of audiences it belongs to, for a given course

get_course_cache(username, course)[source]
Parameters:
  • username – The username

  • course – A Course object

Returns:

a dict containing info about the course, in the form:

{"task_tried": 0, "total_tries": 0, "task_succeeded": 0, "task_grades":{"task_1": 100.0, "task_2": 0.0, ...}}

Note that only the task already seen at least one time will be present in the dict task_grades.

get_course_caches(usernames, course)[source]
Parameters:
  • usernames (list[str]) – List of username for which we want info. If usernames is None, data from all users will be returned.

  • course – A Course object

Returns:

Returns data of the specified users for a specific course. users is a list of username.

The returned value is a dict:

{"username": {"task_tried": 0, "total_tries": 0, "task_succeeded": 0, "task_grades":{"task_1": 100.0, "task_2": 0.0, ...}}}

Note that only the task already seen at least one time will be present in the dict task_grades.

get_course_groups(course)[source]

Returns a list of the course groups

get_course_registered_users(course, with_admins=True)[source]

Get all the users registered to a course :type course: :param course: a Course object :type with_admins: :param with_admins: include admins? :return: a list of usernames that are registered to the course

get_course_user_group(course, username=None)[source]

Returns the audience whose username belongs to :type course: :param course: a Course object :type username: :param username: The username of the user that we want to register. If None, uses session.username :return: the audience description

get_task_cache(username, courseid, taskid)[source]

Shorthand for get_task_caches([username], courseid, taskid)[username]

get_task_caches(usernames, courseid, taskid)[source]
Parameters:
  • usernames – List of username for which we want info. If usernames is None, data from all users will be returned.

  • courseid – the course id

  • taskid – the task id

Returns:

A dict in the form:

{
    "username": {
        "courseid": courseid,
        "taskid": taskid,
        "tried": 0,
        "succeeded": False,
        "grade": 0.0
    }
}

get_user_api_key(username, create=True)[source]

Get the API key of a given user. API keys are generated on demand. :type username: :param username: :type create: :param create: Create the API key if none exists yet :return: the API key assigned to the user, or None if none exists and create is False.

get_user_email(username)[source]
Parameters:

username

Returns:

the email of the user if it can be found, None else

get_user_info(username)[source]
Parameters:

username

Return type:

Optional[UserInfo]

Returns:

a tuple (realname, email) if the user can be found, None else

get_user_pinned_courses(username)[source]
get_user_realname(username)[source]
Parameters:

username

Returns:

the real name of the user if it can be found, None else

get_users_info(usernames, limit=0, skip=0)[source]
Parameters:

usernames – a list of usernames

:param limit A limit of users requested :param skip A quantity of users to skip :rtype: Dict[str, Optional[UserInfo]] :return: a dict, in the form {username: val}, where val is either None if the user cannot be found, or a UserInfo. If the list of usernames is empty, return an empty dict.

has_admin_rights_on_course(course, username=None, include_superadmins=True)[source]

Check if a user can be considered as having admin rights for a course :type course: inginious.frontend.courses.Course :type username: :param username: the username. If None, the username of the currently logged in user is taken :type include_superadmins: :param include_superadmins: Boolean indicating if superadmins should be taken into account :return: True if the user has admin rights, False else

has_staff_rights_on_course(course, username=None, include_superadmins=True)[source]

Check if a user can be considered as having staff rights for a course :type course: inginious.frontend.courses.Course :type username: :param username: the username. If None, the username of the currently logged in user is taken :type include_superadmins: :param include_superadmins: Boolean indicating if superadmins should be taken into account :return: True if the user has staff rights, False else

classmethod hash_password(content)[source]

Encapsulates the other password hashing functions :type content: :param content: a str input :return a hash of str input

classmethod hash_password_argon2id(content)[source]
Parameters:

content – a str input

:return a hash of str input

classmethod hash_password_sha512(content)[source]
Parameters:

content – a str input

:return a hash of str input

pin_course(username, courseid)[source]
register_auth_method(auth_method)[source]

Registers an authentication method :type auth_method: :param auth_method: an AuthMethod object

revoke_binding(username, binding_id)[source]

Revoke a binding method for a user :type binding_id: :param binding_id: The binding method id :type username: :param username: username of the user :return: Boolean if error occurred and message if necessary

classmethod sanitize_email(email)[source]

Sanitize an email address and put the bar part of an address foo@bar in lower case.

Return type:

str

task_can_user_submit(course, task, username=None, only_check=None, lti=None)[source]

returns true if the user can submit his work for this task :param only_check : only checks for ‘groups’, ‘tokens’, or None if all checks :type lti: :param lti: indicates if the user is currently in a LTI session or not. - None to ignore the check - True to indicate the user is in a LTI session - False to indicate the user is not in a LTI session - “auto” to enable the check and take the information from the current session

task_is_visible_by_user(course, task, username=None, lti=None)[source]

Returns true if the task is visible and can be accessed by the user

Parameters:

lti

indicates if the user is currently in a LTI session or not.

  • None to ignore the check

  • True to indicate the user is in a LTI session

  • False to indicate the user is not in a LTI session

  • ”auto” to enable the check and take the information from the current session

unpin_course(username, courseid)[source]
update_user_stats(username, task, submission, result_str, grade, state, newsub, task_dispenser)[source]

Update stats with a new submission

user_is_superadmin(username=None)[source]
Parameters:

username – the username. If None, the username of the currently logged in user is taken

Returns:

True if the user is superadmin, False else

user_saw_task(username, courseid, taskid)[source]

Set in the database that the user has viewed this task

verify_hash(db_hash, password, method='sha512')[source]

Verify a hash :type db_hash: :param db_hash: The hash to verify :type password: :param password: The password to verify :type method: :param method: The hash method :return: A boolean if the hash is correct

verify_hash_argon2id(db_hash, password)[source]
verify_hash_sha512(db_hash, password)[source]