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. |
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.
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": {}}
|
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.
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.
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,
...
]
}
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.
{
"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)"
}
}
]
}
]
}
{
"partials": [],
"accepted": false,
"compile_error": null,
"result": {
"text": "Exitcode %(exitcode)s != 0.",
"kwargs": {
"exitcode": -5
}
}
}