Skip to content

Commit

Permalink
Merge pull request #31 from Riminder/dev
Browse files Browse the repository at this point in the history
Merge `dev` -> `master` : version `1.0.0`
  • Loading branch information
corentin-hrflow authored Jan 19, 2022
2 parents 6af295c + eb0f702 commit f05fe6b
Show file tree
Hide file tree
Showing 215 changed files with 5,754 additions and 3,933 deletions.
32 changes: 31 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,34 @@ All notable changes to this project will be documented in this file.
### Changed
* Pipeline in Action and BoardAction to use `format_switcher` instead of `format`
### Fixed
* HTTPStream : static private attributes become public attributes
* HTTPStream : static private attributes become public attributes

## Version 1.0.0 - 2022/01/19
### Added
* Add `Connector` interface
* add `PullBaseAction` class
* add `PullBaseAction` class
* Breezy.hr Connector
* Ceridian Connector
* Greenhouse Connector
* Monster Connector
* Recruitee Connector
* SAPSuccessfactors Connector
* Smartrecruiters Connector : `PushProfileAction`
* Taleez Connector
* Workable Connector
### Changed
* Facilitate `import`
* Rename `Action` -> `BaseAction`
* Rename `BoardAction` -> `PullJobsBaseAction`
* Rename `ProfileDestinationAction` -> `PushProfileBaseAction`
* Rename `JobDestinationAction` -> `PushJobBaseAction`
* `Auth` is compatible with `requests` auth
* Change the package architecture
* Move docs of each action into `docs/`
* Improve documentation
### Fixed
* Unescape HTML in Hrflow.ai fields `summary` & `sections`
### Removed
* Remove `HTTPStream` and replace with `requests.Request`
* Remove all crawlers : Craigslist and Indeed
40 changes: 18 additions & 22 deletions DOCUMENTATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ In the action execution pipeline, here is where the `logics` are located:
3. Apply `format` to each element
4. `push` the data

**All `Action`s have the following parameters:**
**All actions have the following parameters:**
* `logics` which is a list of function names. This will be used to filter the elements returned by `pull`.
* `global_scope` is a dictionary containing the current scope's global variables.
* `local_scope` is a dictionary containing the current scope's local variables.
Expand All @@ -30,12 +30,12 @@ Most of the time, you would just write `global_scope=globals()` and `local_scope

### Example
```python
from hrflow_connectors.core.action import Action
from hrflow_connectors.core.action import BaseAction

def filter_element1_with_value1(element):
return element.get("element1") == "value1"

action = Action(
action = BaseAction(
logics=["filter_element1_with_value1"],
global_scope=globals(),
local_scope=locals(),
Expand Down Expand Up @@ -75,9 +75,9 @@ By default, all connectors have a `format` provided and ready to use. If you wan

### By inheriting & overriding `format`
```python
from hrflow_connectors.core.action import Action
from hrflow_connectors.core.action import BaseAction

class ActionWithMyFormat(Action)
class ActionWithMyFormat(BaseAction)
def format(data):
# my format
job = dict(my_ref=data["id"])
Expand All @@ -88,7 +88,7 @@ action.execute()
```
### By using a format function external

**All `Action`s have the following parameters:**
**All actions have the following parameters:**
* `format_function_name` which is the function name. This will be used to format each element returned by `pull`.
* `global_scope` is a dictionary containing the current scope's global variables.
* `local_scope` is a dictionary containing the current scope's local variables.
Expand All @@ -103,14 +103,14 @@ Most of the time, you would just write `global_scope=globals()` and `local_scope
ℹ️ To find out more about the scopes and how the `eval` function works: https://docs.python.org/3/library/functions.html#eval

```python
from hrflow_connectors.core.action import Action
from hrflow_connectors.core.action import BaseAction

def my_format(data):
# my format
job = dict(my_ref=data["id"])
return job

action = Action(
action = BaseAction(
format_function_name="my_format",
global_scope=globals(),
local_scope=locals(),
Expand All @@ -119,19 +119,18 @@ action.execute()
```

## Using parsing to enrich a job
**All `Action` for connectors found in `connectors/boards` have an option to enrich a job with parsing.**
**All `PullJobsAction`s have an option to enrich a job with parsing.**

Parsing will parse all the text fields and extract the characteristics of the job and add them to the appropriate fields in ***Hrflow.ai***: `skills`, `languages`, `certifications`, `courses`, `tasks`, ...

**To enable parsing, simply turn on the option `hydrate_with_parsing`.**
```python
from hrflow_connectors.core.action import BoardAction
from hrflow_connectors import MyConnector

action = BoardAction(hydrate_with_parsing=True, ...)
action.execute()
MyConnector.pull_jobs(hydrate_with_parsing=True, ...)
```
## Automatically archive a job when it is deleted from the stream
**All `Action` for connectors found in `connectors/boards` have an `archive_deleted_jobs_from_stream` option to automatically archive a Board job when it is deleted from the stream.**
***All `PullJobsAction`s have an `archive_deleted_jobs_from_stream` option to automatically archive a Board job when it is deleted from the stream.**

This can be useful for synchronizing a board with a job stream.
In this case, you only need to enable the `archive_deleted_jobs_from_stream=True` option.
Expand All @@ -140,10 +139,9 @@ But in some cases, you may only want to add jobs without worrying that the job i

Here is how it looks in an example :
```python
from hrflow_connectors.core.action import BoardAction
from hrflow_connectors import MyConnector

action = BoardAction(archive_deleted_jobs_from_stream=True, ...)
action.execute()
MyConnector.pull_jobs(archive_deleted_jobs_from_stream=True, ...)
```

## Using `hrflow_connector` in a CATCH workflow to get a profile
Expand All @@ -156,7 +154,7 @@ This method retrieves information from a profile if it exists in `_request`.

**Let's take a simple example:**
```python
from hrflow_connectors.connectors.core.action import ProfileDestinationAction
from hrflow_connectors import MyConnector
from hrflow_connectors.utils.hrflow import EventParser

def workflow(_request, settings):
Expand All @@ -166,15 +164,14 @@ def workflow(_request, settings):
event = EventParser(request=_request)
profile = event.get_profile()
if profile is not None:
action = ProfileDestinationAction(profile=profile, ...)
response = action.execute()
response = MyConnector.push_profile(profile=profile, ...)
return response
```

If now you only want to process the profiles added **in the sources with the following keys `MY_SOURCE_KEY_1` and `MY_SOURCE_KEY_2`**.
Then you just have to write :
```python
from hrflow_connectors.connectors.core.action import ProfileDestinationAction
from hrflow_connectors import MyConnector
from hrflow_connectors.utils.hrflow import EventParser

def workflow(_request, settings):
Expand All @@ -184,8 +181,7 @@ def workflow(_request, settings):
event = EventParser(request=_request)
profile = event.get_profile(source_to_listen=["MY_SOURCE_KEY_1", "MY_SOURCE_KEY_2"])
if profile is not None:
action = ProfileDestinationAction(profile=profile, ...)
response = action.execute()
response = MyConnector.push_profile(profile=profile, ...)
return response
```
So **if a profile is added to the source with the key `OTHER_SOURCE_KEY`** then `get_profile` would return `None` and **that profile would be ignored** from the rest of the processing.
Expand Down
150 changes: 59 additions & 91 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,62 @@ This project is designed to simply and easily handle,
complex HR integrations by using [**workflows**](https://developers.hrflow.ai/docs/workflows) feature.
<br/>


## About HrFlow.ai
https://www.HrFlow.ai is **an API first company that provides the most sophisticated AI-Powered JOB & PROFILE API**. Corporates and Software vendors can leverage our technology layers to Parse, Enrich and Score both job and candidate data. The platform supports +200 apps, pipelines, and code integrations so you can automate workflows with your favorite tools.
- Our Developers documentation : https://developers.hrflow.ai/
- Our API list (Parsing, Revealing, Embedding, Searching, Scoring, Reasoning) : https://www.hrflow.ai/api
- Our cool demos labs : https://labs.hrflow.ai
[HrFlow.ai](https://hrflow.ai/) is **an API first company that provides the most sophisticated AI-Powered Job & Profile API**. We help HR Tech, Staffing Agencies, and Large employers to thrive in a high-frequency labor market.

**[HrFlow.ai](https://hrflow.ai/) is on a mission to make AI and data integration pipelines a commodity in the HR Industry:**
1. **Unify**: Link your Talent Data channels with a few clicks, so they can share data.
2. **Understand**: Leverage our AI solutions to process your Talent Data.
3. **Automate**: Sync data between your tools and build workflows that meet your business logic.

## :electric_plug: List of Connectors

| Name | Type | Available |
| - | - | - |
| **ADP** | | :hourglass: |
| [**Breezy.hr**](src/hrflow_connectors/connectors/breezyhr) | ATS | :heavy_check_mark: |
| **Cegid (Meta4)** | | :hourglass: |
| [**Ceridian**](src/hrflow_connectors/connectors/ceridian) | HCM |:heavy_check_mark: |
| **Cornerstone OnDemand** | | :hourglass: |
| [**Crosstalent**](src/hrflow_connectors/connectors/crosstalent) | ATS | :heavy_check_mark: |
| **Digitalrecruiters** | ATS | :hourglass: |
| **Fieldglass SAP** | Recruiting software | :hourglass: |
| [**Flatchr**](src/hrflow_connectors/connectors/flatchr/) | ATS | :heavy_check_mark: |
| [**Greenhouse**](src/hrflow_connectors/connectors/greenhouse) | ATS | :heavy_check_mark: |
| **ICIMS** | | :hourglass: |
| **Jobvite** | | :hourglass: |
| **Kronos (UKG)** | | :hourglass: |
| **Laponi** | Job board | :hourglass: |
| **Lever** | | :hourglass: |
| **Mailchimp** | Marketing tools | :hourglass: |
| **Microsoft Dynamics** | HCM CLoud | :hourglass: |
| [**Monster**](src/hrflow_connectors/connectors/monster/) | Job board | :heavy_check_mark: |
| **Oracle** | Cloud Apps | :hourglass: |
| [**Recruitee**](src/hrflow_connectors/connectors/recruitee/) | ATS | :heavy_check_mark: |
| **RecruitBox** | | :hourglass: |
| [**SAPSuccessfactors**](src/hrflow_connectors/connectors/sapsuccessfactors/) | Cloud Apps for HR | :heavy_check_mark: |
| **Salesforce** | | :hourglass: |
| [**Smartrecruiters**](src/hrflow_connectors/connectors/smartrecruiters/) | ATS | :heavy_check_mark: |
| **Staffme** | Job board | :hourglass: |
| [**Taleez**](src/hrflow_connectors/connectors/taleez/)| ATS | :heavy_check_mark: |
| **Talentsoft** | | :hourglass: |
| **Talentlink** | | :hourglass: |
| **Twilio** | Marketing tools | :hourglass: |
| **Ultimate Software (UKG)** | | :hourglass: |
| [**Workable**](src/hrflow_connectors/connectors/workable/) | ATS | :heavy_check_mark: |
| **Workday** | | :hourglass: |
| [**XML**](src/hrflow_connectors/connectors/xml/) | Job board | :heavy_check_mark: |

## 🪄 Quickstart
### What I can do?
With Hrflow Connector, you can **synchronize** and **process** multiple **HR data streams** in just a few lines of code.

You can do 3 types of actions:
* `Job flow` :arrow_right: ***`Hrflow.ai Board`***
* `Profile flow` :arrow_right: ***`Hrflow.ai Source`***
* ***`Hrflow.ai`*** :arrow_right: `External destination`
You can do 4 types of actions:
* Pull jobs : `Job flow` :arrow_right: ***`Hrflow.ai Board`***
* Pull profiles : `Profile flow` :arrow_right: ***`Hrflow.ai Source`***
* Push job : ***`Hrflow.ai Board`*** :arrow_right: `External destination`
* Push profile : ***`Hrflow.ai Source`*** :arrow_right: `External destination`

The features offered by this package:
* **Synchronize an entire data** stream with a ready-to-use solution
Expand All @@ -53,36 +94,18 @@ The features offered by this package:
* [🔑 Get your API Key](https://developers.hrflow.ai/docs/api-authentification)

1. **`pip install hrflow-connectors`**
2. **I configure the connector** that I want to use. Let's take for example Crosstalent [`GetAllJobs`](src/hrflow_connectors/connectors/boards/crosstalent).
2. **Configure the connector**. Let's take for example Greenhouse [Pull jobs](src/hrflow_connectors/connectors/greenhouse).
```python
from hrflow_connectors import Greenhouse
from hrflow import Hrflow

from hrflow_connectors.core.auth import OAuth2PasswordCredentialsBody
from hrflow_connectors.connectors.boards.crosstalent import GetAllJobs

# 2.1 Hrflow client configuration
client = Hrflow(api_secret="MY_X-API-KEY", api_user="MY_X-USER-EMAIL")

# 2.2 Configuring authentication to Crosstalent via the Salesforce API
access_token_url = "https://test.salesforce.com/services/oauth2/token"
auth = OAuth2PasswordCredentialsBody(
access_token_url=access_token_url,
client_id="MY_CLIENT_ID",
client_secret="MY_CLIENT_SECRET",
username="MY_USERNAME",
password="MY_PASSWORD",
)

# 2.3 General connector configuration
action = GetAllJobs(
auth=auth,
subdomain="MY_SUBDOMAIN",
Greenhouse.pull_jobs(
board_token="MY_GREENHOUSE_BOARD_TOKEN",
hrflow_client=client,
board_key="MY_BOARD_KEY",
hydrate_with_parsing=True,
board_key="MY_HRFLOW_BOARD_KEY"
)
```
3. I write the line of code `action.execute()` to **run the connector.**

🐇 **TADA! You have just called your first connector.**

Expand All @@ -98,68 +121,9 @@ The project mainly uses 4 packages :
* `requests=="2.26.0"`
* `hrflow=="1.9.0"`
* `pydantic=="1.7.4"`
* `selenium=="3.141.0"`

**To find the list of dependencies, you can look at the [`pyproject.toml`](pyproject.toml) file**

## :electric_plug: List of Connectors
- **ADP** (soon)
- **Craigslist** : [`CraigslistFeed`](src/hrflow_connectors/connectors/boards/craigslist/)
- **Careerbuilder** [`CareerBuilderFeed`](src/hrflow_connectors/connectors/boards/careerbuilder)
- **Cegid(Meta4)** (soon)
- **Ceridian** [`PullJobs`](src/hrflow_connectors/connectors/boards/ceridian)
- **Cornerstone OnDemand** (soon)
- **Crosstalent** : [`GetAllJobs`](src/hrflow_connectors/connectors/boards/crosstalent), [`PushProfile`](src/hrflow_connectors/connectors/destinations/crosstalent)
- **Digitalrecruiters** (soon)
- **Flatchr** : [`PushProfile`](src/hrflow_connectors/connectors/destinations/flatchr/), [`EnrichProfile`](src/hrflow_connectors/connectors/destinations/flatchr/)
- **Greenhouse** : [`GetAllJobs`](src/hrflow_connectors/connectors/boards/greenhouse), [`PushProfile`](src/hrflow_connectors/connectors/destinations/greenhouse)
- **Indeed** : [`IndeedFeed`](src/hrflow_connectors/connectors/boards/indeed)
- **Kronos(UKG)** (soon)
- **Laponi** (soon)
- **Lever** (soon)
- **Mailchimp** (soon)
- **Monster** : [`PushJob`](src/hrflow_connectors/connectors/boards/monster), [`PullProfile`](src/hrflow_connectors/connectors/destinations/monster)
- **Oracle** (soon)
- **Recruitee** : [`PullJobs`](src/hrflow_connectors/connectors/boards/recruitee), [`PushProfile`](src/hrflow_connectors/connectors/destinations/recruitee)
- **SAP Successfactors** [`PullJobs`](src/hrflow_connectors/connectors/boards/sapsuccessfactors), [`PushProfile`](src/hrflow_connectors/connectors/destinations/sapsuccessfactors)
- **Salesforce** (soon)
- **Smartrecruiters** : [`GetAllJobs`](src/hrflow_connectors/connectors/boards/smartrecruiters/), [`PushProfile`](src/hrflow_connectors/connectors/destinations/smartrecruiters)
- **Staffme** (soon)
- **Talentsoft** (soon)
- **Twilio** (soon)
- **Ultimate Software(UKG)** (soon)
- **Workable** : [`PullJobs`](src/hrflow_connectors/connectors/boards/workable)
- **Workday** (soon)

## 🧐 What's inside?
**A quick look at the project structure.**

* **`legacy/`** : Folder containing the old code snippets that we used to connect the data streams in the workflows
* **`src/hrflow_connectors/connectors/`** : Folder containing the connectors sorted according to the type of their actions
* **`boards/`** : `Job flow` :arrow_right: ***`Hrflow.ai Board`*** Folder containing the set of connectors that synchronise the job stream in a ***Hrflow.ai Board***.
* **`ConnectorName/`** : Connector folder named `ConnectorName`.
* **`actions.py`** : File containing all the actions of a connector.
* **`spec.py`** : File listing the available actions and the particularities of the connector (version, ...)
* **`README.md`** : File documenting the use of the connector.
* **`sources/`** : `Profile flow` :arrow_right: ***`Hrflow.ai Source`*** Folder containing the set of connectors that synchronise the profile stream in a ***Hrflow.ai Source***. The architecture is the same as for `boards/`.
* **`destinations/`** : ***`Hrflow.ai`*** :arrow_right: `External destination` Folder containing all the connectors that export talent data from Hrflow to an external destination. The architecture is the same as for `boards/`.
* **`src/hrflow_connectors/core/`** : Containing the core of the connectors shared by all.
* **`src/hrflow_connectors/utils/`** : Containing the useful out-of-context functions of the package.
* **`tests/`** : Folder containing all unit and functional tests of the project.
* **`.coveragerc`** : Configuration file for evaluating test coverage with `pytest-cov`.
* **`.gitignore`** : This file tells git which files it should not track / not maintain a version history for.
* **`AUTHORS.md`** : File listing the authors who participated in the project code.
* **`CHANGELOG.md`** : File listing the changes made for each version.
* **`CONTRIBUTING.md`** : File describing how to participate in the project.
* **`LICENSE`** : Project license.
* **`README.md`**: A text file containing useful reference information about this project.
* **`VERSION`** : File containing the project version.
* **`poetry.lock`** : File containing the exact versions of the dependencies to ensure that the package versions are consistent for everyone working on your project.
* **`pyproject.toml`** : File that orchestrates the project and its dependencies.
* **`pytest.ini`** : The main configuration file of pytest, which can change the running mode of pytest.
* **`setup.cfg`** : A Python package that supports providing all of a Python distribution's metadata and build configuration rather than in the `setup.py` script.
* **`setup.py`** : The minimal setup.py which calls the configuration in `setup.cfg`.

## :woman_technologist: Contributions

Please feel free to contribute to the quality of this content by
Expand All @@ -170,7 +134,11 @@ appreciated.

👉 **To find out more about how to proceed, the rules and conventions to follow, read carefully [`CONTRIBUTING.md`](CONTRIBUTING.md).**

## 🔗 Resources
* Our Developers documentation : https://developers.hrflow.ai/
* Our API list (Parsing, Revealing, Embedding, Searching, Scoring, Reasoning) : https://www.hrflow.ai/api
* Our cool demos labs : https://labs.hrflow.ai

## :page_with_curl: License

See the [`LICENSE`](LICENSE) file for licensing information.
See the [`LICENSE`](LICENSE) file for licensing information.
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.2.0
1.0.0
Loading

0 comments on commit f05fe6b

Please sign in to comment.