mcqvid / app.py
roshcheeku's picture
Update app.py
819e5a3 verified
from flask import Flask, request, jsonify
import os
import uuid
import pdfplumber
from docx import Document
import openpyxl
from werkzeug.utils import secure_filename
from threading import Thread
from model_utils import extract_mcqs_with_model
app = Flask(__name__)
# Use /tmp/uploads to avoid permission errors
app.config['UPLOAD_FOLDER'] = '/tmp/uploads'
os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True)
quiz_data_store = {}
processing_results = {}
# -------------------------------
# Text Extraction Functions
# -------------------------------
def extract_text_from_pdf(filepath):
with pdfplumber.open(filepath) as pdf:
return "\n".join([p.extract_text() for p in pdf.pages if p.extract_text()])
def extract_text_from_docx(filepath):
doc = Document(filepath)
return "\n".join([para.text for para in doc.paragraphs])
def extract_text_from_excel(filepath):
wb = openpyxl.load_workbook(filepath)
sheet = wb.active
text = ""
for row in sheet.iter_rows(min_row=2, values_only=True):
if any(row):
text += " ".join([str(cell) for cell in row if cell is not None]) + "\n"
return text
# -------------------------------
# Background Thread Function
# -------------------------------
def background_process(file_path, quiz_id, ext):
try:
if ext == 'pdf':
text = extract_text_from_pdf(file_path)
elif ext == 'docx':
text = extract_text_from_docx(file_path)
elif ext in ['xls', 'xlsx']:
text = extract_text_from_excel(file_path)
else:
processing_results[quiz_id] = {'error': 'Unsupported file type'}
return
mcqs = extract_mcqs_with_model(text)
processing_results[quiz_id] = {'mcqs': mcqs}
quiz_data_store[quiz_id] = mcqs
except Exception as e:
processing_results[quiz_id] = {'error': str(e)}
# -------------------------------
# Non-blocking Upload Route
# -------------------------------
@app.route('/upload', methods=['POST'])
def upload_file():
if 'file' not in request.files:
return jsonify({'error': 'No file provided'}), 400
file = request.files['file']
filename = secure_filename(file.filename)
ext = filename.split('.')[-1].lower()
uid = str(uuid.uuid4())
save_path = os.path.join(app.config['UPLOAD_FOLDER'], uid + '_' + filename)
file.save(save_path)
quiz_id = str(uuid.uuid4())
thread = Thread(target=background_process, args=(save_path, quiz_id, ext))
thread.start()
return jsonify({'quiz_id': quiz_id, 'status': 'processing'})
# -------------------------------
# Status Check Route
# -------------------------------
@app.route('/status/<quiz_id>', methods=['GET'])
def check_status(quiz_id):
if quiz_id not in processing_results:
return jsonify({'status': 'processing'}), 202
result = processing_results[quiz_id]
if 'error' in result:
return jsonify({'status': 'failed', 'error': result['error']}), 500
return jsonify({'status': 'completed', 'mcqs': result['mcqs']}), 200
# -------------------------------
# Quiz Submission
# -------------------------------
@app.route('/submit', methods=['POST'])
def submit_quiz():
data = request.json
quiz_id = data.get('quiz_id')
user_answers = data.get('answers')
if quiz_id not in quiz_data_store:
return jsonify({'error': 'Invalid quiz ID'}), 404
mcqs = quiz_data_store[quiz_id]
correct = 0
for i, ans in enumerate(user_answers):
if i < len(mcqs) and ans.upper() == mcqs[i]['answer'].upper():
correct += 1
total = len(mcqs)
accuracy = round((correct / total) * 100, 2) if total else 0
return jsonify({'score': correct, 'total': total, 'accuracy': accuracy})
# -------------------------------
# Root Route
# -------------------------------
@app.route('/')
def home():
return "MCQ Extraction Flask API is running!"
# -------------------------------
# Start the App
# -------------------------------
if __name__ == '__main__':
app.run(host='0.0.0.0', port=7860)