atz21 commited on
Commit
d5fff10
·
verified ·
1 Parent(s): 751b873

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +50 -28
app.py CHANGED
@@ -4,16 +4,14 @@ import google.generativeai as genai
4
  from reportlab.platypus import SimpleDocTemplate, Paragraph
5
  from reportlab.lib.styles import getSampleStyleSheet
6
  from reportlab.lib.pagesizes import A4
 
7
 
8
  # -------------------- CONFIG --------------------
9
  genai.configure(api_key=os.getenv("GEMINI_API_KEY"))
10
 
11
  # ---------- PROMPTS ----------
12
- TRANSCRIPTION_PROMPT = """ Transcribe the PDF into a clean, question-wise format. While doing so, ensure the following:
13
- Exclude any text that has been cut, striked, or crossed out (since these may represent student mistakes).
14
- Clearly distinguish between a "step cut" and when variables cancel out during a step.
15
- Present the transcription neatly without including unnecessary markings. """
16
- GRADING_PROMPT = """ Instructions to Examiners:
17
  Abbreviations:
18
  - M: Marks for correct Method.
19
  - A: Marks for Answer or Accuracy (often depends on preceding M mark).
@@ -42,17 +40,41 @@ def save_as_pdf(text, filename="output.pdf"):
42
  doc.build(story)
43
  return filename
44
 
45
- # ---------- HELPER: Safe Generate ----------
46
- def safe_generate(model, inputs):
47
- resp = model.generate_content(inputs)
48
- cand = resp.candidates[0] if resp.candidates else None
 
 
 
 
 
49
 
50
- if not cand or not cand.content or not cand.content.parts:
51
  reason = getattr(cand, "finish_reason", "None")
52
- ratings = getattr(cand, "safety_ratings", "None")
53
- return None, f"❌ Empty/blocked response. finish_reason={reason}, safety_ratings={ratings}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
 
55
- return resp.text, None
 
56
 
57
  # ---------- STEP 1: TRANSCRIPTION ----------
58
  def transcribe(ans_file):
@@ -61,15 +83,15 @@ def transcribe(ans_file):
61
  model = genai.GenerativeModel(
62
  "gemini-2.5-pro",
63
  generation_config={"temperature": 0},
64
- safety_settings={
65
- genai.types.HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT: genai.types.HarmBlockThreshold.BLOCK_NONE,
66
- genai.types.HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT: genai.types.HarmBlockThreshold.BLOCK_NONE,
67
- genai.types.HarmCategory.HARM_CATEGORY_HATE_SPEECH: genai.types.HarmBlockThreshold.BLOCK_NONE,
68
- genai.types.HarmCategory.HARM_CATEGORY_HARASSMENT: genai.types.HarmBlockThreshold.BLOCK_NONE,
69
- }
70
  )
71
 
72
- transcription, error = safe_generate(model, [TRANSCRIPTION_PROMPT, ans_uploaded])
73
  if error:
74
  return error, None
75
 
@@ -86,15 +108,15 @@ def grade(qp_file, ms_file, transcription):
86
  model = genai.GenerativeModel(
87
  "gemini-2.5-pro",
88
  generation_config={"temperature": 0},
89
- safety_settings={
90
- genai.types.HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT: genai.types.HarmBlockThreshold.BLOCK_NONE,
91
- genai.types.HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT: genai.types.HarmBlockThreshold.BLOCK_NONE,
92
- genai.types.HarmCategory.HARM_CATEGORY_HATE_SPEECH: genai.types.HarmBlockThreshold.BLOCK_NONE,
93
- genai.types.HarmCategory.HARM_CATEGORY_HARASSMENT: genai.types.HarmBlockThreshold.BLOCK_NONE,
94
- }
95
  )
96
 
97
- grading, error = safe_generate(model, [GRADING_PROMPT, qp_uploaded, ms_uploaded, transcription])
98
  if error:
99
  return error, None
100
 
@@ -139,4 +161,4 @@ with gr.Blocks(title="LeadIB AI Grading") as demo:
139
  )
140
 
141
  if __name__ == "__main__":
142
- demo.launch()
 
4
  from reportlab.platypus import SimpleDocTemplate, Paragraph
5
  from reportlab.lib.styles import getSampleStyleSheet
6
  from reportlab.lib.pagesizes import A4
7
+ from google.generativeai.types import HarmCategory, HarmBlockThreshold, SafetySetting
8
 
9
  # -------------------- CONFIG --------------------
10
  genai.configure(api_key=os.getenv("GEMINI_API_KEY"))
11
 
12
  # ---------- PROMPTS ----------
13
+ TRANSCRIPTION_PROMPT = """Convert the student’s PDF into structured text with each question clearly separated. Ignore crossed-out steps or markings."""
14
+ GRADING_PROMPT = """Instructions to Examiners:
 
 
 
15
  Abbreviations:
16
  - M: Marks for correct Method.
17
  - A: Marks for Answer or Accuracy (often depends on preceding M mark).
 
40
  doc.build(story)
41
  return filename
42
 
43
+ # ---------- HELPER: Safe Generate with Retry ----------
44
+ def safe_generate(model, inputs, fallback_prompt=None):
45
+ try:
46
+ # Try normal generate
47
+ resp = model.generate_content(inputs)
48
+ cand = resp.candidates[0] if resp.candidates else None
49
+
50
+ if cand and cand.content and cand.content.parts:
51
+ return resp.text, None
52
 
 
53
  reason = getattr(cand, "finish_reason", "None")
54
+ if reason == "1": # SAFETY block
55
+ # Retry with streaming
56
+ chunks = []
57
+ stream_resp = model.generate_content(inputs, stream=True)
58
+ for chunk in stream_resp:
59
+ if chunk.candidates and chunk.candidates[0].content.parts:
60
+ chunks.append(chunk.text)
61
+ if chunks:
62
+ return "".join(chunks), None
63
+
64
+ # Retry with simplified prompt if provided
65
+ if fallback_prompt:
66
+ retry_resp = model.generate_content([fallback_prompt] + inputs[1:], stream=True)
67
+ chunks = []
68
+ for chunk in retry_resp:
69
+ if chunk.candidates and chunk.candidates[0].content.parts:
70
+ chunks.append(chunk.text)
71
+ if chunks:
72
+ return "".join(chunks), None
73
+
74
+ return None, f"❌ Empty/blocked response. finish_reason={reason}, safety_ratings={getattr(cand, 'safety_ratings', None)}"
75
 
76
+ except Exception as e:
77
+ return None, f"❌ Exception: {e}"
78
 
79
  # ---------- STEP 1: TRANSCRIPTION ----------
80
  def transcribe(ans_file):
 
83
  model = genai.GenerativeModel(
84
  "gemini-2.5-pro",
85
  generation_config={"temperature": 0},
86
+ safety_settings=[
87
+ SafetySetting(category=HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT, threshold=HarmBlockThreshold.BLOCK_NONE),
88
+ SafetySetting(category=HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT, threshold=HarmBlockThreshold.BLOCK_NONE),
89
+ SafetySetting(category=HarmCategory.HARM_CATEGORY_HATE_SPEECH, threshold=HarmBlockThreshold.BLOCK_NONE),
90
+ SafetySetting(category=HarmCategory.HARM_CATEGORY_HARASSMENT, threshold=HarmBlockThreshold.BLOCK_NONE),
91
+ ]
92
  )
93
 
94
+ transcription, error = safe_generate(model, [TRANSCRIPTION_PROMPT, ans_uploaded], fallback_prompt="Convert the PDF into structured plain text with questions separated.")
95
  if error:
96
  return error, None
97
 
 
108
  model = genai.GenerativeModel(
109
  "gemini-2.5-pro",
110
  generation_config={"temperature": 0},
111
+ safety_settings=[
112
+ SafetySetting(category=HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT, threshold=HarmBlockThreshold.BLOCK_NONE),
113
+ SafetySetting(category=HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT, threshold=HarmBlockThreshold.BLOCK_NONE),
114
+ SafetySetting(category=HarmCategory.HARM_CATEGORY_HATE_SPEECH, threshold=HarmBlockThreshold.BLOCK_NONE),
115
+ SafetySetting(category=HarmCategory.HARM_CATEGORY_HARASSMENT, threshold=HarmBlockThreshold.BLOCK_NONE),
116
+ ]
117
  )
118
 
119
+ grading, error = safe_generate(model, [GRADING_PROMPT, qp_uploaded, ms_uploaded, transcription], fallback_prompt="Grade the answers according to the marking scheme. Show marks step by step.")
120
  if error:
121
  return error, None
122
 
 
161
  )
162
 
163
  if __name__ == "__main__":
164
+ demo.launch()