Spaces:
Sleeping
Sleeping
from flask import Flask, render_template, request, jsonify | |
import os | |
from werkzeug.utils import secure_filename | |
import pdfkit | |
import requests | |
import json | |
from dotenv import load_dotenv | |
load_dotenv() | |
app = Flask(__name__) | |
UPLOAD_FOLDER = 'uploads' | |
ALLOWED_EXTENSIONS = {'pdf', 'doc', 'docx'} | |
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER | |
# Linux-compatible wkhtmltopdf path for Hugging Face | |
wkhtmltopdf_path = '/usr/bin/wkhtmltopdf' # Use system path (you'll install this in Dockerfile) | |
config = pdfkit.configuration(wkhtmltopdf=wkhtmltopdf_path) | |
def allowed_file(filename): | |
return '.' in filename and \ | |
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS | |
def index(): | |
return render_template('index.html') | |
def analyze_resume(): | |
data = request.json | |
resume_text = data.get('resume_text', '') | |
api_key = os.getenv('OPENROUTER_API_KEY') | |
if not api_key: | |
return jsonify({"success": False, "error": "API key not configured"}) | |
headers = { | |
"Authorization": f"Bearer {api_key}", | |
"HTTP-Referer": "http://localhost:5000", | |
"X-Title": "AI Resume Builder" | |
} | |
payload = { | |
"model": "openai/gpt-3.5-turbo", | |
"messages": [ | |
{"role": "system", "content": "You are a professional resume analyzer. Provide specific, actionable suggestions to improve this resume for ATS compatibility and hiring potential."}, | |
{"role": "user", "content": f"Please analyze this resume and provide improvement suggestions:\n\n{resume_text}"} | |
], | |
"temperature": 0.7 | |
} | |
try: | |
response = requests.post( | |
"https://openrouter.ai/api/v1/chat/completions", | |
headers=headers, | |
json=payload, | |
timeout=30 | |
) | |
response.raise_for_status() | |
suggestions = response.json()["choices"][0]["message"]["content"] | |
return jsonify({"success": True, "suggestions": suggestions}) | |
except requests.exceptions.RequestException as e: | |
return jsonify({"success": False, "error": f"API request failed: {str(e)}"}) | |
except Exception as e: | |
return jsonify({"success": False, "error": f"Unexpected error: {str(e)}"}) | |
def improve_section(): | |
data = request.json | |
section_text = data.get('section_text', '') | |
section_type = data.get('section_type', 'general') | |
api_key = os.getenv('OPENROUTER_API_KEY') | |
if not api_key: | |
return jsonify({"success": False, "error": "API key not configured"}) | |
headers = { | |
"Authorization": f"Bearer {api_key}", | |
"HTTP-Referer": "http://localhost:5000", | |
"X-Title": "AI Resume Builder" | |
} | |
payload = { | |
"model": "qwen/qwq-32b:free", | |
"messages": [ | |
{"role": "system", "content": f"You are a professional resume writer. Improve this {section_type} section to be more impactful and ATS-friendly."}, | |
{"role": "user", "content": section_text} | |
], | |
"temperature": 0.5 | |
} | |
try: | |
response = requests.post( | |
"https://openrouter.ai/api/v1/chat/completions", | |
headers=headers, | |
json=payload, | |
timeout=30 | |
) | |
response.raise_for_status() | |
improved_text = response.json()["choices"][0]["message"]["content"] | |
return jsonify({"success": True, "improved_text": improved_text}) | |
except requests.exceptions.RequestException as e: | |
return jsonify({"success": False, "error": f"API request failed: {str(e)}"}) | |
except Exception as e: | |
return jsonify({"success": False, "error": f"Unexpected error: {str(e)}"}) | |
def generate_pdf(): | |
data = request.json | |
html_content = data.get('html_content', '') | |
try: | |
pdf = pdfkit.from_string(html_content, False, configuration=config) | |
return jsonify({ | |
"success": True, | |
"pdf": pdf.decode('latin-1') | |
}) | |
except Exception as e: | |
return jsonify({"success": False, "error": f"PDF generation failed: {str(e)}. Please ensure wkhtmltopdf is installed at {wkhtmltopdf_path}"}) | |
# Required for Hugging Face | |
if __name__ == "__main__": | |
os.makedirs(UPLOAD_FOLDER, exist_ok=True) | |
app.run(debug=True, host="0.0.0.0", port=7860) | |
else: | |
server = app | |