Page tree
Skip to end of metadata
Go to start of metadata

Participants

  • Plugin developers: Nikolai, Olli, Nikolas
  • Customers: Juha, Otto
  • A+ API developers: Markku, Henrik (in the summer 2020)

Project description

Intellij IDEA plugin for A+ integrates A+ functionalities into the IDE so that students can access and submit exercises directly within the development environment.

Requirements of the IntelliJ plugin are described in the GitHub project wiki in more detail: https://github.com/Aalto-LeTech/intellij-plugin/wiki/Requirements

Time frame: January 2020 - August 2020

The project is funded and led by Senior University Lecturer Juha Sorva. At first, the primary goal is to use the plugin at the Programming 1 course (O1) in the autumn 2020, but the plugin should usable and useful for other programming courses in A+ too.

This wiki page concentrates on the A+ API requirements. The IntelliJ plugin development and its requirements are described in the Github repo https://github.com/Aalto-LeTech/intellij-plugin.

Requirements for A+ API

The plugin requires changes to the A+ API. The plugin developers intend to concentrate on the plugin itself, and Markku develops the A+ API.

The A+ API should support the basic functionality before the summer 2020. It is too late to start the development in the summer since the IJ plugin is taken to production use in the autumn 2020.

  • Exercise submissions via the API. This must support group submissions. The feedback of the submission must be available from the API too.
  • User authentication: if existing user tokens are used, it should be possible to retrieve them from the API after the user has logged into A+ via the IntelliJ plugin. Instead of using tokens, OAuth2 could be a feasible authentication method, but it may be too hard to implement in the current state of A+.
  • Group submissions are crucial for the O1 course. The plugin must be able to retrieve the user's groups from the API so that the user may select a group for submitting within the plugin. (It is acceptable to require users to create the groups in the A+ web UI.)

The IJ plugin developers would want the EDIT team to provide test data for their test A+ server. Basically, it is easier for them if the test installation contains such data built-in and the plugin developers can use it directly. A course template already exists, but the test A+ database needs more pre-defined users and student groups (for group submissions). Here is a draft for the generation of test data for the aplus-manual: https://github.com/Mankro/course-templates/blob/test/tools/test-bench-course-mod.py

Technical design draft

  • Adding student groups to the API should be straightforward. We need these API endpoints:
    • Fetch the user's (the user who is authenticated) own student groups in the course instance: /api/v2/courses/ID/mygroups/
      • Data about group members: user's full name, user ID
      • No student IDs are provided here since students should not normally see other students' IDs
    • Fetch all student groups in the course instance (accessible by teachers): /api/v2/courses/ID/groups/
      • Full details about the group members
  • Exercise submissions
    • Students must be allowed to HTTP POST new submissions to the API.
    • New endpoint for creating submissions that are sent to the exercise grader: /api/v2/exercises/ID/submissions/submit/
      • The submission data is included in POST parameters. The submission data must use the keys for different fields that are configured in the exercise config.yaml file (in the course repository). The POST parameters may include files.
      • The endpoint /api/v2/exercises/ID/ provides information about the exercise including the specification of the submission form (i.e., the keys for the submission data fields like a file to submit).
      • The POST data should always include the field "__aplus__={"group": groupID, "lang": "en"}" (in the old version, the parameter was "_aplus_group" without the aplus JSON object) for selecting the group of the submission. Its value is the group ID. The IDs of available groups can be retrieved from the endpoint /api/v2/courses/ID/mygroups/. If the user submits alone, the value -1 (minus one) must be used for the group. If the group ID is not defined and the user has selected a group in the course level in the A+ course web page, then A+ would use that group for the submission, which would be confusing since the user can't see the A+ web page while submitting through the API. NB: the group must be the user's own group. If the ID belongs to a group that the user is not a member of, the group is ignored and the submission is made for the user alone.
      • The language of the submission (in multilingual courses like Programming 1) is defined with the same __aplus__ object: "__aplus__={"group": groupID, "lang": "en"}". If the grader supports different languages, it should generate feedback in the given language.
      • The POST data must NOT include the field "__grader_lang=en" that has previously been used by A+ as a hacky fix to select the questionnaire feedback language.
      • Examples of testing the API with curl in the command line (with and without an uploaded file) (the authorization token must be changed to the real value and likewise, the exercise IDs as well as submission data and files can be changed. The file path "@functions.py" refers to a local file in your computer.):
      • curl -v -X POST 'http://localhost:8000/api/v2/exercises/10/submissions/submit/' -d 'somekey=1&myrandom=2' -H 'Authorization: Token b6a6debaaf94b7a7b65fa5b2cead10eec6cb4516'
      • curl -v -X POST 'http://localhost:8000/api/v2/exercises/21/submissions/submit/' -H 'Authorization: Token 94ad2abfc128a3da3b0541fbfea981bc62becd56' -F '__aplus__={"group": 1, "lang": "en"}'  -F 'file1=@functions.py'
    • The endpoint /api/v2/exercises/ID/submissions/submit/ returns the HTTP response with status 201 Created if the new submission was successfully stored in A+. The response includes the Location header that points to the new submission, e.g., http://localhost:8000/api/v2/submissions/ID/. The submission endpoint returns info about the submission, e.g., the feedback, points and the status. If the status is not "ready", the submission has not been graded yet (or it has failed due to some error).
    • The grading of the submission may fail. The submission may end up in the error status, or it could be stuck in the initialized or waiting statuses. If the submission data does not included the required fields, the grader rejects it and the submission receives the rejected status.
    • Return values for the /api/v2/exercises/ID/submissions/submit/ endpoint:
      • Success: status code HTTP 201 Created and an empty response body. The response has the Location header pointing to the new submission.
      • submission created in A+ but there are errors in grading: status code HTTP 201 Created and JSON response {"errors": ["some message"]} (list of error messages). The response has the Location header pointing to the new submission.
      • student is not allowed to submit (e.g., deadlines or max submissions limit): HTTP 400 Bad request and JSON response {"errors": ["some message"]} (list of error messages)
      • authentication failed: HTTP 403 Forbidden and JSON response  {"detail": "some message"} (a single error string)
      • A+ can not create the submission in the database: HTTP 500 Internal error and JSON response {"detail": "some message"}
      • something else? The Django REST framework may have some built-in validation or something else that would probably use the "detail" key for the error message.
    • The following bullets are comments about the old API before the changes:
      • Currently, only exercise grading service is authorized for this endpoint: https://github.com/apluslms/a-plus/blob/f22aa494e6ebeb7a5fa86111ec424fefcd3b13d0/exercise/api/views.py#L79
      • The same views.py file contains other API endpoints that are related to the A+ grader protocol and manual grading:
        • ExerciseViewSet grader_detail: part of the grader protocol for the mooc-grader. Creates a new submission and grades it. Only one submitter (student). No submission files. This endpoint corresponds to the submission_url parameter of the grader protocol when the exercise description is fetched with HTTP GET.
        • ExerciseSubmissionsViewSet create: only allowed for teachers. Creates a new submission and grades it (basically, it can be used for storing the results of manual grading). Can set feedback, assistant feedback and submission time too. No submission files.
        • SubmissionViewSet grader_detail: part of the grader protocol for the mooc-grader. Grades an existing submission (used in normal asynchronous grading). This endpoint corresponds to the submission_url parameter of the grader protocol when the submission is sent to the exercise service for grading with HTTP POST.
      • The existing endpoint does not support group submissions. The new endpoint should receive the group ID in the POST parameters so that the group members can be added to the submission. Normal submissions in the web page include the submitting user and the group ID in the POST data.
      • Submitting files must be supported.
      • The API must check if the user is allowed to submit to the exercise (like in normal submissions in the web UI).
      • It is  best to create yet another new API endpoint for this. The other old endpoints are intended for different usecases
  • Authentication
    • The existing user tokens can be used in the API for authenticating the user. Users can see their token in their A+ profile page (accessed from the top-right user menu).
    • The API endpoints take the token from the HTTP request Authorization header in the format "Authorization: Token 94ad2abfc128a3da3b0541fbfea981bc62becd56".
    • If we can't implement any better authentication method, then users could manually copy-paste their token from the A+ web page into some menu in the IntelliJ plugin. The plugin could store the token so that it is only set up once.
    • The user tokens are specific to each user and they do not automatically expire. We should avoid leaking these tokens to any malicious outsiders since they are basically like passwords.
    • Improvements to the authentication:
      • Users should not see or manually enter the token in the IntelliJ plugin. Users should be able to log into A+ from the plugin by entering their user name and password.
      • Is it possible to use a web view (browser) inside IntelliJ IDEA in such a way that the user would log into A+ inside IntelliJ and IntelliJ could then capture the user's token from A+ and store the token? The user would not need to manually copy-paste the token.
      • Because A+ typically uses single sign-on (Shibboleth, HAKA federation), it might not be possible to implement an API endpoint that takes the username and password as input and returns the API user token.

Status (what has been completed)

  • No labels