123 lines
4.2 KiB
Python
123 lines
4.2 KiB
Python
"""
|
|
ETimeOfficeAPI Class for interacting with the ETimeOffice API.
|
|
|
|
This module provides an interface to interact with the ETimeOffice API.
|
|
It includes methods to fetch punch data, validate dates, and convert response data
|
|
into Python datetime objects for further processing.
|
|
"""
|
|
|
|
from datetime import datetime
|
|
|
|
import requests
|
|
from requests.auth import HTTPBasicAuth
|
|
|
|
|
|
class ETimeOfficeAPI:
|
|
"""
|
|
A client for interacting with the ETimeOffice API to fetch punch data and related information.
|
|
"""
|
|
|
|
def __init__(self, username, password, base_url="https://api.etimeoffice.com/api/"):
|
|
"""
|
|
Initialize the ETimeOfficeAPI client.
|
|
"""
|
|
self.username = username
|
|
self.password = password
|
|
self.base_url = base_url.rstrip("/") + "/"
|
|
|
|
def _is_valid_date(self, date_str, with_time=True):
|
|
"""
|
|
Validate date format.
|
|
"""
|
|
try:
|
|
if with_time:
|
|
datetime.strptime(date_str, "%d/%m/%Y_%H:%M")
|
|
else:
|
|
datetime.strptime(date_str, "%d/%m/%Y")
|
|
return True
|
|
except ValueError:
|
|
return False
|
|
|
|
def _convert_punch_dates(self, response_data):
|
|
"""
|
|
Convert punch data strings into datetime objects.
|
|
"""
|
|
if not response_data.get("Error", True):
|
|
if "PunchData" in response_data:
|
|
for punch in response_data["PunchData"]:
|
|
try:
|
|
punch["PunchDate"] = datetime.strptime(
|
|
punch["PunchDate"], "%d/%m/%Y %H:%M:%S"
|
|
)
|
|
except ValueError:
|
|
pass
|
|
if "InOutPunchData" in response_data:
|
|
for punch in response_data["InOutPunchData"]:
|
|
try:
|
|
punch["DateString"] = datetime.strptime(
|
|
punch["DateString"], "%d/%m/%Y"
|
|
).date()
|
|
except ValueError:
|
|
pass
|
|
try:
|
|
punch["INTime"] = datetime.strptime(
|
|
punch["INTime"], "%H:%M"
|
|
).time()
|
|
except:
|
|
pass
|
|
try:
|
|
punch["OUTTime"] = datetime.strptime(
|
|
punch["OUTTime"], "%H:%M"
|
|
).time()
|
|
except:
|
|
pass
|
|
return response_data
|
|
|
|
def _fetch_data(self, endpoint, emp_code, from_date, to_date, with_time=True):
|
|
"""
|
|
Make an authenticated API request and parse punch data.
|
|
"""
|
|
if not (
|
|
self._is_valid_date(from_date, with_time)
|
|
and self._is_valid_date(to_date, with_time)
|
|
):
|
|
return {
|
|
"Error": True,
|
|
"Msg": "Error: Invalid date format. Expected format: "
|
|
+ ("DD/MM/YYYY_HH:MM" if with_time else "DD/MM/YYYY"),
|
|
}
|
|
|
|
url = f"{self.base_url}{endpoint}?Empcode={emp_code}&FromDate={from_date}&ToDate={to_date}"
|
|
response = requests.get(
|
|
url, auth=HTTPBasicAuth(self.username, self.password), timeout=20
|
|
)
|
|
return self._convert_punch_dates(response.json())
|
|
|
|
def download_punch_data(self, from_date, to_date, emp_code="ALL"):
|
|
"""
|
|
Download punch data with timestamps.
|
|
"""
|
|
return self._fetch_data(
|
|
"DownloadPunchData", emp_code, from_date, to_date, with_time=True
|
|
)
|
|
|
|
def download_punch_data_mcid(self, from_date, to_date, emp_code="ALL"):
|
|
"""
|
|
Download punch data with MCID (Machine Code ID).
|
|
"""
|
|
return self._fetch_data(
|
|
"DownloadPunchDataMCID", emp_code, from_date, to_date, with_time=True
|
|
)
|
|
|
|
def download_in_out_punch_data(self, from_date, to_date, emp_code="ALL"):
|
|
"""
|
|
Download in and out punch data (without timestamps).
|
|
"""
|
|
return self._fetch_data(
|
|
"DownloadInOutPunchData", emp_code, from_date, to_date, with_time=False
|
|
)
|
|
|
|
|
|
# api = ETimeOfficeAPI(username={corporateid}:{usename}:{password}:true",password="")
|
|
# response = api.download_punch_data(from_date="25/03/2025_00:00",to_date="25/03/2025_12:22")
|