LALAa11 commited on
Commit
1626c71
Β·
verified Β·
1 Parent(s): e7c0ef9

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +57 -29
app.py CHANGED
@@ -3,13 +3,14 @@ import gradio as gr
3
  import requests
4
  from huggingface_hub import InferenceClient
5
 
6
- # Load Gemini API key from environment variable
7
  GEMINI_API_KEY = os.getenv("GOOGLE_AI_API_KEY")
8
- HF_API_KEY = os.getenv("HUGGINGFACE_API_KEY") # optional if private model
9
 
10
- # Hugging Face Client (free model, no API key needed for public models)
11
  hf_client = InferenceClient(model="HuggingFaceH4/zephyr-7b-beta")
12
 
 
13
  def generate_with_huggingface(resume_text, job_desc):
14
  prompt = f"""
15
  You are an expert career assistant.
@@ -23,7 +24,6 @@ def generate_with_huggingface(resume_text, job_desc):
23
  1. Create a customized resume version highlighting relevant skills and achievements.
24
  2. Write a professional cover letter tailored for this role.
25
  """
26
-
27
  response = hf_client.text_generation(
28
  prompt,
29
  max_new_tokens=800,
@@ -31,10 +31,9 @@ def generate_with_huggingface(resume_text, job_desc):
31
  )
32
  return response
33
 
34
-
35
  def call_gemini_api(resume_text, job_desc):
36
  if not GEMINI_API_KEY:
37
- return None # force fallback
38
 
39
  prompt = f"""
40
  You are an expert career assistant.
@@ -48,35 +47,24 @@ def call_gemini_api(resume_text, job_desc):
48
  1. Create a customized resume version highlighting relevant skills and achievements.
49
  2. Write a professional cover letter tailored for this role.
50
  """
51
-
52
  url = "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent"
53
  headers = {
54
  "Content-Type": "application/json",
55
  "X-goog-api-key": GEMINI_API_KEY,
56
  }
57
- data = {
58
- "contents": [
59
- {"parts": [{"text": prompt}]}
60
- ]
61
- }
62
-
63
  try:
64
  response = requests.post(url, headers=headers, json=data, timeout=30)
65
  result = response.json()
66
-
67
  if "candidates" in result:
68
- output_text = result["candidates"][0]["content"]["parts"][0]["text"]
69
- return output_text
70
  else:
71
  return None
72
  except Exception:
73
  return None
74
 
75
-
76
  def generate_documents(resume_text, job_desc):
77
- # Try Gemini first
78
  gemini_output = call_gemini_api(resume_text, job_desc)
79
-
80
  if gemini_output:
81
  output_text = gemini_output
82
  source = "βœ… Google Gemini"
@@ -96,21 +84,61 @@ def generate_documents(resume_text, job_desc):
96
  return resume_out + f"\n\n(Source: {source})", cover_letter_out
97
 
98
 
99
- # Gradio UI
100
- with gr.Blocks(title="AI Resume & Cover Letter Generator") as demo:
101
- gr.Markdown("# πŸ“„ AI Resume & Cover Letter Generator")
102
- gr.Markdown("Upload your resume or paste LinkedIn profile + Job description, and get customized documents.\
103
- \n(Default: Gemini, fallback: Hugging Face LLM)")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
 
105
  with gr.Row():
106
- resume_input = gr.Textbox(label="Paste Resume / LinkedIn profile", lines=10, placeholder="Paste your resume text here...")
107
- job_input = gr.Textbox(label="Paste Job Description", lines=8, placeholder="Paste job description here...")
108
 
109
  generate_btn = gr.Button("✨ Generate Resume & Cover Letter")
110
 
111
- with gr.Row():
112
- resume_output = gr.Textbox(label="Customized Resume", lines=15)
113
- cover_output = gr.Textbox(label="Cover Letter", lines=15)
 
 
114
 
115
  generate_btn.click(generate_documents, inputs=[resume_input, job_input], outputs=[resume_output, cover_output])
116
 
 
3
  import requests
4
  from huggingface_hub import InferenceClient
5
 
6
+ # πŸ”‘ Load API keys from environment
7
  GEMINI_API_KEY = os.getenv("GOOGLE_AI_API_KEY")
8
+ HF_API_KEY = os.getenv("HUGGINGFACE_API_KEY") # optional for private HF models
9
 
10
+ # Hugging Face Client (public model as fallback)
11
  hf_client = InferenceClient(model="HuggingFaceH4/zephyr-7b-beta")
12
 
13
+ # ========== AI Functions ==========
14
  def generate_with_huggingface(resume_text, job_desc):
15
  prompt = f"""
16
  You are an expert career assistant.
 
24
  1. Create a customized resume version highlighting relevant skills and achievements.
25
  2. Write a professional cover letter tailored for this role.
26
  """
 
27
  response = hf_client.text_generation(
28
  prompt,
29
  max_new_tokens=800,
 
31
  )
32
  return response
33
 
 
34
  def call_gemini_api(resume_text, job_desc):
35
  if not GEMINI_API_KEY:
36
+ return None
37
 
38
  prompt = f"""
39
  You are an expert career assistant.
 
47
  1. Create a customized resume version highlighting relevant skills and achievements.
48
  2. Write a professional cover letter tailored for this role.
49
  """
 
50
  url = "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent"
51
  headers = {
52
  "Content-Type": "application/json",
53
  "X-goog-api-key": GEMINI_API_KEY,
54
  }
55
+ data = {"contents": [{"parts": [{"text": prompt}]}]}
 
 
 
 
 
56
  try:
57
  response = requests.post(url, headers=headers, json=data, timeout=30)
58
  result = response.json()
 
59
  if "candidates" in result:
60
+ return result["candidates"][0]["content"]["parts"][0]["text"]
 
61
  else:
62
  return None
63
  except Exception:
64
  return None
65
 
 
66
  def generate_documents(resume_text, job_desc):
 
67
  gemini_output = call_gemini_api(resume_text, job_desc)
 
68
  if gemini_output:
69
  output_text = gemini_output
70
  source = "βœ… Google Gemini"
 
84
  return resume_out + f"\n\n(Source: {source})", cover_letter_out
85
 
86
 
87
+ # ========== Custom CSS ==========
88
+ custom_css = """
89
+ body {
90
+ background: linear-gradient(-45deg, #ff9a9e, #fad0c4, #a1c4fd, #c2e9fb);
91
+ background-size: 400% 400%;
92
+ animation: gradientBG 12s ease infinite;
93
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
94
+ }
95
+ @keyframes gradientBG {
96
+ 0% {background-position: 0% 50%;}
97
+ 50% {background-position: 100% 50%;}
98
+ 100% {background-position: 0% 50%;}
99
+ }
100
+ .gradio-container {
101
+ animation: fadeIn 1.2s ease-in-out;
102
+ }
103
+ textarea, input {
104
+ border-radius: 14px !important;
105
+ box-shadow: 0px 4px 10px rgba(0,0,0,0.2) !important;
106
+ padding: 10px !important;
107
+ }
108
+ button {
109
+ background: linear-gradient(90deg, #667eea, #764ba2) !important;
110
+ color: white !important;
111
+ font-weight: bold !important;
112
+ border-radius: 25px !important;
113
+ transition: all 0.3s ease-in-out;
114
+ padding: 12px 20px !important;
115
+ }
116
+ button:hover {
117
+ transform: scale(1.07);
118
+ box-shadow: 0px 6px 15px rgba(0,0,0,0.3);
119
+ }
120
+ @keyframes fadeIn {
121
+ from {opacity: 0; transform: translateY(25px);}
122
+ to {opacity: 1; transform: translateY(0);}
123
+ }
124
+ """
125
+
126
+ # ========== Gradio UI ==========
127
+ with gr.Blocks(css=custom_css, title="AI Resume & Cover Letter Generator") as demo:
128
+ gr.Markdown("<h1 style='text-align:center; color:white;'>πŸ“„ AI Resume & Cover Letter Generator</h1>")
129
+ gr.Markdown("<p style='text-align:center; color:white; font-size:18px;'>Paste your Resume + Job Description β†’ Get a Customized Resume & Cover Letter</p>")
130
 
131
  with gr.Row():
132
+ resume_input = gr.Textbox(label="πŸ“‘ Paste Resume / LinkedIn profile", lines=10, placeholder="Paste your resume text here...")
133
+ job_input = gr.Textbox(label="πŸ’Ό Paste Job Description", lines=8, placeholder="Paste job description here...")
134
 
135
  generate_btn = gr.Button("✨ Generate Resume & Cover Letter")
136
 
137
+ with gr.Tabs():
138
+ with gr.Tab("🎯 Customized Resume"):
139
+ resume_output = gr.Textbox(label="Customized Resume", lines=20)
140
+ with gr.Tab("✍️ Cover Letter"):
141
+ cover_output = gr.Textbox(label="Cover Letter", lines=20)
142
 
143
  generate_btn.click(generate_documents, inputs=[resume_input, job_input], outputs=[resume_output, cover_output])
144