Kaito117 commited on
Commit
8cf6b7b
·
1 Parent(s): 1f4cf02

add readme, add defaults and uuid creation in routes

Browse files
Files changed (2) hide show
  1. README.md +62 -1
  2. app/api/routes.py +3 -1
README.md CHANGED
@@ -1 +1,62 @@
1
- # score_profiles
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # score_profiles
2
+
3
+ AI-powered LinkedIn candidate sourcing and scoring microservice.
4
+
5
+ ## Features
6
+
7
+ - FastAPI HTTP API with a `/jobs` endpoint
8
+ - URL extraction, SerpAPI search, GitHub & LinkedIn profile clients
9
+ - Profile data extraction & ranking via a `CandidateScorer`
10
+ - CORS enabled for all origins
11
+ - Comprehensive unit & integration tests using `pytest`, `respx` & FastAPI `TestClient`
12
+
13
+ ## Getting Started
14
+
15
+ ### Prerequisites
16
+
17
+ - Python 3.12+
18
+ - `uv` or `pip`
19
+ - `.env` file copied from `.env.example`, populated with your api keys
20
+
21
+ ### Installation
22
+
23
+ ```sh
24
+ # Using pip
25
+ pip install -r requirements.txt
26
+ # or using poetry
27
+ uv sync
28
+ ```
29
+
30
+ ### Configuration
31
+
32
+ Copy `.env.example` to `.env` and populate with your own fields:
33
+
34
+ Additionally, check is you want to change any configs in `config.py` (though the defaults are sensible).
35
+
36
+ ### Running the Service
37
+
38
+ ```sh
39
+ python app/main.py
40
+ ```
41
+
42
+ Docker based setup is not ready yet.
43
+
44
+ The API docs are available at `http://localhost:8000/docs`.
45
+
46
+ ## Testing
47
+
48
+ All HTTP calls are stubbed using [`respx`](https://github.com/lundberg/respx) and fixtures under `test/data/`.
49
+
50
+ ```sh
51
+ pytest
52
+ ```
53
+
54
+ ## Workflow
55
+
56
+ 1. Client POSTs to `/jobs` with `search_query` (job description).
57
+ 2. `LinkedInSourcingAgent` orchestrates:
58
+ - `SerpAPIClient.search` → get LinkedIn & GitHub URLs
59
+ - `LinkedInProfileClient.fetch_profile` & `GitHubClient.fetch_github_profile_html`
60
+ - `LinkedInProfileExtractor` & `GitHubProfileExtractor` → normalized profile dicts
61
+ - `CandidateScorer.batch_score_candidates` → rank & filter
62
+ 3. Returns top-N scored
app/api/routes.py CHANGED
@@ -1,4 +1,5 @@
1
  from fastapi import APIRouter
 
2
  from pydantic import BaseModel
3
  from app.core.job_parser import JobParserAgent
4
  from app.models.schemas import JobProcessingRequest, JobProcessingResponse
@@ -7,7 +8,7 @@ from app.services.agent import LinkedInSourcingAgent
7
  router = APIRouter()
8
 
9
  class HTTPJobRequest(BaseModel):
10
- job_id: str
11
  search_query: str
12
  max_candidates: int = 50
13
  include_github: bool = False
@@ -15,6 +16,7 @@ class HTTPJobRequest(BaseModel):
15
 
16
  @router.post("/jobs", response_model=JobProcessingResponse)
17
  async def process_job(req: HTTPJobRequest):
 
18
  parser = JobParserAgent()
19
  job_desc = await parser.parse(req.search_query)
20
 
 
1
  from fastapi import APIRouter
2
+ import uuid
3
  from pydantic import BaseModel
4
  from app.core.job_parser import JobParserAgent
5
  from app.models.schemas import JobProcessingRequest, JobProcessingResponse
 
8
  router = APIRouter()
9
 
10
  class HTTPJobRequest(BaseModel):
11
+ job_id: str = None
12
  search_query: str
13
  max_candidates: int = 50
14
  include_github: bool = False
 
16
 
17
  @router.post("/jobs", response_model=JobProcessingResponse)
18
  async def process_job(req: HTTPJobRequest):
19
+ req.job_id = str(uuid.uuid4())
20
  parser = JobParserAgent()
21
  job_desc = await parser.parse(req.search_query)
22