Update app.py
Browse files
app.py
CHANGED
|
@@ -1,16 +1,16 @@
|
|
| 1 |
import os
|
| 2 |
import gradio as gr
|
| 3 |
import google.generativeai as genai
|
| 4 |
-
from google.generativeai.types import HarmCategory, HarmBlockThreshold
|
| 5 |
from markdown_pdf import MarkdownPdf, Section
|
| 6 |
|
| 7 |
# -------------------- CONFIG --------------------
|
| 8 |
genai.configure(api_key=os.getenv("GEMINI_API_KEY"))
|
| 9 |
|
| 10 |
-
# ---------- PROMPTS (JSON
|
|
|
|
| 11 |
PROMPTS = {
|
| 12 |
"TRANSCRIPTION_PROMPT": {
|
| 13 |
-
"role": "
|
| 14 |
"content": """Your Role: You are an expert technical transcriber specializing in mathematical and scientific documents.
|
| 15 |
Your mission is to convert handwritten solutions from a provided image or PDF into a clean, accurate, and logically structured Markdown format.
|
| 16 |
Instructions:
|
|
@@ -22,7 +22,7 @@ Instructions:
|
|
| 22 |
"""
|
| 23 |
},
|
| 24 |
"MARKSCHEME_TRANSCRIPTION_PROMPT": {
|
| 25 |
-
"role": "
|
| 26 |
"content": """Your Role: You are an expert transcriber.
|
| 27 |
Convert the official marking scheme from the provided PDF into clean, structured Markdown.
|
| 28 |
Instructions:
|
|
@@ -35,7 +35,7 @@ Instructions:
|
|
| 35 |
"""
|
| 36 |
},
|
| 37 |
"GRADING_PROMPT": {
|
| 38 |
-
"role": "
|
| 39 |
"content": """You are an official examiner. Use the following grading rules strictly.
|
| 40 |
Abbreviations:
|
| 41 |
- M: Marks awarded for attempting to use a correct Method.
|
|
@@ -76,9 +76,9 @@ Produce a GitHub-flavored Markdown table with 3 columns:
|
|
| 76 |
|---------------|---------------|--------|
|
| 77 |
Special Formatting Rule:
|
| 78 |
- Whenever a mark is lost (M0, A0, R0 etc.), wrap it in red using: `<span style=\"color:red\">M0</span>`.
|
| 79 |
-
- Also wrap the corresponding Reason in red
|
| 80 |
- Keep awarded marks (M1, A1, etc.) in plain text.
|
| 81 |
-
- If mixed (e.g., M1A0A1), only highlight the lost marks (`A0`) and its reason.
|
| 82 |
After the table, provide:
|
| 83 |
### Summary & Final Mark
|
| 84 |
- Total marks obtained vs total available
|
|
@@ -95,27 +95,17 @@ def save_as_pdf(text, filename="output.pdf"):
|
|
| 95 |
pdf.save(filename)
|
| 96 |
return filename
|
| 97 |
|
| 98 |
-
# ---------- COMMON MODEL CALL ----------
|
| 99 |
-
def call_model(inputs):
|
| 100 |
-
model = genai.GenerativeModel("gemini-2.5-pro", generation_config={"temperature": 0})
|
| 101 |
-
response = model.generate_content(
|
| 102 |
-
inputs,
|
| 103 |
-
safety_settings={
|
| 104 |
-
HarmCategory.HARM_CATEGORY_HATE_SPEECH: HarmBlockThreshold.BLOCK_LOW_AND_ABOVE,
|
| 105 |
-
HarmCategory.HARM_CATEGORY_HARASSMENT: HarmBlockThreshold.BLOCK_NONE,
|
| 106 |
-
}
|
| 107 |
-
)
|
| 108 |
-
if getattr(response, "text", None):
|
| 109 |
-
return response.text
|
| 110 |
-
elif response.candidates:
|
| 111 |
-
return response.candidates[0].content.parts[0].text
|
| 112 |
-
return None
|
| 113 |
-
|
| 114 |
# ---------- STEP 1: TRANSCRIBE STUDENT ----------
|
| 115 |
def transcribe_student(ans_file):
|
| 116 |
try:
|
| 117 |
ans_uploaded = genai.upload_file(path=ans_file, display_name="Answer Sheet")
|
| 118 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 119 |
pdf_path = save_as_pdf(transcription, "student_transcription.pdf")
|
| 120 |
return transcription, pdf_path
|
| 121 |
except Exception as e:
|
|
@@ -125,7 +115,13 @@ def transcribe_student(ans_file):
|
|
| 125 |
def transcribe_ms(ms_file):
|
| 126 |
try:
|
| 127 |
ms_uploaded = genai.upload_file(path=ms_file, display_name="Markscheme")
|
| 128 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 129 |
pdf_path = save_as_pdf(ms_transcription, "ms_transcription.pdf")
|
| 130 |
return ms_transcription, pdf_path
|
| 131 |
except Exception as e:
|
|
@@ -135,12 +131,19 @@ def transcribe_ms(ms_file):
|
|
| 135 |
def grade(qp_file, ms_transcription, student_transcription):
|
| 136 |
try:
|
| 137 |
qp_uploaded = genai.upload_file(path=qp_file, display_name="Question Paper")
|
| 138 |
-
|
|
|
|
|
|
|
| 139 |
PROMPTS["GRADING_PROMPT"]["content"],
|
| 140 |
qp_uploaded,
|
| 141 |
"### Markscheme Transcription:\n" + ms_transcription,
|
| 142 |
"### Student Transcription:\n" + student_transcription
|
| 143 |
])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 144 |
pdf_path = save_as_pdf(grading, "grading.pdf")
|
| 145 |
return grading, pdf_path
|
| 146 |
except Exception as e:
|
|
|
|
| 1 |
import os
|
| 2 |
import gradio as gr
|
| 3 |
import google.generativeai as genai
|
|
|
|
| 4 |
from markdown_pdf import MarkdownPdf, Section
|
| 5 |
|
| 6 |
# -------------------- CONFIG --------------------
|
| 7 |
genai.configure(api_key=os.getenv("GEMINI_API_KEY"))
|
| 8 |
|
| 9 |
+
# ---------- PROMPTS (JSON style) ----------
|
| 10 |
+
|
| 11 |
PROMPTS = {
|
| 12 |
"TRANSCRIPTION_PROMPT": {
|
| 13 |
+
"role": "system",
|
| 14 |
"content": """Your Role: You are an expert technical transcriber specializing in mathematical and scientific documents.
|
| 15 |
Your mission is to convert handwritten solutions from a provided image or PDF into a clean, accurate, and logically structured Markdown format.
|
| 16 |
Instructions:
|
|
|
|
| 22 |
"""
|
| 23 |
},
|
| 24 |
"MARKSCHEME_TRANSCRIPTION_PROMPT": {
|
| 25 |
+
"role": "system",
|
| 26 |
"content": """Your Role: You are an expert transcriber.
|
| 27 |
Convert the official marking scheme from the provided PDF into clean, structured Markdown.
|
| 28 |
Instructions:
|
|
|
|
| 35 |
"""
|
| 36 |
},
|
| 37 |
"GRADING_PROMPT": {
|
| 38 |
+
"role": "system",
|
| 39 |
"content": """You are an official examiner. Use the following grading rules strictly.
|
| 40 |
Abbreviations:
|
| 41 |
- M: Marks awarded for attempting to use a correct Method.
|
|
|
|
| 76 |
|---------------|---------------|--------|
|
| 77 |
Special Formatting Rule:
|
| 78 |
- Whenever a mark is lost (M0, A0, R0 etc.), wrap it in red using: `<span style=\"color:red\">M0</span>`.
|
| 79 |
+
- Also wrap the corresponding Reason in red color.
|
| 80 |
- Keep awarded marks (M1, A1, etc.) in plain text.
|
| 81 |
+
- If mixed (e.g., M1A0A1), only highlight the lost marks (`A0`) and its reason.
|
| 82 |
After the table, provide:
|
| 83 |
### Summary & Final Mark
|
| 84 |
- Total marks obtained vs total available
|
|
|
|
| 95 |
pdf.save(filename)
|
| 96 |
return filename
|
| 97 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 98 |
# ---------- STEP 1: TRANSCRIBE STUDENT ----------
|
| 99 |
def transcribe_student(ans_file):
|
| 100 |
try:
|
| 101 |
ans_uploaded = genai.upload_file(path=ans_file, display_name="Answer Sheet")
|
| 102 |
+
model = genai.GenerativeModel("gemini-2.5-pro", generation_config={"temperature": 0})
|
| 103 |
+
|
| 104 |
+
resp = model.generate_content([PROMPTS["TRANSCRIPTION_PROMPT"]["content"], ans_uploaded])
|
| 105 |
+
transcription = getattr(resp, "text", None)
|
| 106 |
+
if not transcription and resp.candidates:
|
| 107 |
+
transcription = resp.candidates[0].content.parts[0].text
|
| 108 |
+
|
| 109 |
pdf_path = save_as_pdf(transcription, "student_transcription.pdf")
|
| 110 |
return transcription, pdf_path
|
| 111 |
except Exception as e:
|
|
|
|
| 115 |
def transcribe_ms(ms_file):
|
| 116 |
try:
|
| 117 |
ms_uploaded = genai.upload_file(path=ms_file, display_name="Markscheme")
|
| 118 |
+
model = genai.GenerativeModel("gemini-2.5-pro", generation_config={"temperature": 0})
|
| 119 |
+
|
| 120 |
+
resp = model.generate_content([PROMPTS["MARKSCHEME_TRANSCRIPTION_PROMPT"]["content"], ms_uploaded])
|
| 121 |
+
ms_transcription = getattr(resp, "text", None)
|
| 122 |
+
if not ms_transcription and resp.candidates:
|
| 123 |
+
ms_transcription = resp.candidates[0].content.parts[0].text
|
| 124 |
+
|
| 125 |
pdf_path = save_as_pdf(ms_transcription, "ms_transcription.pdf")
|
| 126 |
return ms_transcription, pdf_path
|
| 127 |
except Exception as e:
|
|
|
|
| 131 |
def grade(qp_file, ms_transcription, student_transcription):
|
| 132 |
try:
|
| 133 |
qp_uploaded = genai.upload_file(path=qp_file, display_name="Question Paper")
|
| 134 |
+
model = genai.GenerativeModel("gemini-2.5-pro", generation_config={"temperature": 0})
|
| 135 |
+
|
| 136 |
+
response = model.generate_content([
|
| 137 |
PROMPTS["GRADING_PROMPT"]["content"],
|
| 138 |
qp_uploaded,
|
| 139 |
"### Markscheme Transcription:\n" + ms_transcription,
|
| 140 |
"### Student Transcription:\n" + student_transcription
|
| 141 |
])
|
| 142 |
+
|
| 143 |
+
grading = getattr(response, "text", None)
|
| 144 |
+
if not grading and response.candidates:
|
| 145 |
+
grading = response.candidates[0].content.parts[0].text
|
| 146 |
+
|
| 147 |
pdf_path = save_as_pdf(grading, "grading.pdf")
|
| 148 |
return grading, pdf_path
|
| 149 |
except Exception as e:
|