Dev1012 commited on
Commit
d4efc9c
·
1 Parent(s): 4fb7a0a

Initial deploy: ATS Score Analyzer API

Browse files
Files changed (3) hide show
  1. app.py +32 -3
  2. ats_core.py +29 -0
  3. requirements.txt +2 -0
app.py CHANGED
@@ -2,7 +2,8 @@ import os
2
  import time
3
  from fastapi import FastAPI, HTTPException, Request
4
  from pydantic import BaseModel
5
- from ats_core import ats_score
 
6
 
7
  PORT = int(os.environ.get("PORT", 7860))
8
 
@@ -33,11 +34,39 @@ def check_rate_limit(request: Request):
33
  usage_tracker[ip][today] = usage_tracker[ip].get(today, 0) + 1
34
 
35
 
 
 
36
  @app.post("/ats-score")
37
- def compute_ats(req: ATSRequest, request: Request):
 
 
 
 
 
38
  check_rate_limit(request)
39
- return ats_score(req.resume_text, req.job_description)
40
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
 
42
  @app.get("/health")
43
  def health():
 
2
  import time
3
  from fastapi import FastAPI, HTTPException, Request
4
  from pydantic import BaseModel
5
+ from ats_core import ats_score, extract_text_from_pdf, ROLE_TEMPLATES
6
+
7
 
8
  PORT = int(os.environ.get("PORT", 7860))
9
 
 
34
  usage_tracker[ip][today] = usage_tracker[ip].get(today, 0) + 1
35
 
36
 
37
+ from fastapi import UploadFile, File, Form
38
+
39
  @app.post("/ats-score")
40
+ async def compute_ats(
41
+ resume_file: UploadFile = File(...),
42
+ job_description: str = Form(""),
43
+ role: str = Form(""),
44
+ request: Request = None
45
+ ):
46
  check_rate_limit(request)
 
47
 
48
+ # Read resume PDF
49
+ if resume_file.content_type != "application/pdf":
50
+ raise HTTPException(status_code=400, detail="Resume must be a PDF")
51
+
52
+ file_bytes = await resume_file.read()
53
+ resume_text = extract_text_from_pdf(file_bytes)
54
+
55
+ if not resume_text:
56
+ raise HTTPException(status_code=400, detail="Could not extract text from resume")
57
+
58
+ # Decide JD source
59
+ if job_description.strip():
60
+ jd_text = job_description
61
+ elif role.lower() in ROLE_TEMPLATES:
62
+ jd_text = ROLE_TEMPLATES[role.lower()]
63
+ else:
64
+ raise HTTPException(
65
+ status_code=400,
66
+ detail="Provide job description text or select a valid role"
67
+ )
68
+
69
+ return ats_score(resume_text, jd_text)
70
 
71
  @app.get("/health")
72
  def health():
ats_core.py CHANGED
@@ -2,10 +2,31 @@ from sentence_transformers import SentenceTransformer
2
  from sklearn.metrics.pairwise import cosine_similarity
3
  import nltk
4
  import re
 
5
 
6
  nltk.download("stopwords")
7
  from nltk.corpus import stopwords
8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  model = SentenceTransformer("all-MiniLM-L6-v2")
10
  STOPWORDS = set(stopwords.words("english"))
11
 
@@ -80,3 +101,11 @@ def ats_score(resume_text, jd_text):
80
  "formatting_score": to_float(round(format_score * 10, 2)),
81
  "missing_keywords": list(set(jd_keywords) - set(resume_keywords))[:10]
82
  }
 
 
 
 
 
 
 
 
 
2
  from sklearn.metrics.pairwise import cosine_similarity
3
  import nltk
4
  import re
5
+ import pdfplumber
6
 
7
  nltk.download("stopwords")
8
  from nltk.corpus import stopwords
9
 
10
+ ROLE_TEMPLATES = {
11
+ "backend": """
12
+ Backend Engineer with experience in Python, APIs, databases,
13
+ system design, REST services, Docker, and scalable backend systems.
14
+ """,
15
+ "frontend": """
16
+ Frontend Developer skilled in JavaScript, React, HTML, CSS,
17
+ responsive design, UI/UX, and modern frontend frameworks.
18
+ """,
19
+ "ml": """
20
+ Machine Learning Engineer with experience in Python, data analysis,
21
+ machine learning models, feature engineering, evaluation metrics,
22
+ and deployment of ML systems.
23
+ """,
24
+ "data": """
25
+ Data Analyst with experience in SQL, Python, data visualization,
26
+ statistics, dashboards, and business insights.
27
+ """
28
+ }
29
+
30
  model = SentenceTransformer("all-MiniLM-L6-v2")
31
  STOPWORDS = set(stopwords.words("english"))
32
 
 
101
  "formatting_score": to_float(round(format_score * 10, 2)),
102
  "missing_keywords": list(set(jd_keywords) - set(resume_keywords))[:10]
103
  }
104
+
105
+ def extract_text_from_pdf(file_bytes):
106
+ text = ""
107
+ with pdfplumber.open(file_bytes) as pdf:
108
+ for page in pdf.pages:
109
+ if page.extract_text():
110
+ text += page.extract_text() + "\n"
111
+ return text.strip()
requirements.txt CHANGED
@@ -4,3 +4,5 @@ sentence-transformers
4
  scikit-learn
5
  numpy
6
  nltk
 
 
 
4
  scikit-learn
5
  numpy
6
  nltk
7
+ pdfplumber
8
+ python-multipart