Skip to content

Commit

Permalink
Merge pull request #12 from AliAfshar7/modify-saving-mechanism
Browse files Browse the repository at this point in the history
chore: modify CV saving mechanism
  • Loading branch information
mohammadi-com authored Dec 16, 2024
2 parents ca0da91 + bd67e55 commit 62c9e99
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 21 deletions.
5 changes: 4 additions & 1 deletion config.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,7 @@
LOG_TO_FILE = True
LOG_TO_CONSOLE = True
LOG_FILE = "log/app.log"
LOG_FORMAT = "<green>{time:YYYY-MM-DD HH:mm:ss.SSS}</green> | <level>{level: <8}</level> | <cyan>{name}</cyan>:<cyan>{function}</cyan>:<cyan>{line}</cyan> - <level>{message}</level>"
LOG_FORMAT = "<green>{time:YYYY-MM-DD HH:mm:ss.SSS}</green> | <level>{level: <8}</level> | <cyan>{name}</cyan>:<cyan>{function}</cyan>:<cyan>{line}</cyan> - <level>{message}</level>"
APPLICANT_NAME = "John Doe"
TEX_FILE_NAME = "resume"
TAR_FOLDER_NAME = "resume"
3 changes: 1 addition & 2 deletions envs.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,5 @@
GMAIL_APP_PASSWORD = getenv("GMAIL_APP_PASSWORD") # Put your gmail app password here
ADD_GDRIVE_ZAP_URL = getenv("ADD_GDRIVE_ZAP_URL") # Put zappier webhook workflow here, This webhook uploads the file to GDrive
LaTeX_COMPILER_URL_TEXT = "https://texlive2020.latexonline.cc/compile?command=pdflatex&text="
# LaTeX_COMPILER_URL = "https://latexonline.cc/compile?command=xelatex&text="
LaTeX_COMPILER_URL_DATA = "https://latexonline.cc/data?target=resume/resume.tex&force=true&command=pdflatex"
LaTeX_COMPILER_URL_DATA = """https://latexonline.cc/data?target={tex_folder_path}&force=true&command=pdflatex"""

15 changes: 10 additions & 5 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from templates import john_doe_resume

from log import logger
from config import APPLICANT_NAME

app = FastAPI()

Expand Down Expand Up @@ -43,11 +44,15 @@ def generate_tailored_latex_resume_save(job_description: str, resume: str = john
Gets resume and job description in plain text and saves tailored resume
"""
tailored_plain_resume = generate_tailored_plain_resume(resume, job_description, model, template)
latex_compiler_reponse, _ = openai_wrapper.covert_plain_resume_to_latex(tailored_plain_resume, model, template)
company_name = openai_wrapper.ai_prompt(f"Give the name of the company that this job description is for. As the output just give the name, nothing else. Job description: {job_description}") # Since this is a simple task we use the cheapest ai
with open(f'./CVs/{company_name}_cv.pdf', 'wb') as f:
# Make a folder for each job description to save PDF, .tex, and .tar files of tailored resume.
os.makedirs(f'./CVs/{company_name}',exist_ok=True)
latex_compiler_reponse, _ = openai_wrapper.covert_plain_resume_to_latex(company_name, tailored_plain_resume, model, template)
# Path to save pdf file of tailored resume
pdf_path = f'./CVs/{company_name}/{APPLICANT_NAME}_cv.pdf'
with open(pdf_path, 'wb') as f:
f.write(latex_compiler_reponse.content)
logger.debug(f"Generated resume saved at here: ./CVs/{company_name}_cv.pdf")
return {"success": f"Generated resume saved at here: ./CVs/{company_name}_cv.pdf",
"path": os.path.abspath(f"./CVs/{company_name}_cv.pdf")
logger.debug(f"Generated resume saved at here: {pdf_path}")
return {"success": f"Generated resume saved at here: {pdf_path}",
"path": os.path.abspath(pdf_path)
}
8 changes: 4 additions & 4 deletions openai_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from templates import TemplateName, Template_Details
import os
from utils import generate_tex_and_tar
from config import TEX_FILE_NAME, TAR_FOLDER_NAME

client = OpenAI(api_key=OPEN_AI_KEY) # we recommend using python-dotenv to add OPENAI_API_KEY="My API Key" to your .env file so that your API Key is not stored in source control.

Expand Down Expand Up @@ -96,7 +97,7 @@ def create_tailored_plain_resume(resume: str, job_description: str, model=AIMode
logger.debug(f"The tailored CV plain text is: {tailored_resume}")
return tailored_resume

def covert_plain_resume_to_latex(plain_resume: str, model=AIModel.gpt_4o_mini, template=TemplateName.Blue_Modern_CV):
def covert_plain_resume_to_latex(company_name: str, plain_resume: str, model=AIModel.gpt_4o_mini, template=TemplateName.Blue_Modern_CV):

messages=[
{"role": "system", "content": "You are a helpful assistant."},
Expand All @@ -112,11 +113,10 @@ def covert_plain_resume_to_latex(plain_resume: str, model=AIModel.gpt_4o_mini, t
tailored_resume = json.loads(completion.choices[0].message.content)["tailored_resume"]
logger.debug(f"The tailored CV Latex code in iteration {i} is: {tailored_resume}")
trimed_tailored_resume = tailored_resume[tailored_resume.find(r"\documentclass"):tailored_resume.rfind(r"\end{document}")+len(r"\end{document}")] # removes possible extra things that AI adds
file_name, folder_name = "resume", "resume"
created_tar_file = generate_tex_and_tar(trimed_tailored_resume, f"{file_name}", f"{folder_name}")
created_tar_file = generate_tex_and_tar(company_name, trimed_tailored_resume, TEX_FILE_NAME, TAR_FOLDER_NAME)
with open(created_tar_file, 'rb') as tar_file:
files = {'file':(os.path.basename(created_tar_file), tar_file, "application/x-tar")}
latex_compiler_response = requests.post(url=LaTeX_COMPILER_URL_DATA, files= files)
latex_compiler_response = requests.post(url=LaTeX_COMPILER_URL_DATA.format(tex_folder_path=f"{TAR_FOLDER_NAME}/{TEX_FILE_NAME}.tex"), files= files)
logger.debug(f"Request url to the LaTeX compiler is: {latex_compiler_response.url}")
if not b"error: " in latex_compiler_response.content: # there is no error in the compiled code
return latex_compiler_response, trimed_tailored_resume
Expand Down
23 changes: 14 additions & 9 deletions utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import tarfile
from log import logger

def generate_tex_and_tar(latex_content: str, file_name: str= "resume", folder_name: str="resume"):
def generate_tex_and_tar(company_name: str, latex_content: str, file_name: str= "resume", folder_name: str="resume"):
"""
Creates a folder, generates a .tex file inside it, and compresses the folder into a .tar file.
Expand All @@ -12,11 +12,17 @@ def generate_tex_and_tar(latex_content: str, file_name: str= "resume", folder_na
folder_name (str): The name of the folder to create.
"""
try:
# Path of a folder for saving .tex files
resume_folder_path = f'./CVs/{company_name}/{folder_name}'

# Path of .tar file
tar_path = f'./CVs/{company_name}'

# Ensure the folder exists
os.makedirs(folder_name, exist_ok=True)
os.makedirs(resume_folder_path, exist_ok=True)

# Full path for the .tex file
tex_file_path = os.path.join(folder_name, file_name)
tex_file_path = os.path.join(resume_folder_path, file_name)

# Ensure the file name ends with .tex
if not tex_file_path.endswith(".tex"):
Expand All @@ -30,11 +36,10 @@ def generate_tex_and_tar(latex_content: str, file_name: str= "resume", folder_na

# Compress the folder into a .tar file
tar_file_name = f"{folder_name}.tar"
with tarfile.open(tar_file_name, "w") as tar:
tar.add(folder_name, arcname=os.path.basename(folder_name))

logger.debug(f"Folder '{folder_name}' compressed into '{tar_file_name}'.")

return (os.path.relpath(tar_file_name))
# Full path of .tar folder
tar_folder_path = os.path.join(tar_path, tar_file_name)
with tarfile.open(tar_folder_path, "w") as tar:
tar.add(resume_folder_path, arcname='resume')
return (os.path.relpath(tar_folder_path))
except Exception as e:
logger.debug(f"An error occurred: {e}")

0 comments on commit 62c9e99

Please sign in to comment.