Website API

List of APIs

First, let’s list all the API views in the following table:

View Function Description
railgun.website.api.api_handin_report() Store the detailed reports of a given submission.
railgun.website.api.api_handin_start() Change the state of a given submission from Pending to Running.
railgun.website.api.api_handin_proclog() Update the process output of a given submission.
railgun.website.api.api_myip() Display the visitor’s ip address.

Protocol

A request from the client is carried in a standard HTTP request, while the result is sent back in the HTTP response.

The request from client may carry important objects that must not be revealed to student users. These objects should be serialized in JSON format, encrypted by AES crypto, and sent to the server through a POST request. Moreover, the POST requests should carry an additional header:

Content-Type: application/octet-stream

To create compatible encrypted data with Railgun system, you may refer to railgun.common.crypto.AESCipher.

Object Types

Basic Types

Since the objects are serialized in JSON format, the following tables shows all the basic types in a JSON message:

Type Description
boolean true or false.
int Integral number literals.
float Real number literals.
string String literals surrounded by pairs of “``”``”.
list

A sequence of objects separated by “,”, while the whole literal surrounded by “[” and “]”, for example:

[1, 2.0, 3e-8, true, "Alice", []]
dict

A collection of "name": object separated by “,”, while the whole literal surrounded by “{” and “}”, for example:

{"int": 1, "float": 2.0, "bool": true,
 "string": "Alice", "list": [3e-8],
 "dict": {}}

GetTextString

railgun.common.lazy_i18n.GetTextString could be encoded to JSON format. For example, if we have the following GetTextString object:

lazy_gettext('My name is %(name)s, and I am a %(nation)s',
             name='Alice', nation='American')

Then we can serialize the object by railgun.common.lazy_i18n.lazystr_to_plain():

{
    "text": "My name is %(name)s, and I am a %(nation)s",
    "kwargs": {
        "name": "Alice",
        "nation": "American"
    }
}

Note

If kwargs is empty, you must keep an empty dict in the JSON serialized message.

HwPartialScore

railgun.common.hw.HwPartialScore could be encoded to JSON format. The JSON object should follow the schema:

{
    "name": GetTextString or string,
    "typeName": string,
    "score": float,
    "weight": float,
    "time": float,
    "brief": GetTextString or string,
    "detail": [
        GetTextString or string,
        ...
    ]
}

GetTextString or string means the mentioned attribute could either be a GetTextString object, or a basic string object. However, it is always recommended to use a GetTextString rather than basic string, to provide translations to different users.

HwScore

railgun.common.hw.HwScore could be encoded to JSON format. The JSON object should follow the schema:

{
    "accepted": boolean,
    "result": GetTextString or string,
    "compile_error": GetTextString or string,
    "partials": [
        HwPartialScore,
        ...
    ]
}

Two Examples of HwScore

To make you better understand the transfered HwScore object, I’ll show you two examples. The first one is an HwScore object for an Accepted submission, while the latter one for a failure and Rejected submission.

HwScore for Accepted

{
  "accepted": true,
  "compile_error": {
    "text": "",
    "kwargs": {}
  },
  "result": {
    "text": "Your submission is accepted.",
    "kwargs": {}
  },
  "partials": [
    {
      "name": {
        "text": "InputClass Scorer",
        "kwargs": {}
      },
      "typeName": "InputClassScorer",
      "time": 0.000146151,
      "score": 15.3846,
      "weight": 0.6,
      "brief": {
        "text": "%(rate).2f%% rules (%(cover)s out of %(total)s) covered",
        "kwargs": {
          "rate": 15.3846,
          "total": 13,
          "cover": 2
        }
      },
      "detail": [
        {
          "text": "NOT COVERED: %(checker)s",
          "kwargs": {
            "checker": "regular triangle"
          }
        },
        {
          "text": "NOT COVERED: %(checker)s",
          "kwargs": {
            "checker": "isosceles triangle (a, b, c > 0) and (a == b != c)"
          }
        }
      ]
    },
    {
      "name": {
        "text": "BoundaryValue Scorer",
        "kwargs": {}
      },
      "typeName": "BoundaryValueScorer",
      "time": 6.79493e-05,
      "score": 0,
      "weight": 0.4,
      "brief": {
        "text": "%(rate).2f%% rules (%(cover)s out of %(total)s) covered",
        "kwargs": {
          "rate": 0,
          "total": 2,
          "cover": 0
        }
      },
      "detail": [
        {
          "text": "NOT COVERED: %(checker)s",
          "kwargs": {
            "checker": "zero data (one of a, b, c == 0)"
          }
        },
        {
          "text": "NOT COVERED: %(checker)s",
          "kwargs": {
            "checker": "zero data (all of a, b, c == 0)"
          }
        }
      ]
    }
  ]
}

HwScore for Rejected

{
  "partials": [],
  "accepted": false,
  "compile_error": null,
  "result": {
    "text": "Exitcode %(exitcode)s != 0.",
    "kwargs": {
      "exitcode": -5
    }
  }
}

Table Of Contents

Previous topic

Technique Overview

Next topic

Common Library

This Page