generated from kgod/ai-review-template
feat: improve resume optimization and import reliability
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import time
|
||||
from collections import OrderedDict
|
||||
from pathlib import Path
|
||||
from typing import Protocol
|
||||
@@ -10,6 +11,7 @@ from uuid import uuid4
|
||||
|
||||
from .document_extractors import extract_text, normalize_upload_name, validate_upload
|
||||
from .import_parser_fast import slim_parser
|
||||
from .llm_services import log_ai_event
|
||||
from .resume_import_models import ParsedResumeDraft
|
||||
from .resume_import_rules import parse_resume_text
|
||||
|
||||
@@ -38,16 +40,29 @@ class ResumeImportService:
|
||||
self._parse_cache: OrderedDict[str, ParsedResumeDraft] = OrderedDict()
|
||||
|
||||
def prepare(self, *, file_name: str, declared_mime: str | None, content: bytes) -> dict:
|
||||
total_started = time.perf_counter()
|
||||
if len(content) > MAX_IMPORT_BYTES:
|
||||
raise ValueError("import_file_too_large")
|
||||
safe_name, extension = normalize_upload_name(file_name)
|
||||
mime_type = validate_upload(extension=extension, declared_mime=declared_mime, content=content)
|
||||
sha256 = hashlib.sha256(content).hexdigest()
|
||||
draft = self._parse_cache.get(sha256)
|
||||
cache_hit = draft is not None
|
||||
extract_ms = 0
|
||||
parse_ms = 0
|
||||
validate_ms = 0
|
||||
text_characters: int | None = None
|
||||
if draft is None:
|
||||
extract_started = time.perf_counter()
|
||||
text = extract_text(extension=extension, content=content)
|
||||
extract_ms = round((time.perf_counter() - extract_started) * 1000)
|
||||
text_characters = len(text)
|
||||
parse_started = time.perf_counter()
|
||||
draft = self.parser.parse(text=text, source_name=safe_name)
|
||||
parse_ms = round((time.perf_counter() - parse_started) * 1000)
|
||||
validate_started = time.perf_counter()
|
||||
self._validate_document(draft.document)
|
||||
validate_ms = round((time.perf_counter() - validate_started) * 1000)
|
||||
self._parse_cache[sha256] = draft
|
||||
self._parse_cache.move_to_end(sha256)
|
||||
while len(self._parse_cache) > _PARSE_CACHE_SIZE:
|
||||
@@ -57,8 +72,22 @@ class ResumeImportService:
|
||||
draft = draft.model_copy(deep=True)
|
||||
object_key = f"{sha256[:2]}/{uuid4().hex}{extension}"
|
||||
target = self.storage_root / object_key
|
||||
storage_started = time.perf_counter()
|
||||
target.parent.mkdir(parents=True, exist_ok=True)
|
||||
target.write_bytes(content)
|
||||
storage_ms = round((time.perf_counter() - storage_started) * 1000)
|
||||
log_ai_event(
|
||||
"resume_import_prepared",
|
||||
extract_ms=extract_ms,
|
||||
parse_ms=parse_ms,
|
||||
validate_ms=validate_ms,
|
||||
storage_ms=storage_ms,
|
||||
total_ms=round((time.perf_counter() - total_started) * 1000),
|
||||
cache_hit=cache_hit,
|
||||
file_extension=extension,
|
||||
size_bytes=len(content),
|
||||
text_characters=text_characters,
|
||||
)
|
||||
return {
|
||||
"file_name": safe_name,
|
||||
"mime_type": mime_type,
|
||||
|
||||
Reference in New Issue
Block a user