Skip to main content

Grade an exam

POST /api/v1/grade is the only implemented HTTP endpoint. It consumes multipart/form-data with both of these required request parameters:

PartTypeMeaning
imagefileThe exam sheet image processed by OpenCV.
answersfileA header-based CSV answer key parsed with OpenCSV.

The CSV header names are questionNumber and correctAnswer:

questionNumber,correctAnswer
1,B
2,C
3,A

The service compares detected answers to every CSV row, case-insensitively. score is (correctCount / number of CSV rows) * 10, rounded to two decimals. An empty answer key produces score 0.0.

Request example

curl -X POST http://localhost:8080/api/v1/grade \
-F "image=@data/test_1.jpeg" \
-F "answers=@answer_key.csv"

localhost:8080 is a local example, not a public deployment recommendation.

Successful response

On success the controller returns HTTP 200 and serializes GradeResult with these fields:

FieldJava typeMeaning
studentNameStringOCR output from the fixed name crop.
classNameStringOCR output from the fixed class crop.
scoredoubleScore on a 0-10 scale, rounded to two decimals.
correctCountintNumber of CSV rows with matching detected answers.
totalQuestionsintNumber of rows parsed from the submitted CSV, not necessarily 40.
incorrectQuestionsList<Integer>CSV question numbers that did not match.
studentAnswersMap<Integer, String>Detected answers for questions 1 through 40.

Example shape:

{
"studentName": "...",
"className": "...",
"score": 8.75,
"correctCount": 35,
"totalQuestions": 40,
"incorrectQuestions": [6, 17, 29, 40],
"studentAnswers": {"1": "B", "2": "C"}
}

This is documentation of the current Java model, not a versioned or stable OpenAPI schema. Do not assume input validation, file-type checks, upload-size limits, authentication, authorization, CORS behavior, or 4xx response contracts. See errors.