📆

Python + requests + Google Calendar APIによる日本の祝日を取得サンプル

こんにちは!TRUSTARTの片ノ坂です!
8月に入りましたね。夏休みシーズンが到来しました🏖️ 皆さん、夏休みの予定はもう立てられましたか?📅
筆者はバンド音楽が好きなのでSummer Sonicに行きたいなーって漠然と思ってます🎵出費はかさみますが、大阪万博にも行ってみたいですね!💸

さて、今回はPythonとrequestsを用いてGoogle Calendar APIを実行して日本の祝日を取得する実装について共有します!

執筆のきっかけ

お休みの計画を立てる際に重要な祝日の情報、それをシステムで扱おうと思うと意外と大変ですよね?祝日情報の収集について、いくつかの実装パターンを簡単にではありますが以下に整理してみました。

  • 標準ライブラリ
    • そもそも対応していない😢
  • サードパーティライブラリ
    • ライブラリ側でカレンダー情報はメンテナンスしてくれる
      • ただし、実装の仕方次第ではカレンダー情報の反映の都合でバージョンアップになるケースもあり得る
    • バージョンアップ時に仕様変更がある場合は対応が必要になる
  • 外部ファイル・データベースのテーブル
    • カレンダー情報やインターフェースを開発側で制御可能
    • そのトレードオフとして、毎年や制度変更の際にファイル・テーブルの保守作業が発生する
  • 外部APIサービス ← 今回選択
    • サービス側でカレンダー情報はメンテナンスしてくれる
      • 祝日の急な変更があっても次回取得時に更新されているので実装の修正は起きづらい
      • ただし、利用者側でキャッシュしているならキャッシュのリフレッシュが必要
    • サービス側の仕様変更に追従しなければならない
    • APIキーの管理作業が増える

不動産登記情報を中心としたビッグデータの収集・提供を行う当社のSaaS製品R.E.DATA Plusでも祝日の情報をシステムで利用しています。これらの状況を鑑み、当社サービスで実装する際に、私は外部APIサービスとしてGoogle Calendar APIを使う方法を選択しました。なお、Google Calendar APIを選んだのはすぐに使用できるためです。すでにR.E.DATA PlusではGoogle Maps APIを使用していた為、Google CloudのAPIキーが存在しており、そのキーに権限を付与するだけでGoogle Calendar APIが使用できました。

実装しようとした際、google-api-client を利用する実装例が多く、requests を使う例があまり見当たりませんでした。私の検索能力不足かもしれませんが。
やりたい事に対してわざわざライブラリを入れるのは少し大袈裟ですし、外部APIサービスのメリットを若干損なうと感じました。「どうにか単純なHTTPリクエストのみで完結できないものか?」と試行錯誤した結果を今回は共有したいと思います。少しでも読者の皆さんのお役に立てますと幸いです。

事前準備

APIキーの調達

Google Calendar APIを使うためには利用権限が付与されたGoogle Cloudで発行されたAPIキーが必要になります。Google CloudでAPIキーを発行する手順については割愛します。発行済みAPIキーがある場合、2025年8月現在は以下の流れで権限付与が可能です。

  1. Google Cloudコンソールを開く
  2. APIキーが存在するプロジェクトを開く
  3. [APIとサービス]を開く
  4. 左ペインの一覧から[認証情報]を開く
  5. 権限を付与したいAPIキーを選択する
  6. [APIの制限]の選択ボックスにて[Google Calendar API]にチェックを入れる
  7. [保存]ボタンを押下する

実行環境の用意

Pythonのバージョンは3.10、requestsのバージョンは2.32.3で動作確認しています!
Pythonのインストールはmiseやasdfといったランタイム管理ツールを、ライブラリについてはuvのようなパッケージ管理ツールを、それぞれ使ってインストールすることをおすすめします!その方がローカル環境を汚さずに済みますので!

サンプル実装

必須の環境変数としてGOOGLE_API_KEY、任意でLOG_LEVELを設けています。事前に準備したAPIキーを環境変数GOOGLE_API_KEYに設定してください!
カレンダーIDは、Googleが公開する日本の祝日に関するカレンダーのIDです。
Google Calendar APIへのリクエストのパラメータについてはこちらを参照されるとよく理解できるかと思います。

import logging
import os
import requests

from datetime import datetime
from zoneinfo import ZoneInfo

logger = logging.getLogger(__name__)
logger.setLevel(os.getenv("LOG_LEVEL", "INFO"))


def get_jp_holiday_calendar(year: int) -> dict:
    """GoogleカレンダーAPIを使用して日本の祝日カレンダーを取得する

    Args:
        year (int): 取得する年

    Returns:
        dict: GoogleカレンダーAPIのレスポンス(https://developers.google.com/calendar/api/v3/reference/events/list?hl=ja#response)
    """
    TIME_ZONE_ASIA_TOKYO = "Asia/Tokyo"
    if not (api_key := os.getenv("GOOGLE_API_KEY")):
        logger.warning("APIキーが環境変数GOOGLE_API_KEYに設定されていません")

    JP_HOLIDAY_CALENDAR_ID = "ja.japanese.official%23holiday%40group.v.calendar.google.com"

    url = f"https://www.googleapis.com/calendar/v3/calendars/{JP_HOLIDAY_CALENDAR_ID}/events"
    params = {
        "timeMin": datetime(year, 1, 1, tzinfo=ZoneInfo(TIME_ZONE_ASIA_TOKYO)).isoformat(),
        "timeMax": datetime(year, 12, 31, 23, 59, 59, tzinfo=ZoneInfo(TIME_ZONE_ASIA_TOKYO)).isoformat(),
        "timeZone": TIME_ZONE_ASIA_TOKYO,
        "singleEvents": True,
        "orderBy": "startTime",
        "key": api_key,
    }

    try:
        response = requests.get(url, params=params)
    except Exception as e:
        logger.warning(f"Google Calendar APIへのリクエストエラーが発生しました: {e}")
        return {}

    if response.status_code != 200:
        logger.warning(f"Google Calendar APIエラー: {response.status_code} {response.json()}")
        return {}

    return response.json()

実行結果サンプル

それでは試しに実行してみましょう!事前に環境変数にAPIキーは設定済みです!

>>> from get_jp_holiday_calendar import get_jp_holiday_calendar
>>> get_jp_holiday_calendar(2026)
{'kind': 'calendar#events', 'etag': '"p333ctb4trro8s0o"', 'summary': '日本の祝日', 'description': '日本の祝日', 'updated': '2025-07-17T10:42:57.320Z', 'timeZone': 'UTC', 'accessRole': 'reader', 'defaultReminders': [], 'items': ["ここに結果がdict型で列挙される"]}

itemsの部分は長大なので一旦省略しました。以下にHTTPレスポンスのJSONをフォーマットしたものを記載します。itemsの内容は長大ですので、ここでは説明としてピックアップしたいもの以外は...,で省略して記載しております。

  • ピックアップポイント
    • 以下は祝日ではないのでこの結果には現れてこないこと
      • 三が日(一般に1月1日〜3日)
      • 大晦日(12月31日)
    • ちゃんと祝日法第3条第3項による休日として2026年9月22日が祝日になっていること
      • 11年ぶりだそうです!
{
   "kind":"calendar#events",
   "etag":"\"p33ifrb7ds3o8s0o\"",
   "summary":"日本の祝日",
   "description":"日本の祝日",
   "updated":"2025-07-17T10:42:57.320Z",
   "timeZone":"UTC",
   "accessRole":"reader",
   "defaultReminders":[
      
   ],
   "items":[
      {
         "kind":"calendar#event",
         "etag":"\"3432754943698000\"",
         "id":"20260101_ke4s0t96o1m43objlc2ihgsp48",
         "status":"confirmed",
         "htmlLink":"https://www.google.com/calendar/event?eid=MjAyNjAxMDFfa2U0czB0OTZvMW00M29iamxjMmloZ3NwNDggamEuamFwYW5lc2Uub2ZmaWNpYWwjaG9saWRheUB2&ctz=Asia/Tokyo",
         "created":"2024-05-22T11:31:11.000Z",
         "updated":"2024-05-22T11:31:11.849Z",
         "summary":"元日",
         "description":"祝日",
         "creator":{
            "email":"ja.japanese.official#holiday@group.v.calendar.google.com",
            "displayName":"日本の祝日",
            "self":true
         },
         "organizer":{
            "email":"ja.japanese.official#holiday@group.v.calendar.google.com",
            "displayName":"日本の祝日",
            "self":true
         },
         "start":{
            "date":"2026-01-01"
         },
         "end":{
            "date":"2026-01-02"
         },
         "transparency":"transparent",
         "visibility":"public",
         "iCalUID":"20260101_ke4s0t96o1m43objlc2ihgsp48@google.com",
         "sequence":0,
         "eventType":"default"
      },
      ...,
      {
         "kind":"calendar#event",
         "etag":"\"3432754955062000\"",
         "id":"20260922_0mnnapbhgfc9th4gh3di589omk",
         "status":"confirmed",
         "htmlLink":"https://www.google.com/calendar/event?eid=MjAyNjA5MjJfMG1ubmFwYmhnZmM5dGg0Z2gzZGk1ODlvbWsgamEuamFwYW5lc2Uub2ZmaWNpYWwjaG9saWRheUB2&ctz=Asia/Tokyo",
         "created":"2024-05-22T11:31:17.000Z",
         "updated":"2024-05-22T11:31:17.531Z",
         "summary":"国民の休日",
         "description":"祝日",
         "creator":{
            "email":"ja.japanese.official#holiday@group.v.calendar.google.com",
            "displayName":"日本の祝日",
            "self":true
         },
         "organizer":{
            "email":"ja.japanese.official#holiday@group.v.calendar.google.com",
            "displayName":"日本の祝日",
            "self":true
         },
         "start":{
            "date":"2026-09-22"
         },
         "end":{
            "date":"2026-09-23"
         },
         "transparency":"transparent",
         "visibility":"public",
         "iCalUID":"20260922_0mnnapbhgfc9th4gh3di589omk@google.com",
         "sequence":0,
         "eventType":"default"
      },
      ...,
      {
         "kind":"calendar#event",
         "etag":"\"3432754934238000\"",
         "id":"20261123_fdahe4s22krqku08ttvesk8ui0",
         "status":"confirmed",
         "htmlLink":"https://www.google.com/calendar/event?eid=MjAyNjExMjNfZmRhaGU0czIya3Jxa3UwOHR0dmVzazh1aTAgamEuamFwYW5lc2Uub2ZmaWNpYWwjaG9saWRheUB2&ctz=Asia/Tokyo",
         "created":"2024-05-22T11:31:07.000Z",
         "updated":"2024-05-22T11:31:07.119Z",
         "summary":"勤労感謝の日",
         "description":"祝日",
         "creator":{
            "email":"ja.japanese.official#holiday@group.v.calendar.google.com",
            "displayName":"日本の祝日",
            "self":true
         },
         "organizer":{
            "email":"ja.japanese.official#holiday@group.v.calendar.google.com",
            "displayName":"日本の祝日",
            "self":true
         },
         "start":{
            "date":"2026-11-23"
         },
         "end":{
            "date":"2026-11-24"
         },
         "transparency":"transparent",
         "visibility":"public",
         "iCalUID":"20261123_fdahe4s22krqku08ttvesk8ui0@google.com",
         "sequence":0,
         "eventType":"default"
      }
   ]
}

まとめ

今回はPythonとrequestsを用いてGoogle Calendar APIを実行して日本の祝日を取得する実装についてサンプルを用いて紹介させていただきました!世の中の誰かの実装の参考になることを願っています!🙏

最後に

TRUSTART株式会社は、一緒に働くメンバーを募集しています!インターンメンバーも大募集中です!
興味をお持ちいただけた方は、ぜひ弊社の採用ページをご確認ください。

https://www.trustart.co.jp/recruit/

TRUSTARTテックブログ

Discussion