OpenContest is a simple, open, and federated HTTPS JSON protocol to enable anyone to develop and host online programming contests!
Go to file
Anthony Wang 25f71d6139
Deprecate the React web client
2022-04-26 11:32:47 -05:00
LICENSE Change license to CC BY-SA 4.0 2021-10-16 22:09:01 -05:00
README.md Deprecate the React web client 2022-04-26 11:32:47 -05:00

README.md

OpenContest

The OpenContest Protocol (formerly LGP) is a simple, open, and federated HTTPS JSON protocol to enable anyone to develop and host online programming contests. You can register an account with any OpenContest server and use that account to submit to problems hosted on any OpenContest server or even other platforms like Codeforces via protocol extensions. Even better, you can easily to host your own OpenContest server on a home computer, Raspberry Pi, or VPS, and create your own contests using problems from all OpenContest servers. The possibilities are endless!

The protocol governs the interactions between OpenContest clients like the Python CLI client, Go CLI client, and Bootstrap web client and OpenContest servers like the Python server. (There is also a deprecated React web client and HTML web client) HTTPS provides built-in security for the protocol without requiring any additional cryptography. With only 10 different request types, OpenContest's design emphasizes simplicity, and is thus extremely easy to implement.

The OpenContest standard is licensed under the Creative Commons Attribution Share Alike 4.0 International.

HTTPS POST request

The OpenContest protocol consists of servers that host contests and clients that participate in those contests. All client requests are HTTPS POST requests of JSON data, such as this one, for submitting code:

{
    "type": "submit",
    "username": "test",
    "homeserver": "example.com",
    "token": "1234567890",
    "contest": "test",
    "problem": "aplusb",
    "language": "py",
    "code": "a,b = map(int, input().split())\nprint(a + b)\n"
}

HTTPS response status codes

For each client request, the server responds with a HTTPS status code and optionally a JSON response body. The status code 400 indicates a request could not be parsed or did not contain all required JSON fields. The code 500 means an internal error occured, while 501 means that the server does not implement that request type.

Authentication

When making a request that requires authentication, a client should not provide their username and password directly to a contest server. Instead, the client should make their request to their homeserver (the server where the user registered their account) containing the contest server. The homeserver generates an authentication token, and forwards the client's request, with the password replaced by the token, to the contest server. The contest server verifies this token is valid by making an authenticate request back to the homeserver. The homeserver should confirm that the token was generated by this homeserver and respond with the status code 200. The contest server can then proceed to process the request and respond with the result to the homeserver, which is forwarded to the client.

Query server information

This request queries for information about a OpenContest server.

Client request

{
    "type": "about"
}

Server response

Status Code Result
200 Query succeeded

The body of the response contains information about the OpenContest server.

{
    "version": OpenContest Protocol version,
    "languages": {
        language1: compiler version,
        language2: compiler version
    },
    "contests": [contest1, contest2]
}

Query contest or problem information

This request queries the server for information about a problem, or contest if a problem is not specified.

Client request

{
    "type": "info",
    "contest": contest,
    "problem": problem (optional)
}

Server response

Status Code Result
200 Query succeeded
403 Contest has not started yet
404 Contest or problem not found

The body of the response contains information about the queried contest or problem.

For contests:

{
    "name": contest name,
    "description": description,
    "start": start time in ISO format,
    "length": length in minutes,
    "problems": [problem1, problem2]
}

For problems:

{
    "name": problem name,
    "author": problem author (optional),
    "statement": problem statement,
    "sample-input": sample input (optional),
    "sample-output": sample output (optional),
    "time-limit": time limit in seconds,
    "memory-limit": memory limit in KiB,
    "points": point value,
    "penalty": penalty value (optional),
    "checker": checker command (optional)
}

Query contest solves

This request queries the server for the number of solves for a problem or each problem in a contest.

Client request

{
    "type": "solves",
    "contest": contest,
    "problem": problem (optional)
}

Server response

Status Code Result
200 Query succeeded
403 Contest has not started yet
404 Contest or problem not found

The body of the response contains the number of solves of the problem or problems.

Query submission history

This request queries the submission history of all users in a contest.

Client request

{
    "type": "history",
    "contest": contest,
    "problem": problem (optional)
}

Server response

Status Code Result
200 Query successful
403 Contest has not started yet
404 Contest or problem not found

The body of the response contains the submission history, with the submission number and verdict of each submission.

Manage user account information

This request manages a user's account information.

Client request

{
    "type": "user",
    "name": name,
    "email": email,
    "username": username,
    "password": password
}

Server response

Status Code Result
201 Account creation succeeded
403 Password incorrect

If the username does not exist, a new user is created by the server. Otherwise, as long as the username and password are correct, the server will update the user's information. If the password is correct and the name field in this request is DELETE, the user is deleted by the server. Password resets are not yet supported and users should contact the server administrator for that.

Authenticate token

This server-to-server request sends a token from one server to another.

Server request

{
    "type": "authorize",
    "username": username,
    "token": token
}

Server response

Status Code Result
200 Authentication succeeded
403 Incorrect token
404 Username not found

Submit code

This request submits code to a particular problem in a contest. This request requires authentication.

Client request

{
    "type": "submit",
    "username": username,
    "homeserver": homeserver,
    "token": token,
    "contest": contest,
    "problem": problem,
    "language": language,
    "code": code
}

Server response

Status Code Result
202 Accepted
401 Incorrect token
403 Contest has not started yet
404 Contest or problem not found
406 Wrong answer
408 Time limit exceeded
500 Compilation error or runtime error

Query user status

This request queries the status of the user in a particular contest, such as which problems are solved and the verdicts. This request requires authentication.

Client request

Use a POST request as below:

{
    "type": "status",
    "username": username,
    "homeserver": homeserver,
    "token": token,
    "contest": contest,
    "problem": problem (optional)
}

Server response

Status Code Result
200 Query successful
401 Incorrect token
403 Contest has not started yet
404 Contest or problem not found

The body of the response contains information about the user's status in that contest.

Query user submission history

This request queries the submission history of the user, returning the submission number and verdict of each submission. This request requires authentication.

Client request

{
    "type": "submissions",
    "username": username,
    "homeserver": homeserver,
    "token": token,
    "contest": contest,
    "problem": problem (optional)
}

Server response

Status Code Result
200 Query successful
401 Incorrect token
403 Contest has not started yet
404 Contest or problem not found

The body of the response contains the submission history in the contest for the user.

Query submission code

This request queries the code that a user submitted to a particular problem. The submission number can be found using the submission history request. This request requires authentication.

Client request

Use a POST request as below:

{
    "type": "code",
    "username": username,
    "homeserver": homeserver,
    "token": token,
    "contest": contest,
    "number": submission number
}

Server response

Status Code Result
200 Query successful
401 Incorrect token
403 Contest has not started yet
404 Contest or problem not found

The body of the response should contain exactly the code that the user submitted.