Spaces:
Runtime error
Runtime error
from flask import Flask, request, jsonify, render_template, make_response, send_from_directory | |
from litellm import completion | |
import os | |
import json | |
from datetime import datetime | |
import base64 | |
from llm_utils import generate_completion | |
import re | |
app = Flask(__name__) | |
# Use an environment variable for the upload folder, with a default to /tmp/uploads | |
UPLOAD_FOLDER = os.environ.get('UPLOAD_FOLDER', '/tmp/uploads') | |
# Ensure the upload folder exists | |
os.makedirs(UPLOAD_FOLDER, exist_ok=True) | |
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER | |
def favicon(): | |
return send_from_directory(os.path.join(app.root_path, 'static'), | |
'favicon.ico', mimetype='image/vnd.microsoft.icon') | |
def index(): | |
recent_files = get_recent_files() | |
response = make_response(render_template('index.html', recent_files=recent_files)) | |
return response | |
def get_recent_files(): | |
if not os.path.exists(app.config['UPLOAD_FOLDER']): | |
os.makedirs(app.config['UPLOAD_FOLDER']) | |
files = os.listdir(app.config['UPLOAD_FOLDER']) | |
valid_files = [f for f in files if f.lower().endswith(('.pdf', '.txt'))] | |
valid_files.sort(key=lambda x: os.path.getmtime(os.path.join(app.config['UPLOAD_FOLDER'], x)), reverse=True) | |
return [{'filename': file, 'date': datetime.fromtimestamp(os.path.getmtime(os.path.join(app.config['UPLOAD_FOLDER'], file))).isoformat()} for file in valid_files[:5]] | |
def get_recent_files_route(): | |
return jsonify(get_recent_files()) | |
def upload_file(): | |
if 'file' not in request.files: | |
return jsonify({'error': 'No file part'}), 400 | |
file = request.files['file'] | |
if file.filename == '': | |
return jsonify({'error': 'No selected file'}), 400 | |
if file and (file.filename.lower().endswith(('.pdf', '.txt', '.epub'))): | |
filename = os.path.join(app.config['UPLOAD_FOLDER'], file.filename) | |
file.save(filename) | |
return jsonify({'message': 'File uploaded successfully', 'filename': file.filename}), 200 | |
return jsonify({'error': 'Invalid file type. Please upload a PDF, TXT, or EPUB file.'}), 400 | |
def get_epub_content(filename): | |
file_path = os.path.join(app.config['UPLOAD_FOLDER'], filename) | |
if os.path.exists(file_path) and filename.endswith('.epub'): | |
with open(file_path, 'rb') as file: | |
epub_content = base64.b64encode(file.read()).decode('utf-8') | |
return jsonify({'epub_content': epub_content}) | |
return jsonify({'error': 'File not found or not an EPUB'}), 404 | |
def open_pdf(filename): | |
return send_from_directory(app.config['UPLOAD_FOLDER'], filename) | |
def generate_flashcard(): | |
data = request.json | |
prompt = data['prompt'] | |
mode = data.get('mode', 'flashcard') | |
model = data.get('model') | |
try: | |
# Use llm_utils to generate completion with the selected model | |
content = generate_completion(prompt, model=model) | |
print(prompt) | |
print(content) | |
if mode == 'language': | |
try: | |
# Extract the JSON substring from the content in case there is extra text. | |
json_match = re.search(r'\{[\s\S]*\}', content) | |
if json_match: | |
json_text = json_match.group(0) | |
flashcard = json.loads(json_text) | |
return jsonify({'flashcard': flashcard}) | |
else: | |
raise ValueError("No JSON object found in response") | |
except Exception as parse_err: | |
print("JSON parsing error in language mode: ", parse_err) | |
return jsonify({'error': 'JSON parsing error in language mode: ' + str(parse_err)}) | |
elif mode == 'flashcard': | |
try: | |
# Extract the JSON array substring from the content in case there is extra text. | |
json_match = re.search(r'\[[\s\S]*\]', content) | |
if json_match: | |
json_text = json_match.group(0) | |
flashcards = json.loads(json_text) | |
return jsonify({'flashcards': flashcards}) | |
else: | |
raise ValueError("No JSON array found in response") | |
except Exception as parse_err: | |
return jsonify({'error': 'JSON parsing error in flashcard mode: ' + str(parse_err)}) | |
elif mode == 'explain': | |
try: | |
# Try loading JSON with an "explanation" key; fallback to plain text if not provided | |
parsed = json.loads(content) | |
explanation = parsed.get('explanation', content) | |
return jsonify({'explanation': explanation}) | |
except Exception as parse_err: | |
return jsonify({'explanation': content}) | |
else: | |
return jsonify({'error': 'Invalid mode'}), 400 | |
except Exception as e: | |
return jsonify({'error': str(e)}), 500 | |
if __name__ == '__main__': | |
# Use environment variables to determine the run mode | |
debug_mode = os.environ.get('FLASK_DEBUG', 'False').lower() == 'true' | |
app.run(debug=debug_mode, host='0.0.0.0', port=7860) | |