Spaces:
Sleeping
Sleeping
File size: 3,000 Bytes
031a84a 5b624c3 031a84a 5b624c3 031a84a 5b624c3 031a84a 5b624c3 031a84a 9b0650f 031a84a | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | from fastapi import HTTPException, UploadFile
from schemas.report import (
AnalyzeResponseSchema,
CVAnalysisSchema,
JobMatchSchema,
RecommendationSchema,
SenioritySchema,
)
from use_cases.analyze_cv import AnalyzeCVUseCase
from domain.entities import AnalysisReport
MAX_PDF_SIZE_MB = 5
MIN_CONFIDENCE = 0.4
class AnalyzeController:
def __init__(self, use_case: AnalyzeCVUseCase):
self.use_case = use_case
async def handle(
self,
file: UploadFile,
job_description: str | None,
) -> AnalyzeResponseSchema:
pdf_bytes = await self._validate_and_read(file)
report = self.use_case.execute(pdf_bytes=pdf_bytes, job_description=job_description)
return self._to_response(report)
@staticmethod
def _resolve_area(label: str | None, confidence: float | None) -> str:
if not label or label == "Unknown":
return "No detectado"
if (confidence or 0.0) < MIN_CONFIDENCE:
return "No detectado"
return label
async def _validate_and_read(self, file: UploadFile) -> bytes:
if file.content_type != "application/pdf":
raise HTTPException(status_code=400, detail="El archivo debe ser un PDF.")
pdf_bytes = await file.read()
if len(pdf_bytes) > MAX_PDF_SIZE_MB * 1024 * 1024:
raise HTTPException(
status_code=400,
detail=f"El PDF no puede superar {MAX_PDF_SIZE_MB}MB.",
)
return pdf_bytes
def _to_response(self, report: AnalysisReport) -> AnalyzeResponseSchema:
return AnalyzeResponseSchema(
cv_analysis=CVAnalysisSchema(
extracted_skills=report.profile.skills,
experience_years=report.profile.experience_years,
roles=report.profile.roles,
education=report.profile.education,
seniority=SenioritySchema(
label=report.profile.seniority or "Unknown",
confidence=report.profile.seniority_confidence or 0.0,
),
area=SenioritySchema(
label=self._resolve_area(report.profile.area, report.profile.area_confidence),
confidence=report.profile.area_confidence or 0.0,
),
has_projects=report.profile.has_projects,
),
job_match=JobMatchSchema(
available=report.job_match.available,
score=report.job_match.score,
matched_skills=report.job_match.matched_skills,
missing_skills=report.job_match.missing_skills,
),
recommendations=[
RecommendationSchema(
category=r.category,
priority=r.priority,
message=r.message,
)
for r in report.recommendations
],
narrative=report.narrative,
)
|