holiday_api_checker.py
· 4.8 KiB · Python
Surowy
import requests
import os
import json
class HolidayAPI:
def __init__(self, base_url, cache_dir="cache"):
"""
Initialize the HolidayAPI class.
:param base_url: The base URL for the API endpoint.
:param cache_dir: Directory to store cached data.
"""
self.base_url = base_url
self.cached_holidays = {}
self.cache_dir = cache_dir
if not os.path.exists(self.cache_dir):
os.makedirs(self.cache_dir)
def _get_cache_path(self, page, size):
"""
Generate the cache file path for a given page and size.
:param page: The page number.
:param size: The size of the page.
:return: Path to the cache file.
"""
return os.path.join(self.cache_dir, f"holidays_page{page}_size{size}.json")
def get_holidays(self, page=0, size=10):
"""
Fetch holiday data from the API or cache.
:param page: The page number to fetch.
:param size: The number of records per page.
:return: A list of holiday data dictionaries.
"""
cache_path = self._get_cache_path(page, size)
if os.path.exists(cache_path):
with open(cache_path, "r", encoding="utf-8") as cache_file:
return json.load(cache_file)
url = f"{self.base_url}?page={page}&size={size}"
headers = {
'accept': 'application/json'
}
response = requests.get(url, headers=headers)
if response.status_code == 200:
data = response.json()
with open(cache_path, "w", encoding="utf-8") as cache_file:
json.dump(data, cache_file, ensure_ascii=False, indent=4)
return data
else:
response.raise_for_status()
def get_holidays_by_year(self, year):
"""
Fetch holiday data for a specific year.
If the data is already cached, it returns from the cache.
:param year: The year for which to fetch holidays.
:return: A list of holiday data dictionaries for the given year.
"""
if year in self.cached_holidays:
return self.cached_holidays[year]
all_holidays = []
page = 0
while True:
data = self.get_holidays(page=page, size=100)
if not data:
break
all_holidays.extend(data)
page += 1
filtered_holidays = [
holiday for holiday in all_holidays
if holiday.get("year") == str(year) and holiday.get("date")[4:] != "0903"
]
self.cached_holidays[year] = filtered_holidays
return filtered_holidays
def is_holiday(self, date):
"""
Check if a specific date is a holiday.
:param date: The date to check in YYYYMMDD format.
:return: True if the date is a holiday, False otherwise.
"""
year = date[:4]
if year not in self.cached_holidays:
self.get_holidays_by_year(year)
for holiday in self.cached_holidays[year]:
if holiday.get("date") == date and holiday.get("isholiday") == "是":
return True
return False
class Holiday:
def __init__(self, date, year, name, isholiday, holidaycategory, description):
"""
Represent a single holiday entry.
:param date: The date of the holiday in YYYYMMDD format.
:param year: The year of the holiday.
:param name: The name of the holiday (if any).
:param isholiday: Whether it is a holiday ('是' or '否').
:param holidaycategory: The category of the holiday.
:param description: The description of the holiday.
"""
self.date = date
self.year = year
self.name = name
self.isholiday = isholiday
self.holidaycategory = holidaycategory
self.description = description
def __repr__(self):
return f"Holiday(date={self.date}, year={self.year}, name={self.name}, " \
f"isholiday={self.isholiday}, holidaycategory={self.holidaycategory}, " \
f"description={self.description})"
# Example usage
if __name__ == "__main__":
api = HolidayAPI("https://data.ntpc.gov.tw/api/datasets/308dcd75-6434-45bc-a95f-584da4fed251/json")
holidays_2025 = api.get_holidays_by_year(2025)
holidays = []
for entry in holidays_2025:
holiday = Holiday(
date=entry.get("date"),
year=entry.get("year"),
name=entry.get("name"),
isholiday=entry.get("isholiday"),
holidaycategory=entry.get("holidaycategory"),
description=entry.get("description")
)
holidays.append(holiday)
for holiday in holidays:
print(holiday)
# Check if a specific date is a holiday
specific_date = "20250102"
print(f"Is {specific_date} a holiday? {api.is_holiday(specific_date)}")
| 1 | import requests |
| 2 | import os |
| 3 | import json |
| 4 | |
| 5 | class HolidayAPI: |
| 6 | def __init__(self, base_url, cache_dir="cache"): |
| 7 | """ |
| 8 | Initialize the HolidayAPI class. |
| 9 | :param base_url: The base URL for the API endpoint. |
| 10 | :param cache_dir: Directory to store cached data. |
| 11 | """ |
| 12 | self.base_url = base_url |
| 13 | self.cached_holidays = {} |
| 14 | self.cache_dir = cache_dir |
| 15 | if not os.path.exists(self.cache_dir): |
| 16 | os.makedirs(self.cache_dir) |
| 17 | |
| 18 | def _get_cache_path(self, page, size): |
| 19 | """ |
| 20 | Generate the cache file path for a given page and size. |
| 21 | :param page: The page number. |
| 22 | :param size: The size of the page. |
| 23 | :return: Path to the cache file. |
| 24 | """ |
| 25 | return os.path.join(self.cache_dir, f"holidays_page{page}_size{size}.json") |
| 26 | |
| 27 | def get_holidays(self, page=0, size=10): |
| 28 | """ |
| 29 | Fetch holiday data from the API or cache. |
| 30 | :param page: The page number to fetch. |
| 31 | :param size: The number of records per page. |
| 32 | :return: A list of holiday data dictionaries. |
| 33 | """ |
| 34 | cache_path = self._get_cache_path(page, size) |
| 35 | if os.path.exists(cache_path): |
| 36 | with open(cache_path, "r", encoding="utf-8") as cache_file: |
| 37 | return json.load(cache_file) |
| 38 | |
| 39 | url = f"{self.base_url}?page={page}&size={size}" |
| 40 | headers = { |
| 41 | 'accept': 'application/json' |
| 42 | } |
| 43 | response = requests.get(url, headers=headers) |
| 44 | |
| 45 | if response.status_code == 200: |
| 46 | data = response.json() |
| 47 | with open(cache_path, "w", encoding="utf-8") as cache_file: |
| 48 | json.dump(data, cache_file, ensure_ascii=False, indent=4) |
| 49 | return data |
| 50 | else: |
| 51 | response.raise_for_status() |
| 52 | |
| 53 | def get_holidays_by_year(self, year): |
| 54 | """ |
| 55 | Fetch holiday data for a specific year. |
| 56 | If the data is already cached, it returns from the cache. |
| 57 | :param year: The year for which to fetch holidays. |
| 58 | :return: A list of holiday data dictionaries for the given year. |
| 59 | """ |
| 60 | if year in self.cached_holidays: |
| 61 | return self.cached_holidays[year] |
| 62 | |
| 63 | all_holidays = [] |
| 64 | page = 0 |
| 65 | while True: |
| 66 | data = self.get_holidays(page=page, size=100) |
| 67 | if not data: |
| 68 | break |
| 69 | all_holidays.extend(data) |
| 70 | page += 1 |
| 71 | |
| 72 | filtered_holidays = [ |
| 73 | holiday for holiday in all_holidays |
| 74 | if holiday.get("year") == str(year) and holiday.get("date")[4:] != "0903" |
| 75 | ] |
| 76 | self.cached_holidays[year] = filtered_holidays |
| 77 | return filtered_holidays |
| 78 | |
| 79 | def is_holiday(self, date): |
| 80 | """ |
| 81 | Check if a specific date is a holiday. |
| 82 | :param date: The date to check in YYYYMMDD format. |
| 83 | :return: True if the date is a holiday, False otherwise. |
| 84 | """ |
| 85 | year = date[:4] |
| 86 | if year not in self.cached_holidays: |
| 87 | self.get_holidays_by_year(year) |
| 88 | |
| 89 | for holiday in self.cached_holidays[year]: |
| 90 | if holiday.get("date") == date and holiday.get("isholiday") == "是": |
| 91 | return True |
| 92 | return False |
| 93 | |
| 94 | class Holiday: |
| 95 | def __init__(self, date, year, name, isholiday, holidaycategory, description): |
| 96 | """ |
| 97 | Represent a single holiday entry. |
| 98 | :param date: The date of the holiday in YYYYMMDD format. |
| 99 | :param year: The year of the holiday. |
| 100 | :param name: The name of the holiday (if any). |
| 101 | :param isholiday: Whether it is a holiday ('是' or '否'). |
| 102 | :param holidaycategory: The category of the holiday. |
| 103 | :param description: The description of the holiday. |
| 104 | """ |
| 105 | self.date = date |
| 106 | self.year = year |
| 107 | self.name = name |
| 108 | self.isholiday = isholiday |
| 109 | self.holidaycategory = holidaycategory |
| 110 | self.description = description |
| 111 | |
| 112 | def __repr__(self): |
| 113 | return f"Holiday(date={self.date}, year={self.year}, name={self.name}, " \ |
| 114 | f"isholiday={self.isholiday}, holidaycategory={self.holidaycategory}, " \ |
| 115 | f"description={self.description})" |
| 116 | |
| 117 | # Example usage |
| 118 | if __name__ == "__main__": |
| 119 | api = HolidayAPI("https://data.ntpc.gov.tw/api/datasets/308dcd75-6434-45bc-a95f-584da4fed251/json") |
| 120 | holidays_2025 = api.get_holidays_by_year(2025) |
| 121 | |
| 122 | holidays = [] |
| 123 | for entry in holidays_2025: |
| 124 | holiday = Holiday( |
| 125 | date=entry.get("date"), |
| 126 | year=entry.get("year"), |
| 127 | name=entry.get("name"), |
| 128 | isholiday=entry.get("isholiday"), |
| 129 | holidaycategory=entry.get("holidaycategory"), |
| 130 | description=entry.get("description") |
| 131 | ) |
| 132 | holidays.append(holiday) |
| 133 | |
| 134 | for holiday in holidays: |
| 135 | print(holiday) |
| 136 | |
| 137 | # Check if a specific date is a holiday |
| 138 | specific_date = "20250102" |
| 139 | print(f"Is {specific_date} a holiday? {api.is_holiday(specific_date)}") |
| 140 | |
| 141 |