-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* bambbo sdk base api class * minor change * minor changes * comment resolve * resolved comments * added new methods * added 201 status code * class to sync employees from bamboo hr (#98) * class to sync employees from bamboo hr * bug fix * minor changes * comment resolved * minor changes * Bamboo sdk class (#99) * bamboo sdk class * comment resolved * Webhook create and delete API (#108) * webhook api added * indentation fixed * indentaion fixed * minor fix * Fields get API (#109) * Fields get API * added timeoff instead of fields and tested
- Loading branch information
1 parent
73ff29e
commit 6fd47e9
Showing
8 changed files
with
250 additions
and
0 deletions.
There are no files selected for viewing
Empty file.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
import requests | ||
import base64 | ||
import json | ||
from bamboosdk.exceptions import * | ||
|
||
class ApiBase: | ||
""" | ||
Base class for all API classes | ||
""" | ||
API_BASE_URL = 'https://api.bamboohr.com/api/gateway.php/{}' | ||
|
||
def __init__(self) -> None: | ||
self.__api_token = None | ||
self.__sub_domain = None | ||
self.headers = None | ||
|
||
def _get_request(self, module_api_path): | ||
""" | ||
HTTP get method get data from BambooHR API URL | ||
Parameters: | ||
module_api_path (str): URL of BambooHR API | ||
""" | ||
|
||
url = self.API_BASE_URL.format(self.__sub_domain) + module_api_path | ||
response = requests.get(url=url, headers=self.headers) | ||
if response.status_code == 200: | ||
result = json.loads(response.text) | ||
return result | ||
|
||
if response.status_code == 403: | ||
error_msg = json.loads(response.text) | ||
raise NoPrivilegeError('Forbidden, the user has insufficient privilege', error_msg) | ||
|
||
if response.status_code == 404: | ||
error_msg = json.loads(response.text) | ||
raise NotFoundItemError('Not found item with ID', error_msg) | ||
|
||
if response.status_code == 401: | ||
error_msg = 'The api token is invalid' | ||
raise InvalidTokenError('Invalid token, try to refresh it', error_msg) | ||
|
||
else: | ||
error_msg = json.loads(response.text) | ||
raise BambooHrSDKError('Status code {0}'.format(response.status_code), error_msg) | ||
|
||
|
||
def _post_request(self, module_api_path, payload): | ||
""" | ||
HTTP post method to send data to BambooHR API URL | ||
Parameters: | ||
payload (dict): Data to be sent to Bamboo API | ||
module_api_path (str): URL of BambooHR API | ||
""" | ||
|
||
url= self.API_BASE_URL.format(self.__sub_domain) + module_api_path | ||
response = requests.post(url=url, json=payload, headers=self.headers) | ||
if response.status_code == 200: | ||
result = json.loads(response.text) | ||
return result | ||
|
||
if response.status_code == 201: | ||
result = json.loads(response.text) | ||
return result | ||
|
||
if response.status_code == 403: | ||
error_msg = json.loads(response.text) | ||
raise NoPrivilegeError('Forbidden, the user has insufficient privilege', error_msg) | ||
|
||
if response.status_code == 404: | ||
error_msg = json.loads(response.text) | ||
raise NotFoundItemError('Not found item with ID', error_msg) | ||
|
||
if response.status_code == 401: | ||
error_msg = 'The api token is invalid' | ||
raise InvalidTokenError('Invalid token, try to refresh it', error_msg) | ||
|
||
else: | ||
error_msg = json.loads(response.text) | ||
raise BambooHrSDKError('Status code {0}'.format(response.status_code), error_msg) | ||
|
||
def _delete_request(self, module_api_path): | ||
""" | ||
HTTP delete method to delete resource on BambooHR | ||
Parameters: | ||
module_api_path (str): URL of BambooHR API | ||
""" | ||
url= self.API_BASE_URL.format(self.__sub_domain) + module_api_path | ||
response = requests.delete(url=url, headers=self.headers) | ||
if response.status_code == 200: | ||
result = json.loads(response.text) | ||
return result | ||
|
||
if response.status_code == 403: | ||
error_msg = json.loads(response.text) | ||
raise NoPrivilegeError('Forbidden, the user has insufficient privilege', error_msg) | ||
|
||
if response.status_code == 404: | ||
error_msg = json.loads(response.text) | ||
raise NotFoundItemError('Not found item with ID', error_msg) | ||
|
||
if response.status_code == 401: | ||
error_msg = 'The api token is invalid' | ||
raise InvalidTokenError('Invalid token, try to refresh it', error_msg) | ||
|
||
else: | ||
error_msg = json.loads(response.text) | ||
raise BambooHrSDKError('Status code {0}'.format(response.status_code), error_msg) | ||
|
||
def __encode_username_password(self): | ||
""" | ||
Utility method to be used in the header for authorization | ||
converts the api token and password to base64 | ||
""" | ||
|
||
payload = f'{self.__api_token}:a' | ||
payload = payload.encode() | ||
|
||
return base64.b64encode(payload).decode() | ||
|
||
def set_api_token(self, api_token): | ||
self.__api_token = api_token | ||
|
||
self.headers = { | ||
'Accept': 'application/json', | ||
'content-type': 'application/json', | ||
'authorization': f'Basic {self.__encode_username_password()}' | ||
} | ||
|
||
def set_sub_domain(self, sub_domain): | ||
self.__sub_domain = sub_domain |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
from .api_base import ApiBase | ||
|
||
|
||
class Employee(ApiBase): | ||
|
||
GET_EMPLOYEE_REPORT = '/v1/reports/custom?format=JSON&onlyCurrent=false' | ||
payload = { "fields": ["displayName", "firstName", "lastName", "department", "workEmail", "supervisorEmail", "status"] } | ||
|
||
def get_all(self): | ||
"""Get the list of employees from bambooHr | ||
Returns: | ||
List with dicts in Employee schema. | ||
""" | ||
return self._post_request(self.GET_EMPLOYEE_REPORT, payload=self.payload) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
from .api_base import ApiBase | ||
|
||
class TimeOff(ApiBase): | ||
CHECK_URL = '/v1/meta/time_off/types/' | ||
|
||
def get(self): | ||
""" | ||
Get method to get the different fields, | ||
used here for checking connection. | ||
Returns: | ||
""" | ||
return self._get_request(self.CHECK_URL) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
from .api_base import ApiBase | ||
|
||
|
||
class Webhook(ApiBase): | ||
""" Class for webhook APIs for bamboohr """ | ||
|
||
POST_WEBHOOK = '/v1/webhooks/' | ||
DELETE_WEBHOOK = '/v1/webhooks/{}' | ||
|
||
def post(self, payload): | ||
""" | ||
Post webhook url to bamboohr for employee update or create | ||
Returns: | ||
""" | ||
return self._post_request(self.POST_WEBHOOK, payload) | ||
|
||
def delete(self, id): | ||
""" | ||
Delete Webhook | ||
Returns: | ||
""" | ||
return self._delete_request(self.DELETE_WEBHOOK.format(id)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
from .api.employee import Employee | ||
from .api.webhook import Webhook | ||
from .api.time_off import TimeOff | ||
|
||
class BambooHrSDK: | ||
""" | ||
Creates connection with BambooHr APIs | ||
Parameters: | ||
api_token (str): API token for BambooHr | ||
sub_domain (str): Sub domain of the user in BambooHr | ||
""" | ||
|
||
def __init__(self, api_token: str, sub_domain: str): | ||
self.__api_token = api_token | ||
self.__sub_domain = sub_domain | ||
|
||
self.employees = Employee() | ||
self.webhook = Webhook() | ||
self.time_off = TimeOff() | ||
|
||
self.set_api_token() | ||
self.set_sub_domain() | ||
|
||
def set_api_token(self): | ||
""" | ||
Set the api token for all the APIs | ||
""" | ||
self.employees.set_api_token(self.__api_token) | ||
self.webhook.set_api_token(self.__api_token) | ||
self.time_off.set_api_token(self.__api_token) | ||
|
||
def set_sub_domain(self): | ||
""" | ||
Set sub domain for all the APIs | ||
""" | ||
self.employees.set_sub_domain(self.__sub_domain) | ||
self.webhook.set_sub_domain(self.__sub_domain) | ||
self.time_off.set_sub_domain(self.__sub_domain) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
""" | ||
BambooHR SDK exceptions | ||
""" | ||
|
||
|
||
class BambooHrSDKError(Exception): | ||
""" | ||
The base exception class for BambooHR SDK | ||
""" | ||
|
||
def __init__(self, msg, response=None): | ||
super(BambooHrSDKError, self).__init__(msg) | ||
self.message = msg | ||
self.response = response | ||
|
||
def __str__(self): | ||
return repr(self.message) | ||
|
||
|
||
class NoPrivilegeError(BambooHrSDKError): | ||
"""The user has insufficient privilege, 403 error.""" | ||
|
||
class NotFoundItemError(BambooHrSDKError): | ||
"""Not found the item from URL, 404 error.""" | ||
|
||
class InvalidTokenError(BambooHrSDKError): | ||
"""Invalid or non-existing access token, 401 error""" | ||
|
||
class InternalServerError(BambooHrSDKError): | ||
"""Internal server error, 500 error""" |