from collections.abc import Sequence from decimal import Decimal from typing import cast from httpx import AsyncClient from template_project.application.common.data_structure import to_data_structure from template_project.application.resume.entity import ResumeId @to_data_structure class SuitableVacancyDs: vacancy_id: str from_salary: Decimal to_salary: Decimal key_skills: list[str] resume_similarity: float @to_data_structure class GenerateResumePredictionResponse: salary_from: Decimal salary_to: Decimal recommended_skills: list[str] class MlApiGateway: def __init__(self, client: AsyncClient) -> None: self._client = client async def generate_embedding(self, text: str) -> list[float]: response = await self._client.post("/get_embedding", json={"text": text}, timeout=100) return cast(list[float], response.json()["embedding"]) async def generate_resume_prediction( self, resume_id: ResumeId, key_skills: list[str], suitable_vacancies: Sequence[SuitableVacancyDs], ) -> GenerateResumePredictionResponse: response = await self._client.post( "/predict", json={ "resume_id": str(resume_id), "key_skills": key_skills, "vacancies": [ { "vacancy_id": str(suitable_vacancy.vacancy_id), "from_salary": str(suitable_vacancy.from_salary), "to_salary": str(suitable_vacancy.to_salary), "key_skills": suitable_vacancy.key_skills, "resume_similarity": suitable_vacancy.resume_similarity, } for suitable_vacancy in suitable_vacancies ], }, timeout=100, ) response.raise_for_status() response_json = response.json() return GenerateResumePredictionResponse( salary_from=Decimal(str(response_json["salary_from"])), salary_to=Decimal(str(response_json["salary_to"])), recommended_skills=response_json["recommended_skills"], )