mo7amed3ly commited on
Commit
8f0183f
·
verified ·
1 Parent(s): 4a0c3b8

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +73 -0
app.py ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI
2
+ from pydantic import BaseModel
3
+ from typing import List
4
+ from sentence_transformers import SentenceTransformer
5
+ from sklearn.metrics.pairwise import cosine_similarity
6
+ import numpy as np
7
+
8
+ # -----------------------
9
+ # Load model ONCE (important for performance)
10
+ # -----------------------
11
+ model = SentenceTransformer("all-MiniLM-L6-v2")
12
+
13
+ app = FastAPI(
14
+ title="CV Matching API",
15
+ description="Rank CVs against a Job Description using BERT embeddings",
16
+ version="1.0"
17
+ )
18
+
19
+ # -----------------------
20
+ # Request schema
21
+ # -----------------------
22
+ class MatchRequest(BaseModel):
23
+ job_description: str
24
+ cvs: List[str]
25
+
26
+ # -----------------------
27
+ # Response schema
28
+ # -----------------------
29
+ class CVScore(BaseModel):
30
+ cv_text: str
31
+ relevance_score: float
32
+
33
+ class MatchResponse(BaseModel):
34
+ results: List[CVScore]
35
+
36
+ # -----------------------
37
+ # Utility: text cleaning (optional but recommended)
38
+ # -----------------------
39
+ def clean_text(text: str) -> str:
40
+ return text.replace("\n", " ").strip().lower()
41
+
42
+ # -----------------------
43
+ # API endpoint
44
+ # -----------------------
45
+ @app.post("/match", response_model=MatchResponse)
46
+ def match_cvs(request: MatchRequest):
47
+ # Clean input
48
+ jd = clean_text(request.job_description)
49
+ cvs = [clean_text(cv) for cv in request.cvs]
50
+
51
+ # Embed job description
52
+ jd_embedding = model.encode([jd])
53
+
54
+ # Embed CVs
55
+ cv_embeddings = model.encode(cvs)
56
+
57
+ # Compute cosine similarity
58
+ scores = cosine_similarity(jd_embedding, cv_embeddings)[0]
59
+
60
+ # Build response
61
+ results = []
62
+ for cv_text, score in zip(request.cvs, scores):
63
+ results.append(
64
+ CVScore(
65
+ cv_text=cv_text,
66
+ relevance_score=float(score)
67
+ )
68
+ )
69
+
70
+ # Sort by relevance (descending)
71
+ results.sort(key=lambda x: x.relevance_score, reverse=True)
72
+
73
+ return MatchResponse(results=results)