diff --git a/hrflow/job/__init__.py b/hrflow/job/__init__.py index b2f80d3..75f792f 100644 --- a/hrflow/job/__init__.py +++ b/hrflow/job/__init__.py @@ -1,5 +1,6 @@ from .asking import JobAsking from .embedding import JobEmbedding +from .matching import JobMatching from .parsing import JobParsing from .reasoning import JobReasoning from .scoring import JobScoring @@ -17,3 +18,4 @@ def __init__(self, client): self.scoring = JobScoring(self.client) self.reasoning = JobReasoning(self.client) self.storing = JobStoring(self.client) + self.matching = JobMatching(self.client) diff --git a/hrflow/job/matching.py b/hrflow/job/matching.py new file mode 100644 index 0000000..429aefb --- /dev/null +++ b/hrflow/job/matching.py @@ -0,0 +1,113 @@ +import json + +from ..core.rate_limit import rate_limiter +from ..core.validation import ( + KEY_REGEX, + ORDER_BY_VALUES, + SORT_BY_VALUES, + validate_key, + validate_limit, + validate_page, + validate_provider_keys, + validate_reference, + validate_response, + validate_value, +) + + +class JobMatching: + def __init__(self, api): + """Init.""" + self.client = api + + @rate_limiter + def list( + self, + board_key, + job_key=None, + job_reference=None, + board_keys=None, + page=1, + limit=30, + sort_by="created_at", + order_by=None, + created_at_min=None, + created_at_max=None, + **kwargs, + ): + """ + 💾 Match Jobs indexed in Boards to a Job + (https://api.hrflow.ai/v1/jobs/matching). + + Args: + board_key: + The key of the Board in which the job is indexed. + job_key: + The key of a specific job to macth with. + job_reference: + The reference of a specific job to macth with. + board_keys: + A list of keys for multiple Boards of profiles to be matched with the specific job. + Example : ["xxx", "yyy", "zzz"] + limit: (default to 30) + number of fetched jobs/page + page: REQUIRED default to 1 + number of the page associated to the pagination + sort_by: + order_by: + created_at_min: + The minimum date of creation of the targeted Jobs. + Format: "YYYY-MM-DD". + created_at_max: + The maximum date of creation of the targeted Jobs. + Format: "YYYY-MM-DD". + + Returns: + Match the job identified by job_key or job_reference + and board_key with all jobs in the boards identified by keys in board_keys list. + Response examples: + - Success response: + { + "code": 200, # response code + "message": "Job Matching results", # response message + "meta" : { + 'page': 1, # current page + 'maxPage': 5, # max page in the paginated response + 'count': 2, # number of jobs in the current page + 'total': 10 # total number of jobs retrieved + }, + "data": { # list of jobs objects + "predictions": [[]], + "jobs": [ + { + "key": "xxx", + "reference": "xxx", + ... + }, + ... + ] + } + } + - Error response: (if the board_key is not valid) + { + "code": 400, + "message": "Invalid parameters. Unable to find object: source" + } + """ + + query_params = { + "board_key": validate_key("Board", board_key, regex=KEY_REGEX), + "job_key": validate_key("Key", job_key, regex=KEY_REGEX), + "job_reference": validate_reference(job_reference), + "board_keys": json.dumps(validate_provider_keys(board_keys)), + "limit": validate_limit(limit), + "page": validate_page(page), + "sort_by": validate_value(sort_by, SORT_BY_VALUES, "sort by"), + "order_by": validate_value(order_by, ORDER_BY_VALUES, "order by"), + "created_at_min": created_at_min, # TODO validate dates format + "created_at_max": created_at_max, # TODO validate dates format + } + + params = {**query_params, **kwargs} + response = self.client.get("jobs/matching", params) + return validate_response(response) diff --git a/hrflow/profile/__init__.py b/hrflow/profile/__init__.py index 44a8dec..1f5016b 100644 --- a/hrflow/profile/__init__.py +++ b/hrflow/profile/__init__.py @@ -3,6 +3,8 @@ from .asking import ProfileAsking from .attachment import ProfileAttachments from .embedding import ProfileEmbedding +from .grading import ProfileGrading +from .matching import ProfileMatching from .parsing import ProfileParsing from .reasoning import ProfileReasoning from .revealing import ProfileRevealing @@ -35,3 +37,5 @@ def __init__(self, client): self.searching = ProfileSearching(self.client) self.reasoning = ProfileReasoning(self.client) self.unfolding = ProfileUnfolding(self.client) + self.matching = ProfileMatching(self.client) + self.grading = ProfileGrading(self.client) diff --git a/hrflow/profile/grading.py b/hrflow/profile/grading.py new file mode 100644 index 0000000..a55b973 --- /dev/null +++ b/hrflow/profile/grading.py @@ -0,0 +1,72 @@ +import json +import typing as t + +from ..core.rate_limit import rate_limiter +from ..core.validation import ( + KEY_REGEX, + ORDER_BY_VALUES, + SORT_BY_VALUES, + validate_key, + validate_limit, + validate_page, + validate_provider_keys, + validate_reference, + validate_response, + validate_value, +) + + +class ProfileGrading: + def __init__(self, api): + """Initialize the ProfileGrading class with the provided API client.""" + self.client = api + + @rate_limiter + def get( + self, + algorithm_key: str, + source_key: str, + board_key: str, + profile_key: t.Optional[str] = None, + profile_reference: t.Optional[str] = None, + job_key: t.Optional[str] = None, + job_reference: t.Optional[str] = None, + ): + """ + 💾 Grade a Profile indexed in a Source for a Job + (https://api.hrflow.ai/v1/profile/grading). + + Args: + algorithm_key: + The key of the grading algorithm to use. + Refer to the documentation: https://developers.hrflow.ai/reference/grade-a-profile-indexed-in-a-source-for-a-job + for all possible values. + source_key: + The key of the Source where the profile to grade is indexed. + board_key: + The key of the Board where the job to grade to is indexed. + profile_key: + (Optional) The Profile unique identifier. + profile_reference: + (Optional) The Profile reference chosen by the customer. + job_key: + (Optional) The Job unique identifier. + job_reference: + (Optional) The Job reference chosen by the customer. + + Returns: + The grading information for the profile, based on the specified job. + + """ + query_params = { + "algorithm_key": algorithm_key, + "source_key": validate_key("Source", source_key, regex=KEY_REGEX), + "profile_key": validate_key("Key", profile_key, regex=KEY_REGEX), + "profile_reference": validate_reference(profile_reference), + "board_key": validate_key("Board", board_key, regex=KEY_REGEX), + "job_key": validate_key("Key", job_key, regex=KEY_REGEX), + "job_reference": validate_reference(job_reference), + } + + response = self.client.get("profile/grading", query_params) + return validate_response(response) diff --git a/hrflow/profile/matching.py b/hrflow/profile/matching.py new file mode 100644 index 0000000..d4acd84 --- /dev/null +++ b/hrflow/profile/matching.py @@ -0,0 +1,113 @@ +import json + +from ..core.rate_limit import rate_limiter +from ..core.validation import ( + KEY_REGEX, + ORDER_BY_VALUES, + SORT_BY_VALUES, + validate_key, + validate_limit, + validate_page, + validate_provider_keys, + validate_reference, + validate_response, + validate_value, +) + + +class ProfileMatching: + def __init__(self, api): + """Initialize the ProfileMatching class with the provided API client.""" + self.client = api + + @rate_limiter + def list( + self, + source_key, + profile_key=None, + profile_reference=None, + source_keys=None, + page=1, + limit=30, + sort_by="created_at", + order_by=None, + created_at_min=None, + created_at_max=None, + **kwargs, + ): + """ + 💾 Match Profils indexed in Sources to a Profile + (https://api.hrflow.ai/v1/profils/matching). + + Args: + source_key: + The key of the Source in which the profile is indexed. + profile_key: (Optional) + The key of a specific profile to macth with. + profile_reference: (Optional) + The reference of a specific profile to macth with. + source_keys: (Optional) + A list of keys for multiple Sources of profiles to be matched with the profile. + page: (default to 1) + The page number for pagination. + limit: (default to 30) + Number of profiles to fetch per page. + sort_by: (default to "created_at") + The field to sort by. + order_by: (Optional) + The order of sorting, either 'asc' or 'desc'. + created_at_min: (Optional) + The minimum creation date of the profiles in format "YYYY-MM-DD". + created_at_max: (Optional) + The maximum creation date of the profiles in format "YYYY-MM-DD". + + Returns: + Match the profile identified by profile_key or profile_reference + and source_key with all profiles in the sources identified by keys in source_keys list. + + Response examples: + - Success response: + { + "code": 200, # response code + "message": "Profile Matching results", # response message + "meta": { + 'page': 1, # current page + 'maxPage': 5, # max page in the paginated response + 'count': 2, # number of profiles in the current page + 'total': 10 # total number of profiles retrieved + }, + "data": { # list of profile objects + "predictions": [[]], + "profiles": [ + { + "key": "xxx", + "reference": "xxx", + ... + }, + ... + ] + } + } + - Error response: (if the source_key is not valid) + { + "code": 400, + "message": "Invalid parameters. Unable to find object: source" + } + """ + + query_params = { + "source_key": validate_key("Source", source_key, regex=KEY_REGEX), + "profile_key": validate_key("Key", profile_key, regex=KEY_REGEX), + "profile_reference": validate_reference(profile_reference), + "source_keys": json.dumps(validate_provider_keys(source_keys)), + "limit": validate_limit(limit), + "page": validate_page(page), + "sort_by": validate_value(sort_by, SORT_BY_VALUES, "sort by"), + "order_by": validate_value(order_by, ORDER_BY_VALUES, "order by"), + "created_at_min": created_at_min, # TODO validate dates format + "created_at_max": created_at_max, # TODO validate dates format + } + + params = {**query_params, **kwargs} + response = self.client.get("profiles/matching", params) + return validate_response(response)