mobenta's picture
Create app.py
62ab0d5 verified
import gradio as gr
import cohere
import os
from docx import Document as DocxDocument
from docx.shared import Pt
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
import pypandoc
from datetime import datetime
import fitz # PyMuPDF
from docx import Document
import zipfile
# Get the API key from environment variables
cohere_api_key = os.getenv('COHERE_API_KEY')
if not cohere_api_key:
raise ValueError("Bitte setzen Sie die Umgebungsvariable COHERE_API_KEY.")
# Initialize Cohere client with your API key
co = cohere.Client(cohere_api_key)
def extract_text_from_file(file_path):
if file_path.endswith('.docx'):
doc = DocxDocument(file_path)
return '\n'.join([para.text for para in doc.paragraphs])
elif file_path.endswith('.pdf'):
text = ""
with fitz.open(file_path) as pdf_doc:
for page in pdf_doc:
text += page.get_text()
return text
else:
return ""
def extract_text_from_zip(zip_path):
extracted_text = ""
with zipfile.ZipFile(zip_path, 'r') as zip_ref:
zip_ref.extractall('/tmp/certificates')
for file_name in zip_ref.namelist():
file_path = os.path.join('/tmp/certificates', file_name)
extracted_text += extract_text_from_file(file_path) + "\n"
return extracted_text
def generate_body(job_description, language, cv_text=None, certificates_text=None):
model = 'command-xlarge-nightly'
cv_text = f"Hier ist der Lebenslauf des Kandidaten:\n{cv_text}\n" if cv_text else ""
certificates_text = f"Hier sind die Zertifikate des Kandidaten:\n{certificates_text}\n" if certificates_text else ""
prompt = f"{cv_text}{certificates_text}Schreiben Sie ein professionelles Bewerbungsschreiben auf {language} ohne Anrede. Erstellen Sie nur den Textkörper basierend auf dieser Stellenbeschreibung:\n{job_description}"
response = co.generate(
model=model,
prompt=prompt,
max_tokens=250,
temperature=0.7,
)
return response.generations[0].text.strip()
def evaluate_match(job_description, cv_text, language):
prompt = f"Bewerten Sie, wie gut der folgende Lebenslauf zur Stellenbeschreibung passt:\n\nStellenbeschreibung:\n{job_description}\n\nLebenslauf:\n{cv_text}\n\nGeben Sie eine Zusammenfassung der Stärken und Schwächen sowie eine Übereinstimmungsbewertung zwischen 0 und 100 ab, auf {language}."
response = co.generate(
model='command-xlarge-nightly',
prompt=prompt,
max_tokens=150,
temperature=0.7,
)
return response.generations[0].text.strip()
def create_application_letter(name, sender_street, sender_zip, sender_city, email, phone, job_position, employer_name, employer_street, employer_zip, employer_city, greeting_option, employer_contact_name, job_id, start_date, job_description, language, output_format, cv_file=None, certificates_file=None):
cv_text = extract_text_from_file(cv_file) if cv_file else None
certificates_text = extract_text_from_zip(certificates_file) if certificates_file else ""
body = generate_body(job_description, language, cv_text=cv_text, certificates_text=certificates_text)
doc = Document()
header = doc.sections[0].header
header_paragraph = header.paragraphs[0]
header_paragraph.text = f"{name} | {sender_street}, {sender_zip} {sender_city} | {email} | {phone}"
header_paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.LEFT
for run in header_paragraph.runs:
run.font.size = Pt(10)
doc.add_paragraph(f"{employer_name}\n{employer_contact_name if greeting_option == 'Known' else ''}\n{employer_street}\n{employer_zip} {employer_city}")
current_date = datetime.now().strftime('%d.%m.%Y')
paragraph = doc.add_paragraph()
paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.RIGHT
run = paragraph.add_run(f"{employer_city}, {current_date}")
run.font.size = Pt(11)
doc.add_paragraph(f"Bewerbung als {job_position}\nKennnummer {job_id}\n", style='Heading 2')
if language == "German":
if greeting_option == "Known" and employer_contact_name:
doc.add_paragraph(f"Sehr geehrter Herr {employer_contact_name},\n")
else:
doc.add_paragraph("Sehr geehrte Damen und Herren,\n")
else:
if greeting_option == "Known" and employer_contact_name:
doc.add_paragraph(f"Dear {employer_contact_name},\n")
else:
doc.add_paragraph("Dear Sir/Madam,\n")
doc.add_paragraph(body)
closing_text = (
f"\nIch unterstütze Ihr Team gerne ab dem {start_date} und freue mich über die Einladung zu einem persönlichen Vorstellungsgespräch."
if language == "German" else
f"\nI am eager to join your team starting on {start_date} and look forward to the opportunity to discuss my application further."
)
doc.add_paragraph(closing_text)
doc.add_paragraph("\nMit freundlichen Grüßen,\n\n" if language == "German" else "\nSincerely,\n\n")
doc.add_paragraph(f"{name}\n")
for paragraph in doc.paragraphs:
for run in paragraph.runs:
run.font.size = Pt(11)
output_filename_docx = f'{name}_Bewerbungsschreiben.docx'
doc.save(output_filename_docx)
if output_format == "PDF":
output_filename_pdf = f'{name}_Bewerbungsschreiben.pdf'
pypandoc.convert_file(output_filename_docx, 'pdf', outputfile=output_filename_pdf)
os.remove(output_filename_docx)
return output_filename_pdf
else:
return output_filename_docx
def generate_and_download(name, sender_street, sender_zip, sender_city, email, phone, job_position, employer_name, employer_street, employer_zip, employer_city, greeting_option, employer_contact_name, job_id, start_date, job_description, language, output_format, cv_file, certificates_file, perform_evaluation):
# Generate application letter
output_filename = create_application_letter(name, sender_street, sender_zip, sender_city, email, phone, job_position, employer_name, employer_street, employer_zip, employer_city, greeting_option, employer_contact_name, job_id, start_date, job_description, language, output_format, cv_file=cv_file, certificates_file=certificates_file)
# Perform evaluation if requested
evaluation_result = ""
if perform_evaluation and cv_file:
cv_text = extract_text_from_file(cv_file)
evaluation_result = evaluate_match(job_description, cv_text, language)
return output_filename, evaluation_result
description = """
# Professioneller Bewerbungsschreiben-Generator
Willkommen beim ultimativen Tool zum Erstellen professioneller Bewerbungsschreiben mit Leichtigkeit. Dieses Tool nutzt die Kraft von **Cohere**, einem hochmodernen Sprachmodell, um automatisch einen maßgeschneiderten Bewerbungstext basierend auf der von Ihnen bereitgestellten Stellenbeschreibung zu erstellen.
Sie können optional Ihren Lebenslauf im DOCX- oder PDF-Format hochladen und Ihre Zertifikate als ZIP-Datei, um ein persönlicheres Bewerbungsschreiben zu erstellen. Sie können auch wählen, ob Sie eine Bewertung darüber erhalten möchten, wie gut Ihr Lebenslauf zur Stellenbeschreibung passt. Füllen Sie einfach die erforderlichen Felder aus und in wenigen Sekunden erhalten Sie ein wunderschön formatiertes Bewerbungsschreiben, das Sie entweder im DOCX- oder PDF-Format herunterladen können.
Starten Sie Ihren Weg zu Ihrer nächsten Karrierechance mit einem überzeugenden Bewerbungsschreiben, das speziell für Sie erstellt wurde!
"""
with gr.Blocks() as demo:
gr.Markdown(description)
with gr.Row():
with gr.Column():
sender_name = gr.Textbox(label="Absendername", placeholder="Geben Sie Ihren vollständigen Namen ein", value="Maximilian Müller")
sender_street = gr.Textbox(label="Straße des Absenders", placeholder="Geben Sie Ihre Straßenadresse ein", value="Beispielstraße 42")
sender_zip = gr.Textbox(label="PLZ des Absenders", placeholder="Geben Sie Ihre Postleitzahl ein", value="10115")
sender_city = gr.Textbox(label="Stadt des Absenders", placeholder="Geben Sie Ihre Stadt ein", value="Berlin")
sender_email = gr.Textbox(label="E-Mail des Absenders", placeholder="Geben Sie Ihre E-Mail-Adresse ein", value="[email protected]")
sender_phone = gr.Textbox(label="Telefon des Absenders", placeholder="Geben Sie Ihre Telefonnummer ein", value="+49 170 1234567")
certificates_file = gr.File(label="Zertifikate hochladen (optional, als .zip)", type="filepath", file_types=[".zip"])
with gr.Column():
job_position = gr.Textbox(label="Stellenbezeichnung", placeholder="Geben Sie die Stellenbezeichnung ein", value="Softwareentwickler")
job_id = gr.Textbox(label="Job-ID", placeholder="Geben Sie die Job-ID ein", value="DEV-2024-01")
start_date = gr.Textbox(label="Startdatum", placeholder="Geben Sie das Startdatum ein (z.B. 15.05.2020)", value="01.09.2024")
job_description = gr.Textbox(label="Stellenbeschreibung", placeholder="Fügen Sie hier die Stellenbeschreibung ein", lines=11.5, value="Wir suchen einen engagierten Softwareentwickler, der unser Team bei der Erstellung innovativer Anwendungen unterstützt. Erfahrungen mit Python und Java sowie Kenntnisse agiler Methoden sind erforderlich.")
language = gr.Dropdown(choices=["Englisch", "Deutsch"], label="Sprache auswählen", value="Deutsch")
output_format = gr.Dropdown(choices=["DOCX", "PDF"], label="Ausgabeformat auswählen", value="DOCX")
perform_evaluation = gr.Checkbox(label="Lebenslauf im Vergleich zur Stellenbeschreibung bewerten (optional)", value=False)
with gr.Column():
employer_name = gr.Textbox(label="Arbeitgebername", placeholder="Geben Sie den Namen des Arbeitgebers ein", value="Tech Innovations GmbH")
employer_street = gr.Textbox(label="Straße des Arbeitgebers", placeholder="Geben Sie die Straßenadresse des Arbeitgebers ein", value="Innovationsstraße 1")
employer_zip = gr.Textbox(label="PLZ des Arbeitgebers", placeholder="Geben Sie die Postleitzahl des Arbeitgebers ein", value="10115")
employer_city = gr.Textbox(label="Stadt des Arbeitgebers", placeholder="Geben Sie die Stadt des Arbeitgebers ein", value="Berlin")
greeting_option = gr.Dropdown(choices=["Bekannt", "Unbekannt"], label="Ist der Name des Empfängers bekannt?", value="Bekannt")
employer_contact_name = gr.Textbox(label="Name des Ansprechpartners beim Arbeitgeber", placeholder="Geben Sie den Namen des Ansprechpartners ein (falls bekannt)", value="Herr Dr. Felix Schmidt", visible=True)
cv_file = gr.File(label="Lebenslauf hochladen (optional)", type="filepath", file_types=[".docx", ".pdf"])
generate_button = gr.Button("Bewerbungsschreiben erstellen")
output_letter = gr.File(label="Laden Sie Ihr Bewerbungsschreiben herunter")
evaluation_output = gr.Textbox(label="Bewertungsergebnis", placeholder="Die Bewertung wird hier angezeigt...", lines=7)
generate_button.click(generate_and_download,
inputs=[sender_name, sender_street, sender_zip, sender_city, sender_email, sender_phone, job_position, employer_name, employer_street, employer_zip, employer_city, greeting_option, employer_contact_name, job_id, start_date, job_description, language, output_format, cv_file, certificates_file, perform_evaluation],
outputs=[output_letter, evaluation_output])
demo.launch(debug=True)