atz21 commited on
Commit
630855b
Β·
verified Β·
1 Parent(s): 050210e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +37 -19
app.py CHANGED
@@ -40,13 +40,14 @@ else:
40
  # Prompts are now imported from prompts.py
41
 
42
  # ---------------- SUPABASE HELPERS ----------------
43
- def upload_file_to_supabase(local_path, file_type="unknown"):
44
  """
45
  Upload a file to Supabase Storage.
46
 
47
  Args:
48
  local_path (str): Local file path
49
  file_type (str): Type of file (qp, ms, ans, graded, imprinted)
 
50
 
51
  Returns:
52
  str: Public URL of uploaded file or None if upload failed
@@ -56,9 +57,12 @@ def upload_file_to_supabase(local_path, file_type="unknown"):
56
  return None
57
 
58
  try:
59
- timestamp = str(int(time.time()))
 
 
60
  original_name = os.path.basename(local_path)
61
- remote_path = f"{timestamp}/{file_type}_{original_name}"
 
62
 
63
  print(f"πŸ“€ Uploading {file_type} to Supabase: {remote_path}")
64
 
@@ -79,7 +83,7 @@ def upload_file_to_supabase(local_path, file_type="unknown"):
79
 
80
  def process_and_upload_input_files(qp_file_obj, ms_file_obj, ans_file_obj):
81
  """
82
- Process uploaded files and upload them to Supabase.
83
 
84
  Args:
85
  qp_file_obj: Gradio file object for Question Paper
@@ -87,12 +91,16 @@ def process_and_upload_input_files(qp_file_obj, ms_file_obj, ans_file_obj):
87
  ans_file_obj: Gradio file object for Answer Sheet
88
 
89
  Returns:
90
- tuple: (qp_path, ms_path, ans_path, upload_urls_dict)
91
  """
92
  print("\n" + "="*60)
93
  print("πŸ“ PROCESSING INPUT FILES")
94
  print("="*60)
95
 
 
 
 
 
96
  upload_urls = {
97
  "qp_url": None,
98
  "ms_url": None,
@@ -104,18 +112,18 @@ def process_and_upload_input_files(qp_file_obj, ms_file_obj, ans_file_obj):
104
  ms_path = ms_file_obj.name if ms_file_obj else None
105
  ans_path = ans_file_obj.name if ans_file_obj else None
106
 
107
- # Upload to Supabase if configured
108
  if supabase_client:
109
  if qp_path:
110
- upload_urls["qp_url"] = upload_file_to_supabase(qp_path, "qp")
111
  if ms_path:
112
- upload_urls["ms_url"] = upload_file_to_supabase(ms_path, "ms")
113
  if ans_path:
114
- upload_urls["ans_url"] = upload_file_to_supabase(ans_path, "ans")
115
 
116
  print("="*60 + "\n")
117
 
118
- return qp_path, ms_path, ans_path, upload_urls
119
 
120
 
121
 
@@ -1051,9 +1059,17 @@ def extract_pdf_pages_as_images(pdf_path, page_numbers, prefix):
1051
  return out_paths
1052
 
1053
  # ---------------- PIPELINE ----------------
1054
- def align_and_grade_pipeline(qp_path, ms_path, ans_path, subject="Maths", imprint=False):
1055
  """
1056
  Final pipeline with graph-aware grading logic using NEW SDK.
 
 
 
 
 
 
 
 
1057
  """
1058
  try:
1059
  print("πŸ” Starting pipeline...")
@@ -1146,7 +1162,7 @@ def align_and_grade_pipeline(qp_path, ms_path, ans_path, subject="Maths", imprin
1146
  imprinted_pdf_path = imprint_marks_using_mapping(ans_path, grading_json, imprinted_pdf_path, extracted_ids)
1147
  print("βœ… Imprinting finished. Imprinted PDF at:", imprinted_pdf_path)
1148
 
1149
- # Upload output files to Supabase
1150
  output_urls = {
1151
  "graded_pdf_url": None,
1152
  "imprinted_pdf_url": None
@@ -1155,9 +1171,9 @@ def align_and_grade_pipeline(qp_path, ms_path, ans_path, subject="Maths", imprin
1155
  if supabase_client:
1156
  print("\nπŸ“€ Uploading output files to Supabase...")
1157
  if grading_pdf_path:
1158
- output_urls["graded_pdf_url"] = upload_file_to_supabase(grading_pdf_path, "graded")
1159
  if imprinted_pdf_path:
1160
- output_urls["imprinted_pdf_url"] = upload_file_to_supabase(imprinted_pdf_path, "imprinted")
1161
 
1162
  print("🏁 Pipeline finished successfully.")
1163
  return qpms_text, as_text, grading_text, grading_pdf_path, imprinted_pdf_path, output_urls
@@ -1215,20 +1231,20 @@ with gr.Blocks(title="AI Grading (Pandoc + pdflatex)") as demo:
1215
  else:
1216
  return error_msg, "", "", None, None
1217
 
1218
- # Process and upload input files
1219
- qp_path, ms_path, ans_path, input_urls = process_and_upload_input_files(
1220
  qp_file_obj, ms_file_obj, ans_file_obj
1221
  )
1222
 
1223
- # Run the grading pipeline
1224
  qpms_text, as_text, grading_text, grading_pdf_path, imprinted_pdf_path, output_urls = align_and_grade_pipeline(
1225
- qp_path, ms_path, ans_path, subject=subject_choice, imprint=imprint_flag
1226
  )
1227
 
1228
  # Build URLs summary
1229
  urls_summary = ""
1230
  if supabase_client:
1231
- urls_summary = "πŸ“€ UPLOADED FILES:\n\n"
1232
  urls_summary += "INPUT FILES:\n"
1233
  if input_urls.get("qp_url"):
1234
  urls_summary += f"β€’ Question Paper: {input_urls['qp_url']}\n"
@@ -1243,6 +1259,8 @@ with gr.Blocks(title="AI Grading (Pandoc + pdflatex)") as demo:
1243
  if output_urls.get("imprinted_pdf_url"):
1244
  urls_summary += f"β€’ Imprinted PDF: {output_urls['imprinted_pdf_url']}\n"
1245
 
 
 
1246
  if not any(input_urls.values()) and not any(output_urls.values()):
1247
  urls_summary += "\n⚠️ No files were uploaded to Supabase"
1248
 
 
40
  # Prompts are now imported from prompts.py
41
 
42
  # ---------------- SUPABASE HELPERS ----------------
43
+ def upload_file_to_supabase(local_path, file_type="unknown", timestamp=None):
44
  """
45
  Upload a file to Supabase Storage.
46
 
47
  Args:
48
  local_path (str): Local file path
49
  file_type (str): Type of file (qp, ms, ans, graded, imprinted)
50
+ timestamp (str): Unix timestamp for folder organization (optional)
51
 
52
  Returns:
53
  str: Public URL of uploaded file or None if upload failed
 
57
  return None
58
 
59
  try:
60
+ if timestamp is None:
61
+ timestamp = str(int(time.time()))
62
+
63
  original_name = os.path.basename(local_path)
64
+ # Use original filename without prefix for cleaner storage
65
+ remote_path = f"{timestamp}/{original_name}"
66
 
67
  print(f"πŸ“€ Uploading {file_type} to Supabase: {remote_path}")
68
 
 
83
 
84
  def process_and_upload_input_files(qp_file_obj, ms_file_obj, ans_file_obj):
85
  """
86
+ Process uploaded files and upload them to Supabase using a shared timestamp.
87
 
88
  Args:
89
  qp_file_obj: Gradio file object for Question Paper
 
91
  ans_file_obj: Gradio file object for Answer Sheet
92
 
93
  Returns:
94
+ tuple: (qp_path, ms_path, ans_path, upload_urls_dict, timestamp)
95
  """
96
  print("\n" + "="*60)
97
  print("πŸ“ PROCESSING INPUT FILES")
98
  print("="*60)
99
 
100
+ # Generate single timestamp for this entire run
101
+ run_timestamp = str(int(time.time()))
102
+ print(f"πŸ• Run timestamp: {run_timestamp}")
103
+
104
  upload_urls = {
105
  "qp_url": None,
106
  "ms_url": None,
 
112
  ms_path = ms_file_obj.name if ms_file_obj else None
113
  ans_path = ans_file_obj.name if ans_file_obj else None
114
 
115
+ # Upload to Supabase if configured (all files use same timestamp)
116
  if supabase_client:
117
  if qp_path:
118
+ upload_urls["qp_url"] = upload_file_to_supabase(qp_path, "qp", run_timestamp)
119
  if ms_path:
120
+ upload_urls["ms_url"] = upload_file_to_supabase(ms_path, "ms", run_timestamp)
121
  if ans_path:
122
+ upload_urls["ans_url"] = upload_file_to_supabase(ans_path, "ans", run_timestamp)
123
 
124
  print("="*60 + "\n")
125
 
126
+ return qp_path, ms_path, ans_path, upload_urls, run_timestamp
127
 
128
 
129
 
 
1059
  return out_paths
1060
 
1061
  # ---------------- PIPELINE ----------------
1062
+ def align_and_grade_pipeline(qp_path, ms_path, ans_path, subject="Maths", imprint=False, run_timestamp=None):
1063
  """
1064
  Final pipeline with graph-aware grading logic using NEW SDK.
1065
+
1066
+ Args:
1067
+ qp_path: Path to Question Paper PDF
1068
+ ms_path: Path to Markscheme PDF
1069
+ ans_path: Path to Answer Sheet PDF
1070
+ subject: Subject name (Maths or Science)
1071
+ imprint: Whether to generate imprinted PDF
1072
+ run_timestamp: Unix timestamp for organizing files in Supabase
1073
  """
1074
  try:
1075
  print("πŸ” Starting pipeline...")
 
1162
  imprinted_pdf_path = imprint_marks_using_mapping(ans_path, grading_json, imprinted_pdf_path, extracted_ids)
1163
  print("βœ… Imprinting finished. Imprinted PDF at:", imprinted_pdf_path)
1164
 
1165
+ # Upload output files to Supabase (using same timestamp as input files)
1166
  output_urls = {
1167
  "graded_pdf_url": None,
1168
  "imprinted_pdf_url": None
 
1171
  if supabase_client:
1172
  print("\nπŸ“€ Uploading output files to Supabase...")
1173
  if grading_pdf_path:
1174
+ output_urls["graded_pdf_url"] = upload_file_to_supabase(grading_pdf_path, "graded", run_timestamp)
1175
  if imprinted_pdf_path:
1176
+ output_urls["imprinted_pdf_url"] = upload_file_to_supabase(imprinted_pdf_path, "imprinted", run_timestamp)
1177
 
1178
  print("🏁 Pipeline finished successfully.")
1179
  return qpms_text, as_text, grading_text, grading_pdf_path, imprinted_pdf_path, output_urls
 
1231
  else:
1232
  return error_msg, "", "", None, None
1233
 
1234
+ # Process and upload input files (generates shared timestamp)
1235
+ qp_path, ms_path, ans_path, input_urls, run_timestamp = process_and_upload_input_files(
1236
  qp_file_obj, ms_file_obj, ans_file_obj
1237
  )
1238
 
1239
+ # Run the grading pipeline (pass timestamp to keep all files together)
1240
  qpms_text, as_text, grading_text, grading_pdf_path, imprinted_pdf_path, output_urls = align_and_grade_pipeline(
1241
+ qp_path, ms_path, ans_path, subject=subject_choice, imprint=imprint_flag, run_timestamp=run_timestamp
1242
  )
1243
 
1244
  # Build URLs summary
1245
  urls_summary = ""
1246
  if supabase_client:
1247
+ urls_summary = f"πŸ“€ UPLOADED FILES (Timestamp: {run_timestamp}):\n\n"
1248
  urls_summary += "INPUT FILES:\n"
1249
  if input_urls.get("qp_url"):
1250
  urls_summary += f"β€’ Question Paper: {input_urls['qp_url']}\n"
 
1259
  if output_urls.get("imprinted_pdf_url"):
1260
  urls_summary += f"β€’ Imprinted PDF: {output_urls['imprinted_pdf_url']}\n"
1261
 
1262
+ urls_summary += f"\nπŸ“ All files stored in: examfiles/{run_timestamp}/\n"
1263
+
1264
  if not any(input_urls.values()) and not any(output_urls.values()):
1265
  urls_summary += "\n⚠️ No files were uploaded to Supabase"
1266