Spaces:
Build error
Build error
Update app.py
Browse files
app.py
CHANGED
@@ -1,91 +1,59 @@
|
|
1 |
-
import os
|
2 |
import gradio as gr
|
3 |
import cohere
|
|
|
4 |
from docx import Document
|
5 |
from docx.shared import Pt
|
6 |
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
|
7 |
import pypandoc
|
|
|
8 |
|
9 |
-
#
|
10 |
-
cohere_api_key = os.getenv('COHERE_API_KEY')
|
11 |
if not cohere_api_key:
|
12 |
-
raise ValueError("
|
13 |
|
|
|
14 |
co = cohere.Client(cohere_api_key)
|
15 |
|
16 |
def generate_body(job_description, language):
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
:param job_description: The description of the job you are applying for.
|
21 |
-
:param language: The language in which the letter should be written (English or German).
|
22 |
-
:return: The generated body text for the job application letter.
|
23 |
-
"""
|
24 |
-
# Set the language model based on user selection
|
25 |
-
model = 'command-xlarge-nightly' # Default to command-xlarge-nightly model for both English and German
|
26 |
-
|
27 |
-
# Modify the prompt to exclude greetings
|
28 |
prompt = f"Write a professional job application letter in {language} without a greeting. Only generate the body text based on this job description:\n{job_description}"
|
29 |
|
30 |
-
# Use Cohere's API to generate the body of the application letter
|
31 |
response = co.generate(
|
32 |
model=model,
|
33 |
prompt=prompt,
|
34 |
-
max_tokens=250,
|
35 |
temperature=0.7,
|
36 |
)
|
37 |
return response.generations[0].text.strip()
|
38 |
|
39 |
-
def create_application_letter(name,
|
40 |
-
"""
|
41 |
-
Create a job application letter with the provided details and format it for download.
|
42 |
-
|
43 |
-
:param name: Applicant's full name.
|
44 |
-
:param address: Applicant's address.
|
45 |
-
:param email: Applicant's email address.
|
46 |
-
:param phone: Applicant's phone number.
|
47 |
-
:param job_position: Position being applied for.
|
48 |
-
:param employer_name: Employer's name.
|
49 |
-
:param greeting_option: Indicates whether the recipient's name is known.
|
50 |
-
:param employer_contact_name: Employer contact's name (if known).
|
51 |
-
:param employer_address: Employer's address.
|
52 |
-
:param job_id: Job ID for the application.
|
53 |
-
:param start_date: Desired start date for the job.
|
54 |
-
:param job_description: The job description.
|
55 |
-
:param language: Language of the letter (English or German).
|
56 |
-
:param output_format: Desired output format (DOCX or PDF).
|
57 |
-
:return: The filename of the generated application letter.
|
58 |
-
"""
|
59 |
-
# Generate the body using the job description and language
|
60 |
body = generate_body(job_description, language)
|
61 |
|
62 |
-
# Create a new Document
|
63 |
doc = Document()
|
64 |
|
65 |
-
# Add header with sender's name, address, email, and phone in a single line
|
66 |
header = doc.sections[0].header
|
67 |
header_paragraph = header.paragraphs[0]
|
68 |
-
header_paragraph.text = f"{name} | {
|
69 |
header_paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.LEFT
|
70 |
|
71 |
-
# Adjust the font size for the header
|
72 |
for run in header_paragraph.runs:
|
73 |
run.font.size = Pt(10)
|
74 |
|
75 |
-
|
76 |
-
doc.add_paragraph("\n")
|
77 |
|
78 |
-
|
79 |
-
doc.add_paragraph(
|
80 |
-
|
|
|
|
|
81 |
|
82 |
-
# Add the subject
|
83 |
doc.add_paragraph(f"Bewerbung als {job_position}\nKennnummer {job_id}\n", style='Heading 2')
|
84 |
|
85 |
-
# Add the greeting based on the selected option
|
86 |
if language == "German":
|
87 |
if greeting_option == "Known" and employer_contact_name:
|
88 |
-
doc.add_paragraph(f"Sehr geehrter Herr {employer_contact_name
|
89 |
else:
|
90 |
doc.add_paragraph("Sehr geehrte Damen und Herren,\n")
|
91 |
else:
|
@@ -94,10 +62,8 @@ def create_application_letter(name, address, email, phone, job_position, employe
|
|
94 |
else:
|
95 |
doc.add_paragraph("Dear Sir/Madam,\n")
|
96 |
|
97 |
-
# Add the generated body of the letter
|
98 |
doc.add_paragraph(body)
|
99 |
|
100 |
-
# Add closing
|
101 |
closing_text = (
|
102 |
f"\nIch unterstütze Ihr Team gerne ab dem {start_date} und freue mich über die Einladung zu einem persönlichen Vorstellungsgespräch."
|
103 |
if language == "German" else
|
@@ -107,63 +73,59 @@ def create_application_letter(name, address, email, phone, job_position, employe
|
|
107 |
doc.add_paragraph("\nMit freundlichen Grüßen,\n\n" if language == "German" else "\nSincerely,\n\n")
|
108 |
doc.add_paragraph(f"{name}\n")
|
109 |
|
110 |
-
# Adjust font size for body to ensure it fits on one page
|
111 |
for paragraph in doc.paragraphs:
|
112 |
for run in paragraph.runs:
|
113 |
-
run.font.size = Pt(11)
|
114 |
|
115 |
-
# Save the document
|
116 |
output_filename_docx = f'{name}_application_letter.docx'
|
117 |
doc.save(output_filename_docx)
|
118 |
|
119 |
-
# Convert to PDF if requested
|
120 |
if output_format == "PDF":
|
121 |
output_filename_pdf = f'{name}_application_letter.pdf'
|
122 |
pypandoc.convert_file(output_filename_docx, 'pdf', outputfile=output_filename_pdf)
|
123 |
-
os.remove(output_filename_docx)
|
124 |
return output_filename_pdf
|
125 |
else:
|
126 |
return output_filename_docx
|
127 |
|
128 |
-
def generate_and_download(name,
|
129 |
-
|
130 |
-
Generate the application letter and return the file for download.
|
131 |
-
|
132 |
-
:return: Filename of the generated application letter for download.
|
133 |
-
"""
|
134 |
-
output_filename = create_application_letter(name, address, email, phone, job_position, employer_name, greeting_option, employer_contact_name, employer_address, job_id, start_date, job_description, language, output_format)
|
135 |
return output_filename
|
136 |
|
137 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
138 |
with gr.Blocks() as demo:
|
139 |
-
gr.Markdown(
|
140 |
-
## Professional Job Application Letter Generator
|
141 |
-
|
142 |
-
This tool helps you generate a professional job application letter in either English or German.
|
143 |
-
The letter is automatically formatted and can be downloaded in DOCX or PDF format.
|
144 |
-
|
145 |
-
### Powered by Cohere's Language Model
|
146 |
-
|
147 |
-
The body of the application letter is generated using **Cohere**, a state-of-the-art language model,
|
148 |
-
ensuring that your application is not only well-written but also tailored to the job description you provide.
|
149 |
-
""")
|
150 |
|
151 |
-
name = gr.Textbox(label="Name", placeholder="Enter your full name", value="
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
163 |
language = gr.Dropdown(choices=["English", "German"], label="Select Language", value="German")
|
164 |
output_format = gr.Dropdown(choices=["DOCX", "PDF"], label="Select Output Format", value="PDF")
|
165 |
|
166 |
-
# Show or hide the employer contact name input based on the greeting option
|
167 |
def update_visibility(greeting_option):
|
168 |
return gr.update(visible=(greeting_option == "Known"))
|
169 |
|
@@ -173,8 +135,7 @@ with gr.Blocks() as demo:
|
|
173 |
output = gr.File(label="Download your application letter")
|
174 |
|
175 |
generate_button.click(generate_and_download,
|
176 |
-
inputs=[name,
|
177 |
outputs=output)
|
178 |
|
179 |
-
# Launch the Gradio interface
|
180 |
demo.launch(debug=True)
|
|
|
|
|
1 |
import gradio as gr
|
2 |
import cohere
|
3 |
+
import os
|
4 |
from docx import Document
|
5 |
from docx.shared import Pt
|
6 |
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
|
7 |
import pypandoc
|
8 |
+
from datetime import datetime
|
9 |
|
10 |
+
# Get the API key from environment variables
|
11 |
+
cohere_api_key = os.getenv('COHERE_API_KEY')
|
12 |
if not cohere_api_key:
|
13 |
+
raise ValueError("Please set the COHERE_API_KEY environment variable")
|
14 |
|
15 |
+
# Initialize Cohere client with your API key
|
16 |
co = cohere.Client(cohere_api_key)
|
17 |
|
18 |
def generate_body(job_description, language):
|
19 |
+
model = 'command-xlarge-nightly'
|
20 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
prompt = f"Write a professional job application letter in {language} without a greeting. Only generate the body text based on this job description:\n{job_description}"
|
22 |
|
|
|
23 |
response = co.generate(
|
24 |
model=model,
|
25 |
prompt=prompt,
|
26 |
+
max_tokens=250,
|
27 |
temperature=0.7,
|
28 |
)
|
29 |
return response.generations[0].text.strip()
|
30 |
|
31 |
+
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):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
32 |
body = generate_body(job_description, language)
|
33 |
|
|
|
34 |
doc = Document()
|
35 |
|
|
|
36 |
header = doc.sections[0].header
|
37 |
header_paragraph = header.paragraphs[0]
|
38 |
+
header_paragraph.text = f"{name} | {sender_street}, {sender_zip} {sender_city} | {email} | {phone}"
|
39 |
header_paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.LEFT
|
40 |
|
|
|
41 |
for run in header_paragraph.runs:
|
42 |
run.font.size = Pt(10)
|
43 |
|
44 |
+
doc.add_paragraph(f"{employer_name}\n{employer_contact_name if greeting_option == 'Known' else ''}\n{employer_street}\n{employer_zip} {employer_city}")
|
|
|
45 |
|
46 |
+
current_date = datetime.now().strftime('%d.%m.%Y')
|
47 |
+
paragraph = doc.add_paragraph()
|
48 |
+
paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.RIGHT
|
49 |
+
run = paragraph.add_run(f"{employer_city}, {current_date}")
|
50 |
+
run.font.size = Pt(11)
|
51 |
|
|
|
52 |
doc.add_paragraph(f"Bewerbung als {job_position}\nKennnummer {job_id}\n", style='Heading 2')
|
53 |
|
|
|
54 |
if language == "German":
|
55 |
if greeting_option == "Known" and employer_contact_name:
|
56 |
+
doc.add_paragraph(f"Sehr geehrter Herr {employer_contact_name},\n")
|
57 |
else:
|
58 |
doc.add_paragraph("Sehr geehrte Damen und Herren,\n")
|
59 |
else:
|
|
|
62 |
else:
|
63 |
doc.add_paragraph("Dear Sir/Madam,\n")
|
64 |
|
|
|
65 |
doc.add_paragraph(body)
|
66 |
|
|
|
67 |
closing_text = (
|
68 |
f"\nIch unterstütze Ihr Team gerne ab dem {start_date} und freue mich über die Einladung zu einem persönlichen Vorstellungsgespräch."
|
69 |
if language == "German" else
|
|
|
73 |
doc.add_paragraph("\nMit freundlichen Grüßen,\n\n" if language == "German" else "\nSincerely,\n\n")
|
74 |
doc.add_paragraph(f"{name}\n")
|
75 |
|
|
|
76 |
for paragraph in doc.paragraphs:
|
77 |
for run in paragraph.runs:
|
78 |
+
run.font.size = Pt(11)
|
79 |
|
|
|
80 |
output_filename_docx = f'{name}_application_letter.docx'
|
81 |
doc.save(output_filename_docx)
|
82 |
|
|
|
83 |
if output_format == "PDF":
|
84 |
output_filename_pdf = f'{name}_application_letter.pdf'
|
85 |
pypandoc.convert_file(output_filename_docx, 'pdf', outputfile=output_filename_pdf)
|
86 |
+
os.remove(output_filename_docx)
|
87 |
return output_filename_pdf
|
88 |
else:
|
89 |
return output_filename_docx
|
90 |
|
91 |
+
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):
|
92 |
+
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)
|
|
|
|
|
|
|
|
|
|
|
93 |
return output_filename
|
94 |
|
95 |
+
description = """
|
96 |
+
# Professional Job Application Letter Generator
|
97 |
+
|
98 |
+
Welcome to the ultimate tool for crafting professional job application letters with ease. This tool leverages the power of **Cohere**, a state-of-the-art language model, to automatically generate a tailored application letter body based on the job description you provide.
|
99 |
+
|
100 |
+
Simply fill in the required details, and within seconds, you'll have a beautifully formatted job application letter ready to download in either DOCX or PDF format.
|
101 |
+
|
102 |
+
Start your journey to your next career opportunity with a compelling application letter generated just for you!
|
103 |
+
"""
|
104 |
+
|
105 |
with gr.Blocks() as demo:
|
106 |
+
gr.Markdown(description)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
107 |
|
108 |
+
name = gr.Textbox(label="Name", placeholder="Enter your full name", value="Maximilian Müller")
|
109 |
+
sender_street = gr.Textbox(label="Sender Street", placeholder="Enter your street address", value="Beispielstraße 42")
|
110 |
+
sender_zip = gr.Textbox(label="Sender Postal Code", placeholder="Enter your postal code", value="10115")
|
111 |
+
sender_city = gr.Textbox(label="Sender City", placeholder="Enter your city", value="Berlin")
|
112 |
+
email = gr.Textbox(label="Email", placeholder="Enter your email", value="[email protected]")
|
113 |
+
phone = gr.Textbox(label="Phone", placeholder="Enter your phone number", value="+49 170 1234567")
|
114 |
+
|
115 |
+
job_position = gr.Textbox(label="Job Position", placeholder="Enter the job position", value="Softwareentwickler")
|
116 |
+
employer_name = gr.Textbox(label="Employer Name", placeholder="Enter the employer's name", value="Tech Innovations GmbH")
|
117 |
+
employer_street = gr.Textbox(label="Employer Street", placeholder="Enter the employer's street address", value="Innovationsstraße 1")
|
118 |
+
employer_zip = gr.Textbox(label="Employer Postal Code", placeholder="Enter the employer's postal code", value="10115")
|
119 |
+
employer_city = gr.Textbox(label="Employer City", placeholder="Enter the employer's city", value="Berlin")
|
120 |
+
greeting_option = gr.Dropdown(choices=["Known", "Unknown"], label="Is the recipient's name known?", value="Known")
|
121 |
+
employer_contact_name = gr.Textbox(label="Employer Contact Name", placeholder="Enter the contact person's name (if known)", value="Herr Dr. Felix Schmidt", visible=True)
|
122 |
+
|
123 |
+
job_id = gr.Textbox(label="Job ID", placeholder="Enter the job ID", value="DEV-2024-01")
|
124 |
+
start_date = gr.Textbox(label="Start Date", placeholder="Enter the start date (e.g., 15.05.2020)", value="01.09.2024")
|
125 |
+
job_description = gr.Textbox(label="Job Description", placeholder="Paste the job description here", lines=7, value="We are seeking a dedicated Software Developer to join our team in creating innovative applications. Experience in Python and Java, as well as knowledge of agile methodologies, is required.")
|
126 |
language = gr.Dropdown(choices=["English", "German"], label="Select Language", value="German")
|
127 |
output_format = gr.Dropdown(choices=["DOCX", "PDF"], label="Select Output Format", value="PDF")
|
128 |
|
|
|
129 |
def update_visibility(greeting_option):
|
130 |
return gr.update(visible=(greeting_option == "Known"))
|
131 |
|
|
|
135 |
output = gr.File(label="Download your application letter")
|
136 |
|
137 |
generate_button.click(generate_and_download,
|
138 |
+
inputs=[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],
|
139 |
outputs=output)
|
140 |
|
|
|
141 |
demo.launch(debug=True)
|