-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbamboohr_fetch.py
143 lines (117 loc) · 4.65 KB
/
bamboohr_fetch.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
import os
import json
import base64
import requests
from datetime import datetime
from dotenv import load_dotenv
from common.logger import setup_logger
logger = setup_logger()
def fetch_bamboo_users():
"""Fetch active users from BambooHR and save them to a JSON file."""
try:
load_dotenv()
# Get environment variables
subdomain = os.getenv('BAMBOOHR_SUBDOMAIN')
api_key = os.getenv('BAMBOOHR_API_KEY')
# Get exclude filter configuration
exclude_filter_str = os.getenv('BAMBOOHR_EXCLUDE_FILTER')
exclude_filter = None
if exclude_filter_str:
try:
exclude_filter = json.loads(exclude_filter_str)
except json.JSONDecodeError:
logger.warning("Invalid BAMBOOHR_EXCLUDE_FILTER format, filter will be skipped")
if not all([subdomain, api_key]):
raise ValueError("Missing required environment variables")
# Setup authentication and headers
auth_string = base64.b64encode(f"{api_key}:x".encode()).decode()
headers = {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': f'Basic {auth_string}'
}
# BambooHR API endpoint for employee dataset
url = f'https://api.bamboohr.com/api/gateway.php/{subdomain}/v1/datasets/employee'
# Prepare base filters
base_filters = [
{
"field": "employmentStatus",
"operator": "does_not_include",
"value": ["Terminated"]
},
{
"field": "status",
"operator": "does_not_include",
"value": ["Inactive"]
}
]
# Add exclude filter if configured
if exclude_filter:
base_filters.insert(0, exclude_filter)
logger.info("Using exclude filter from configuration")
# Prepare base fields
fields = [
"employeeNumber",
"name",
"email",
"jobInformationDepartment",
"jobInformationDivision",
"isSupervisor",
"supervisorId"
]
# Prepare request payload
payload = {
"filters": {
"match": "all",
"filters": base_filters
},
"fields": fields
}
logger.info("Fetching employees from BambooHR...")
all_employees = []
current_page = 1
while True:
# Add pagination parameters to payload
payload['page'] = current_page
# Get employees for current page
response = requests.post(url, headers=headers, json=payload)
response.raise_for_status()
data = response.json()
employees = data.get('data', [])
pagination = data.get('pagination', {})
all_employees.extend(employees)
# Check if there are more pages
if not pagination.get('next_page'):
break
current_page += 1
logger.info(f"Fetching page {current_page}...")
# Transform to our schema
users = []
for emp in all_employees:
# Join department and division with a forward slash if both exist
department = emp.get('jobInformationDepartment', '')
division = emp.get('jobInformationDivision', '')
combined_department = f"{department}/{division}" if department and division else department or division or ''
user = {
"external_id": emp.get('employeeNumber'),
"name": emp.get('name', '').strip(),
"email": emp.get('email'),
"department": combined_department,
"status": "active",
"supervisor_id": emp.get('supervisorId', '')
}
users.append(user)
# Prepare output data
output_data = {"users": users}
# Save to file in main directory
with open("users.json", 'w') as f:
json.dump(output_data, f, indent=2)
logger.info(f"Successfully saved {len(users)} users to users.json")
except requests.exceptions.RequestException as e:
logger.error(f"Error fetching BambooHR users: {str(e)}")
raise
except Exception as e:
logger.error(f"Error processing BambooHR users: {str(e)}")
raise
if __name__ == "__main__":
fetch_bamboo_users()