Kaggleの新着コンペを自動通知するツールを作った
はじめに
Kaggleで新しいコンペティションが始まったときに、いち早く情報をキャッチしたいですよね。特に自分はGPU環境がなくてtableばかり追っているので、毎回コンペをチェックするのは手間に感じていました。
そこで、Kaggle APIを使って新着のテーブルコンペ(それ以外も可)を自動で検出し、メール通知してくれるツールを作りました。GitHub Actionsで定期実行すれば、完全自動化できます。
主な機能
このツールには以下の機能があります:
- Kaggle APIでコンペ一覧を自動取得
- テーブルコンペ(
tabularタグ)のみをフィルタリング - カテゴリー指定(Featured、Researchなど)
- 重複通知の防止(送信済みコンペを記録)
- Gmailでのメール通知
- GitHub Actionsによる定期実行
技術スタック
- Python 3.13
- uv: 高速なPythonパッケージマネージャー
- Kaggle API: コンペ情報の取得
- SMTP (Gmail): メール送信
- GitHub Actions: 定期実行とキャッシュ管理
実装のポイント
1. Kaggle APIでコンペ情報を取得
Kaggle APIを使うことで、コンペティションの詳細情報を簡単に取得できます。
from kaggle.api.kaggle_api_extended import KaggleApi
api = KaggleApi()
api.authenticate()
# 複数ページを取得(約60件)
all_comps = []
for page in range(1, 4):
comps = api.competitions_list(page=page)
if not comps:
break
all_comps.extend(comps)
取得できる情報:
- タイトル、URL、締切
- カテゴリー(Featured / Research / Getting Started)
- 賞金、チーム数
- タグ(tabular、nlp、computer-visionなど)
2. 重複通知の防止
sent_competitions.jsonに送信済みのコンペタイトルを記録しています。
def load_sent_history():
history_file = Path("sent_competitions.json")
if not history_file.exists():
return set()
with open(history_file, "r") as f:
data = json.load(f)
return set(data.get("sent_titles", []))
def save_sent_history(titles):
history_file = Path("sent_competitions.json")
with open(history_file, "w") as f:
json.dump({"sent_titles": list(titles)}, f, indent=2)
3. GitHub Actionsで自動化
毎日決まった時間に自動実行し、送信履歴もキャッシュで永続化します。
on:
schedule:
# 毎日 9:00 AM UTC(日本時間 18:00)に実行
- cron: '0 9 * * *'
workflow_dispatch: # 手動実行も可能
jobs:
notify:
runs-on: ubuntu-latest
steps:
- name: Setup Kaggle credentials
run: |
mkdir -p ~/.kaggle
echo "{\"username\":\"${KAGGLE_USERNAME}\",\"key\":\"${KAGGLE_KEY}\"}" > ~/.kaggle/kaggle.json
chmod 600 ~/.kaggle/kaggle.json
- name: Load sent history from cache
uses: actions/cache@v4
with:
path: sent_competitions.json
key: sent-competitions-${{ github.sha }}
restore-keys: sent-competitions-
- name: Run notifier
run: uv run python main.py
- name: Save sent history to cache
uses: actions/cache/save@v4
with:
path: sent_competitions.json
key: sent-competitions-${{ github.sha }}
キャッシュのポイント:
-
actions/cache@v4でsent_competitions.jsonを保存 -
restore-keysで過去のキャッシュをフォールバック - 実行後に必ず保存(
if: always())
セットアップ方法
1. リポジトリをクローン
git clone git@github.com:satabie/kaggle-notifier.git
cd kaggle-notifier
2. 依存パッケージをインストール
uv sync
3. 環境変数を設定
.env.exampleをコピーして.envを作成:
cp .env.example .env
.envに以下を設定:
EMAIL=your-email@example.com
SMTP_USER=your-email@gmail.com
SMTP_PASS=your-16-digit-app-password
SMTP_SERVER=smtp.gmail.com
SMTP_PORT=587
Gmailアプリパスワードの取得方法:
- Googleアカウントで2段階認証を有効化
- https://myaccount.google.com/apppasswords にアクセス
- アプリパスワードを生成(16桁)
-
SMTP_PASSに設定
4. Kaggle API認証の設定
# Kaggle Account Settingsからkaggle.jsonをダウンロード
mkdir -p ~/.kaggle
mv ~/Downloads/kaggle.json ~/.kaggle/
chmod 600 ~/.kaggle/kaggle.json
5. フィルター設定
config.json.exampleをコピーして編集:
cp config.json.example config.json
{
"filters": {
"table_only": true,
"category": ["Featured", "Research"]
}
}
6. 実行
uv run python main.py
GitHub Actionsでの自動実行
Secretsの設定
GitHubリポジトリの Settings > Secrets and variables > Actions で以下を追加:
| Secret名 | 説明 |
|---|---|
EMAIL |
通知先メールアドレス |
SMTP_USER |
SMTP認証用メールアドレス |
SMTP_PASS |
Gmailアプリパスワード(16桁) |
KAGGLE_USERNAME |
Kaggleユーザー名 |
KAGGLE_KEY |
Kaggle APIキー |
設定後、Actionsタブから手動実行でテストできます。
工夫した点
1. uvを使った高速セットアップ
従来のpipやpoetryではなく、Rust製の高速パッケージマネージャーuvを採用しました。GitHub Actions上でも数秒で環境構築が完了します。
2. キャッシュによる永続化
GitHub Actionsは毎回クリーンな環境で実行されるため、sent_competitions.jsonが消えてしまいます。actions/cacheを使うことで、実行間で送信履歴を保持し、重複通知を防いでいます。
3. わかりやすいエラーメッセージ
SMTP認証エラーなど、よくあるエラーに対して詳細なガイドメッセージを表示するようにしました。
raise ValueError(
"SMTP_USER and SMTP_PASS must be set in .env file.\n"
"For Gmail, you need to:\n"
"1. Enable 2-factor authentication\n"
"2. Generate an App Password at https://myaccount.google.com/apppasswords\n"
"3. Set SMTP_USER=your-email@gmail.com and SMTP_PASS=your-app-password in .env"
)
今後の改善案
- メール本文のHTML化(見やすいレイアウト)
- Slack/Discord通知への対応
- 締切が近いコンペの優先通知
- コンペの難易度予測(過去のメダル獲得ラインから)
まとめ
このツールを使えば、Kaggleの新着テーブルコンペを見逃すことなく、自動でメール通知を受け取れます。GitHub Actionsで完全自動化できるので、一度セットアップすれば後は放置でOKです。
興味がある方はぜひ試してみてください!
Discussion