Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -218,36 +218,42 @@ def find_jobs(file, added_kw, use_ai):
|
|
| 218 |
explanation = refine_with_ai(ranked, resume) if use_ai else ""
|
| 219 |
return table, explanation
|
| 220 |
|
| 221 |
-
# 8️⃣ Jobs in
|
| 222 |
-
def
|
| 223 |
total = len(table)
|
| 224 |
pages = max(1, math.ceil(total / per_page))
|
| 225 |
page = max(1, min(page, pages))
|
| 226 |
start, end = (page-1)*per_page, page*per_page
|
| 227 |
slice_ = table[start:end]
|
| 228 |
-
|
| 229 |
-
|
| 230 |
-
|
| 231 |
-
md += "| ---- | ------- | ---- | -------- | ------ | ----- | ------- | ----- |\n"
|
| 232 |
for row in slice_:
|
| 233 |
-
|
| 234 |
-
|
| 235 |
-
|
| 236 |
-
|
| 237 |
-
|
| 238 |
-
|
| 239 |
-
|
| 240 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 241 |
|
| 242 |
def load_jobs_and_pages(resume, added_kw, use_ai):
|
| 243 |
full_table, explanation = find_jobs(resume, added_kw, use_ai)
|
| 244 |
total_pages = max(1, math.ceil(len(full_table) / PER_PAGE))
|
| 245 |
slider_update = gr.update(value=1, maximum=total_pages)
|
| 246 |
-
|
| 247 |
expl_header = "### AI Explanation" if explanation else ""
|
| 248 |
print("Header", expl_header)
|
| 249 |
|
| 250 |
-
return full_table, explanation, expl_header, slider_update,
|
| 251 |
|
| 252 |
# 9️⃣ Gradio UI
|
| 253 |
with gr.Blocks(theme=gr.themes.Base()) as demo:
|
|
@@ -267,23 +273,40 @@ with gr.Blocks(theme=gr.themes.Base()) as demo:
|
|
| 267 |
|
| 268 |
jobs_state = gr.State([]) # holds full table
|
| 269 |
page_sel = gr.Slider(1, 1, step=1, value=1, label="Page")
|
| 270 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 271 |
expl_md_h = gr.Markdown()
|
| 272 |
expl_md = gr.Markdown() # shows AI explanation
|
| 273 |
|
| 274 |
# 1) On Find Jobs:
|
| 275 |
-
# - load the jobs, explanation, slider max, and first-page
|
| 276 |
find_btn.click(
|
| 277 |
fn=load_jobs_and_pages,
|
| 278 |
inputs=[resume, added, use_ai],
|
| 279 |
-
outputs=[jobs_state, expl_md, expl_md_h, page_sel,
|
| 280 |
)
|
| 281 |
|
| 282 |
-
# 2) On page change, re-render only the table
|
|
|
|
|
|
|
|
|
|
|
|
|
| 283 |
page_sel.change(
|
| 284 |
-
fn=
|
| 285 |
inputs=[jobs_state, page_sel],
|
| 286 |
-
outputs=[
|
| 287 |
)
|
| 288 |
|
| 289 |
if __name__ == "__main__":
|
|
|
|
| 218 |
explanation = refine_with_ai(ranked, resume) if use_ai else ""
|
| 219 |
return table, explanation
|
| 220 |
|
| 221 |
+
# 8️⃣ Jobs in DataFrame format
|
| 222 |
+
def jobs_to_dataframe(table, page, per_page=PER_PAGE):
|
| 223 |
total = len(table)
|
| 224 |
pages = max(1, math.ceil(total / per_page))
|
| 225 |
page = max(1, min(page, pages))
|
| 226 |
start, end = (page-1)*per_page, page*per_page
|
| 227 |
slice_ = table[start:end]
|
| 228 |
+
|
| 229 |
+
# Convert to list of lists for DataFrame
|
| 230 |
+
df_data = []
|
|
|
|
| 231 |
for row in slice_:
|
| 232 |
+
# Create clickable link for apply URL
|
| 233 |
+
apply_link = f'<a href="{row["Apply"]}" target="_blank">Apply</a>' if row['Apply'] else "N/A"
|
| 234 |
+
|
| 235 |
+
df_data.append([
|
| 236 |
+
row['Role'],
|
| 237 |
+
row['Company'],
|
| 238 |
+
row['Company Type'],
|
| 239 |
+
row['Location'],
|
| 240 |
+
row['Posted'],
|
| 241 |
+
row['Score'],
|
| 242 |
+
row['Summary'],
|
| 243 |
+
apply_link
|
| 244 |
+
])
|
| 245 |
+
|
| 246 |
+
return df_data, f"Showing jobs {start+1}–{min(end,total)} of {total} (Page {page}/{pages})"
|
| 247 |
|
| 248 |
def load_jobs_and_pages(resume, added_kw, use_ai):
|
| 249 |
full_table, explanation = find_jobs(resume, added_kw, use_ai)
|
| 250 |
total_pages = max(1, math.ceil(len(full_table) / PER_PAGE))
|
| 251 |
slider_update = gr.update(value=1, maximum=total_pages)
|
| 252 |
+
first_page_data, page_info = jobs_to_dataframe(full_table, 1)
|
| 253 |
expl_header = "### AI Explanation" if explanation else ""
|
| 254 |
print("Header", expl_header)
|
| 255 |
|
| 256 |
+
return full_table, explanation, expl_header, slider_update, first_page_data, page_info
|
| 257 |
|
| 258 |
# 9️⃣ Gradio UI
|
| 259 |
with gr.Blocks(theme=gr.themes.Base()) as demo:
|
|
|
|
| 273 |
|
| 274 |
jobs_state = gr.State([]) # holds full table
|
| 275 |
page_sel = gr.Slider(1, 1, step=1, value=1, label="Page")
|
| 276 |
+
|
| 277 |
+
# Page info display
|
| 278 |
+
page_info = gr.Markdown("")
|
| 279 |
+
|
| 280 |
+
# DataFrame for jobs display
|
| 281 |
+
jobs_df = gr.DataFrame(
|
| 282 |
+
headers=["Role", "Company", "Type", "Location", "Posted", "Score", "Summary", "Apply"],
|
| 283 |
+
datatype=["str", "str", "str", "str", "str", "str", "str", "html"],
|
| 284 |
+
interactive=False,
|
| 285 |
+
wrap=True,
|
| 286 |
+
max_rows=PER_PAGE,
|
| 287 |
+
value=[]
|
| 288 |
+
)
|
| 289 |
+
|
| 290 |
expl_md_h = gr.Markdown()
|
| 291 |
expl_md = gr.Markdown() # shows AI explanation
|
| 292 |
|
| 293 |
# 1) On Find Jobs:
|
| 294 |
+
# - load the jobs, explanation, slider max, and first-page data
|
| 295 |
find_btn.click(
|
| 296 |
fn=load_jobs_and_pages,
|
| 297 |
inputs=[resume, added, use_ai],
|
| 298 |
+
outputs=[jobs_state, expl_md, expl_md_h, page_sel, jobs_df, page_info]
|
| 299 |
)
|
| 300 |
|
| 301 |
+
# 2) On page change, re-render only the table data
|
| 302 |
+
def update_page_display(tbl, pg):
|
| 303 |
+
df_data, info = jobs_to_dataframe(tbl, pg)
|
| 304 |
+
return df_data, info
|
| 305 |
+
|
| 306 |
page_sel.change(
|
| 307 |
+
fn=update_page_display,
|
| 308 |
inputs=[jobs_state, page_sel],
|
| 309 |
+
outputs=[jobs_df, page_info]
|
| 310 |
)
|
| 311 |
|
| 312 |
if __name__ == "__main__":
|