curiouscurrent commited on
Commit
c6c76ad
·
verified ·
1 Parent(s): 0e94fa0

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +119 -0
app.py ADDED
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import requests
3
+ import pandas as pd
4
+ import json
5
+
6
+ # ----------------------------
7
+ # CONFIG
8
+ # ----------------------------
9
+ st.set_page_config(page_title="Startup Candidate Dashboard", layout="wide")
10
+
11
+ JSON_URL = "https://file.notion.so/f/f/f86ed84d-b33c-4dfb-b0e0-97c5661516a3/3ed586a1-78e7-46af-9cf1-0961f95b5109/form-submissions-1.json?table=block&id=18a5392c-c93e-8054-b617-eb2a1a213d6c&spaceId=f86ed84d-b33c-4dfb-b0e0-97c5661516a3&expirationTimestamp=1758932214635&signature=sq1Jw2w3WoKIVMc8X078LO4SbfViD9ppdO0VXZ72Nro&downloadName=form-submissions.json"
12
+
13
+ MODEL_ID = "HuggingFaceH4/zephyr-7b-beta"
14
+ HF_API_TOKEN = st.secrets.get("HF_API_TOKEN") # store your Hugging Face token in Space Secrets
15
+
16
+ # ----------------------------
17
+ # CATEGORIES DEFINED BY JOB TITLES
18
+ # ----------------------------
19
+ CATEGORIES = {
20
+ "AI": [
21
+ "AI/ML Ops Engineer","Senior Machine Learning Engineer","Principal Data Scientist",
22
+ "Senior Data Scientist","Machine Learning Research Scientist","Senior AI/ML Engineer",
23
+ "AI/ML Engineer","Big Data Engineer","AI Research Scientist","AI Research Analyst Consultant",
24
+ "AI Analyst","Senior Data Analyst","Automation Engineer","Senior Data Engineer",
25
+ "Machine Learning Engineer","Data Engineer","Data Scientist","Data Analyst"
26
+ ],
27
+ "Marketing": [
28
+ "Marketing Specialist","Sales Agent","Salesman","Sales Associate"
29
+ ],
30
+ "CTO": [
31
+ "Chief Technology Officer","CTO"
32
+ ],
33
+ "Legal": [
34
+ "Legal Specialist","Attorney","Legal Intern","Lawyer"
35
+ ],
36
+ "Finance": [
37
+ "Financial Analyst","Financial Advisor"
38
+ ]
39
+ }
40
+
41
+ # ----------------------------
42
+ # HELPER FUNCTIONS
43
+ # ----------------------------
44
+ def fetch_json(url):
45
+ resp = requests.get(url)
46
+ resp.raise_for_status()
47
+ return resp.json()
48
+
49
+ def call_zephyr(prompt):
50
+ headers = {
51
+ "Authorization": f"Bearer {HF_API_TOKEN}",
52
+ "Content-Type": "application/json"
53
+ }
54
+ payload = {"inputs": prompt}
55
+ response = requests.post(
56
+ f"https://api-inference.huggingface.co/models/{MODEL_ID}",
57
+ headers=headers,
58
+ data=json.dumps(payload),
59
+ timeout=60
60
+ )
61
+ if response.status_code != 200:
62
+ st.error(f"Zephyr API error: {response.text}")
63
+ return None
64
+ result = response.json()
65
+ if isinstance(result, dict) and "error" in result:
66
+ st.error(result["error"])
67
+ return None
68
+ return result[0].get("generated_text", "")
69
+
70
+ def get_candidates_by_category(data, category_name, job_titles):
71
+ candidates = []
72
+ for person in data:
73
+ work_exps = person.get("work_experiences", [])
74
+ if len(work_exps) == 0:
75
+ continue # skip no experience
76
+ if any("full stack developer" in exp.get("roleName","").lower() for exp in work_exps):
77
+ continue # skip full stack
78
+
79
+ # Prepare prompt: ask Zephyr if this candidate matches any of the predefined job titles
80
+ prompt = f"""
81
+ You are an HR assistant. Determine if the following candidate is suitable for the category '{category_name}'.
82
+ The category is defined by the job titles: {job_titles}
83
+
84
+ Candidate JSON: {json.dumps(person)}
85
+
86
+ Respond only 'Yes' or 'No'.
87
+ """
88
+ try:
89
+ llm_response = call_zephyr(prompt)
90
+ if llm_response and "Yes" in llm_response:
91
+ candidates.append({
92
+ "Name": person.get("name"),
93
+ "Email": person.get("email"),
94
+ "Phone": person.get("phone"),
95
+ "Location": person.get("location"),
96
+ "Roles": ", ".join([exp.get("roleName") for exp in work_exps]),
97
+ "Skills": ", ".join(person.get("skills", [])),
98
+ "Salary": person.get("annual_salary_expectation", {}).get("full-time", "N/A")
99
+ })
100
+ except Exception as e:
101
+ st.warning(f"Error processing {person.get('name')}: {e}")
102
+ return pd.DataFrame(candidates)
103
+
104
+ # ----------------------------
105
+ # MAIN
106
+ # ----------------------------
107
+ st.title("🚀 Startup Candidate Dashboard - Zephyr LLM")
108
+
109
+ st.markdown("Fetching candidate data from Notion...")
110
+ data = fetch_json(JSON_URL)
111
+ st.success(f"✅ Loaded {len(data)} submissions!")
112
+
113
+ for category_name, job_titles in CATEGORIES.items():
114
+ st.subheader(f"{category_name} Suitable Candidates")
115
+ df = get_candidates_by_category(data, category_name, job_titles)
116
+ if df.empty:
117
+ st.write("No suitable candidates found.")
118
+ else:
119
+ st.dataframe(df)