Spaces:
Runtime error
Runtime error
| 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 | |
| # ------------------------------- | |
| 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 | |
| # ------------------------------- | |
| 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 | |
| # ------------------------------- | |
| 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 | |
| # ------------------------------- | |
| def home(): | |
| return "MCQ Extraction Flask API is running!" | |
| # ------------------------------- | |
| # Start the App | |
| # ------------------------------- | |
| if __name__ == '__main__': | |
| app.run(host='0.0.0.0', port=7860) | |