Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions hrflow/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,12 @@ class Experience(BaseModel):
tasks: t.Optional[t.List[GeneralEntitySchema]] = Field(
None, description="List of tasks of the Experience."
)
languages: t.Optional[t.List[GeneralEntitySchema]] = Field(
None, description="List of spoken languages of the profile"
)
interests: t.Optional[t.List[GeneralEntitySchema]] = Field(
None, description="List of interests of the Experience."
)


class Education(BaseModel):
Expand Down Expand Up @@ -274,6 +280,12 @@ class Education(BaseModel):
tasks: t.Optional[t.List[GeneralEntitySchema]] = Field(
None, description="List of tasks of the Education."
)
languages: t.Optional[t.List[GeneralEntitySchema]] = Field(
None, description="List of spoken languages of the profile"
)
interests: t.Optional[t.List[GeneralEntitySchema]] = Field(
None, description="List of interests of the Experience."
)


class Attachment(BaseModel):
Expand Down
2 changes: 2 additions & 0 deletions hrflow/utils/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# noqa: F401
from .evaluation import generate_parsing_evaluation_report
from .scoring import is_valid_for_scoring
from .searching import is_valid_for_searching
from .storing import get_all_jobs, get_all_profiles
75 changes: 75 additions & 0 deletions hrflow/utils/scoring.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import typing as t

from ..schemas import Education, Experience, HrFlowProfile
from .searching import is_valid_for_searching


def is_valid_experiences_for_scoring(
experience_list: t.Optional[t.List[Experience]],
) -> bool:
"""
Check if a list of experiences is valid for scoring

Args:
experience_list: <list>
List of experiences to check
Return:
<bool> True if the list of experiences is valid for
scoring, False otherwise
"""
for experience in experience_list:
if experience.title:
return True

return False


def is_valid_educations_for_scoring(
education_list: t.Optional[t.List[Education]],
) -> bool:
"""
Check if a list of educations is valid for scoring

Args:
education_list: <list>
List of educations to check
Return:
<bool> True if the list of educations is valid for
scoring, False otherwise
"""
for education in education_list:
if education.title or education.school:
return True
return False


def is_valid_for_scoring(
profile: t.Union[t.Dict, HrFlowProfile],
) -> bool:
"""
Check if a profile is valid for scoring

Based on the following schemas https://developers.hrflow.ai/docs/profiles-scoring

Args:
client: <Hrflow>
Hrflow client
profile: <dict> or <HrFlowProfile>
Profile to check
Return:
<bool> True if the profile is valid for scoring,
False otherwise
"""
if isinstance(profile, dict):
profile = HrFlowProfile.parse_obj(profile)

if not isinstance(profile, HrFlowProfile):
raise ValueError("profile must be a dict or a HrFlowProfile object")

return is_valid_for_searching(profile) and (
is_valid_experiences_for_scoring(profile.experiences)
or is_valid_educations_for_scoring(profile.educations)
or bool(profile.summary)
or bool(profile.skills)
or bool(profile.tasks)
)
67 changes: 67 additions & 0 deletions hrflow/utils/searching.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import typing as t

from ..schemas import HrFlowProfile, ProfileInfo


def is_valid_info_for_searching(info: ProfileInfo) -> bool:
"""
Check if the info part of a profile is valid for searching

Based on the following schemas https://developers.hrflow.ai/docs/profiles-searching

Args:
info: <ProfileInfo>
Info part of the profile
"""
if not isinstance(info, ProfileInfo):
raise ValueError("info must be a ProfileInfo object")

first_name_score = 1 if info.first_name else 0
last_name_score = 1 if info.last_name else 0
phone_score = 1 if info.phone else 0
date_birth_score = 1 if info.date_birth else 0
gender_score = 1 if info.gender else 0
summary_score = 1 if info.summary else 0
urls_score = 1 if info.urls else 0
location_score = 1 if info.location else 0

info_score = (
first_name_score
+ last_name_score
+ phone_score
+ date_birth_score
+ gender_score
+ summary_score
+ urls_score
+ location_score
)
info_score = info_score / 8
has_person = info.first_name and info.last_name

return info.email or has_person or info_score >= 0.5


def is_valid_for_searching(
profile: t.Union[t.Dict, HrFlowProfile],
) -> bool:
"""
Check if a profile is valid for searching

Based on the following schemas https://developers.hrflow.ai/docs/profiles-searching

Args:
client: <Hrflow>
Hrflow client
profile: <dict> or <HrFlowProfile>
Profile to check
Return:
<bool> True if the profile is valid for searching,
False otherwise
"""
if isinstance(profile, dict):
profile = HrFlowProfile.parse_obj(profile)

if not isinstance(profile, HrFlowProfile):
raise ValueError("profile must be a dict or a HrFlowProfile object")

return is_valid_info_for_searching(profile.info) and bool(profile.text)