**Show HN:** *FastScheduler* – Decorator‑first Python task scheduler with async support  
→ **HNで紹介**:FastScheduler ― デコレータ優先のPythonタスクスケジューラ、非同期対応

2026/01/13 23:45

**Show HN:** *FastScheduler* – Decorator‑first Python task scheduler with async support → **HNで紹介**:FastScheduler ― デコレータ優先のPythonタスクスケジューラ、非同期対応

RSS: https://news.ycombinator.com/rss

要約

Japanese Translation:

FastSchedulerは、開発者が最小限のコードで非同期タスクをスケジュールできる軽量Pythonライブラリです。

@scheduler.every(10).seconds
@scheduler.daily.at("14:30")
といったデコレータを使用すると、インターバル型・時間ベース型・cron型・ワンタイムジョブを定義でき、オプションでタイムゾーン設定(
tz="America/New_York"
.tz()
チェーン可能)も行えます。

自動リトライ(指数バックオフ付き)、タイムアウト設定、pause/ resume / cancel アクション、“no‑catch‑up” モード(欠落した実行をスキップ)、履歴保持制限(

max_history
history_retention_days
)およびデッドレターキューサイズ(
max_dead_letters
)をサポートしています。Scheduler の状態は
fastscheduler_state.json
に永続化され、デッドレタージョブは
_dead_letters.json
に保存されます。

インストールは pip で簡単に行えます。[cron] などの extras を指定すると cron 構文がサポートされ、[fastapi] を追加すると

/scheduler/
に FastAPI ベースのリアルタイムダッシュボードが提供されます。ダッシュボードは SSE(Server‑Sent Events)でライブ更新を行い、ジョブステータス・リスト・履歴・イベント用の REST エンドポイントも公開します。

FastScheduler の API には

start()
stop(wait=True, timeout=30)
get_jobs()
get_job(id)
get_history()
get_statistics()
pause_job(id)
resume_job(id)
cancel_job(id)
があり、コンテキストマネージャとしても使用可能です。

典型的な使用例としては、インターバルジョブ、非同期タイムゾーンジョブ(タイムアウト付き)、リトライ付き cron ジョブ、週次ジョブ、および寿命フックを使った FastAPI アプリへの統合があります。

本文

FastScheduler(ファストスケジューラ)

FastScheduler は、Python 用の軽量で非同期に優しいタスクスケジューラです。タイムゾーン・cron 式・永続状態をサポートし、FastAPI が提供するリアルタイムダッシュボードと連携します。


主な特徴

🎯デコレータベースのシンプル API – 1 行でタスクをスケジュール
async/await
をネイティブにサポート
🕐タイムゾーン対応 – 任意のタイムゾーンでジョブ実行
📅cron 式による複雑なスケジュール設定
💾永続状態 – 再起動後も残存し、欠落したジョブを処理
🎨FastAPI ダッシュボードでリアルタイム監視
🔄失敗時の自動再試行(指数関数的バックオフ)
⏱️ジョブタイムアウト – 長時間実行中のタスクを強制終了
⏸️削除せずに一時停止/再開
📋デッドレターキュー – 失敗したジョブを追跡・デバッグ

インストール

# 基本インストール
pip install fastscheduler

# FastAPI ダッシュボード付き
pip install fastscheduler[fastapi]

# cron サポート付き
pip install fastscheduler[cron]

# すべてのオプションを有効にする
pip install fastscheduler[all]

クイックスタート

from fastscheduler import FastScheduler

scheduler = FastScheduler(quiet=True)

@scheduler.every(10).seconds
def task():
    print("Task executed")

@scheduler.daily.at("14:30")
async def daily_task():
    print("Daily task at 2:30 PM")

scheduler.start()

スケジューリングオプション

インターバルベース

@scheduler.every(10).seconds
@scheduler.every(5).minutes
@scheduler.every(2).hours
@scheduler.every(1).days

時間ベース

@scheduler.daily.at("09:00")               # 毎朝9時
@scheduler.hourly.at(":30")                # 毎時間30分に
@scheduler.weekly.monday.at("10:00")       # 月曜10時
@scheduler.weekly.weekdays.at("09:00")     # 平日9時
@scheduler.weekly.weekends.at("12:00")     # 週末正午

cron 式(
pip install fastscheduler[cron]
が必要)

@scheduler.cron("0 9 * * MON-FRI")
def market_open():
    ...

@scheduler.cron("*/15 * * * *")
def frequent_check():
    ...

@scheduler.cron("0 0 1 * *")
def monthly_report():
    ...

一度だけ実行

@scheduler.once(60)
def delayed_task():
    ...

@scheduler.at("2024-12-25 00:00:00")
def christmas_task():
    ...

タイムゾーンサポート

# tz パラメータ
@scheduler.daily.at("09:00", tz="America/New_York")
def nyc_morning(): ...

# チェーン可能な .tz()
@scheduler.weekly.monday.tz("Europe/London").at("09:00")
def london_standup(): ...

# cron でも
@scheduler.cron("0 9 * * MON-FRI").tz("Asia/Tokyo")
def tokyo_market(): ...

代表的なタイムゾーンは

UTC
America/New_York
Europe/London
Asia/Tokyo
等です。


ジョブ制御

タイムアウト

@scheduler.every(1).minutes.timeout(30)
def quick_task():
    ...

@scheduler.daily.at("02:00").timeout(3600)  # 最大1時間
def nightly_backup():
    ...

再試行

@scheduler.every(5).minutes.retries(5)
def flaky_api_call():
    ...
# 指数関数的バックオフ:2s, 4s, 8s …

カッチアップをスキップ

@scheduler.every(1).hours.no_catch_up()
def hourly_stats():
    ...

一時停止 / 再開 / キャンセル

scheduler.pause_job("job_0")
scheduler.resume_job("job_0")
scheduler.cancel_job("job_0")
scheduler.cancel_job_by_name("my_task")

FastAPI 連携

from fastapi import FastAPI
from fastscheduler import FastScheduler
from fastscheduler.fastapi_integration import create_scheduler_routes

app = FastAPI()
scheduler = FastScheduler(quiet=True)

app.include_router(create_scheduler_routes(scheduler))

@scheduler.every(30).seconds
def background_task():
    print("Background work")

scheduler.start()

ダッシュボードは

http://localhost:8000/scheduler/
で確認できます。


API エンドポイント

エンドポイントメソッド説明
/scheduler/
GETダッシュボード UI
/scheduler/api/status
GETスケジューラの状態
/scheduler/api/jobs
GETすべてのジョブ一覧
/scheduler/api/jobs/{job_id}
GET指定ジョブ取得
/scheduler/api/jobs/{job_id}/pause
POSTジョブを一時停止
/scheduler/api/jobs/{job_id}/resume
POSTジョブを再開
/scheduler/api/jobs/{job_id}/cancel
POSTジョブをキャンセル
/scheduler/api/history
GET実行履歴
/scheduler/api/dead-letters
GETデッドレターキュー
/scheduler/api/dead-letters
DELETEキュークリア
/scheduler/events
GETSSE イベントストリーム

設定

scheduler = FastScheduler(
    state_file="scheduler.json",      # 永続ファイル
    quiet=True,                       # ログ抑制
    auto_start=False,                 # 手動起動
    max_history=5000,                 # 履歴最大件数
    max_workers=20,                   # 同時ジョブ数
    history_retention_days=8,         # 古い履歴削除期間
    max_dead_letters=500,             # デッドレターキューサイズ
)

履歴保持

  • max_history
    (件数上限)
  • history_retention_days
    (時間上限;0 で無効化)

デッドレターキュー

  • *_dead_letters.json
    に保存
  • 最新の
    max_dead_letters
    件を詳細付きで保持

モニタリング & プログラム的アクセス

jobs = scheduler.get_jobs()
job = scheduler.get_job("job_0")
history = scheduler.get_history(limit=100)
stats = scheduler.get_statistics()
scheduler.print_status()

コンテキストマネージャーで使用可能:

with FastScheduler(quiet=True) as scheduler:
    @scheduler.every(5).seconds
    def task():
        print("Running")
    time.sleep(30)   # スケジューラは自動実行
# 退出時に停止

状態永続化

  • ジョブ定義・スケジュール・履歴・統計・ジョブカウンタをディスクへ保存
  • 再起動時:ジョブ復元、欠落した実行を算出し、必要ならキャッチアップジョブを実行(
    no_catch_up()
    で除外可)

完全な例

import asyncio, time
from fastscheduler import FastScheduler

scheduler = FastScheduler(quiet=True)

@scheduler.every(10).seconds
def heartbeat():
    print(f"[{time.strftime('%H:%M:%S')}] ❤️ Heartbeat")

@scheduler.daily.at("09:00", tz="America/New_York").timeout(60)
async def morning_report():
    print("Generating report...")
    await asyncio.sleep(5)
    print("Report sent!")

@scheduler.cron("*/5 * * * *").retries(3)
def check_api():
    print("Checking API health")

@scheduler.weekly.monday.at("10:00")
def weekly_standup():
    print("Time for standup!")

scheduler.start()

try:
    while True:
        time.sleep(60)
        scheduler.print_status()
except KeyboardInterrupt:
    scheduler.stop()

FastAPI とライフサイクル

from contextlib import asynccontextmanager
from fastapi import FastAPI
from fastscheduler import FastScheduler
from fastscheduler.fastapi_integration import create_scheduler_routes

scheduler = FastScheduler(quiet=True)

@asynccontextmanager
async def lifespan(app: FastAPI):
    scheduler.start()
    yield
    scheduler.stop(wait=True)

app = FastAPI(lifespan=lifespan)
app.include_router(create_scheduler_routes(scheduler))

@scheduler.every(30).seconds
def background_job():
    print("Working...")

API 参照

メソッド説明
start()
スケジューラを開始
stop(wait=True, timeout=30)
Graceful 停止
get_jobs()
すべてのジョブ取得
get_job(job_id)
指定ジョブ取得
get_history(func_name=None, limit=50)
実行履歴
get_statistics()
ランタイム統計
get_dead_letters(limit=100)
失敗ジョブキュー
clear_dead_letters()
キューをクリア
pause_job(job_id)
ジョブ停止
resume_job(job_id)
ジョブ再開
cancel_job(job_id)
ジョブキャンセル・削除
cancel_job_by_name(func_name)
関数名でジョブ全て削除
print_status()
コンソールに状態表示

ライセンス

MIT © 2024


貢献歓迎!GitHub で issue や PR を作成してください。

同じ日のほかのニュース

一覧に戻る →

2026/01/14 5:45

**ゲームズ・ワークショップ、スタッフのAI使用を全面禁止 経営陣はテクノロジーに興味津々でない** - 同社は従業員が業務上人工知能ツールを利用することを一律で禁じる方針を採用しました。 - 経営層は知的財産の安全性や創造的コントロールへの影響を懸念していると述べています。 - 業界内では注目が集まっても、上級経営者はAIがデザイン・生産フローに与えるメリットに対し慎重な姿勢を保ち続けています。

## Japanese Translation: **改善された概要** Games Workshop は、コンテンツ制作と設計プロセスにおける生成型 AI ツールの使用を正式に禁止しました。この方針では、厳格な監視下で数名の上級マネージャーのみが AI を実験できるようになっていますが、その可能性についてはまだ誰も興奮していません。外部コンペティションへの参加を含む不正使用は禁止されており、企業はデータ準拠・セキュリティ・ガバナンスを監視し、AI/ML エンジンがデバイスに自動インストールされるのを防止する必要があります。 GW の禁止措置は知的財産権を保護し、人間クリエイターを尊重するとともに、上級スタッフによる限定的な調査を許可しています。この決定は、より広い文脈の中で行われました。GW は *Warhammer 40,000* や *Age of Sigmar* などのフラッグシップテーブルトップタイトルを所有し、高品質のコデックス本・ミニチュア・アニメーションを販売しており、最近は新規採用で Warhammer Studio を拡大しました。Displate の作品に関する最近の紛争―Displate がそのアートワークが AI によって生成されたと否定し、「赤旗」を人為的なミスに帰せたケース―は、ファンが生成型 AI アートに対して反発していることを示しています。特に Warhammer の美学に大きな影響力を持つアーティスト John Blanche の存在がその背景にあります。 今後も GW はデータ準拠とセキュリティの監視を継続します。上級マネージャーは AI の可能性を探るかもしれませんが、内部方針の変更や外部圧力が変わらない限り、広範な採用は見込めません。この禁止措置により GW は Genvid、EA、Square Enix など AI を積極的に導入している競合他社に比べて遅れを取ることになり、ゲーム開発の競争ダイナミクスが変わる可能性があります。これは生成型 AI の統合に対する業界全体の慎重な姿勢を反映しています。

2026/01/14 2:10

**チューリップ・クリエイティブ・コンピュータ** - 芸術と技術のユニークな融合 - 革新的なビジュアル体験を設計 - 鮮やかなカラーパレットと最先端ハードウェアを組み合わせる

## 日本語訳: **Tulip CC** は低電力で手頃な価格のセルフコンテインドポータブルコンピュータで、オープンソースの音楽ワークステーションとしても機能します。ESP32‑S3マイクロコントローラを中心に構築され、MicroPython を実行し、AMY ステレオ 120 ボイスシンセサイザーエンジン(加法/減法/F‑M 合成、サンプラー、Karplus–Strong、アナログフィルタ、シーケンサー、ドラムマシン、パッチエディタ)とキャパシティブ・マルチタッチ対応のタッチスクリーンディスプレイを備えています。 デバイスは 8.5 MB の RAM(MicroPython 用 2 MB、OS 用 1.5 MB、残りがグラフィックスフレームバッファ)と 32 MB のフラッシュ(うち 24 MB が使用可能)、Wi‑Fi、USB キーボード/マウス/MIDI、I²C/Grove/Mabee コネクタをセンサーや周辺機器用に搭載し、組み込みの pico/nano スタイルエディタ(構文ハイライトと REPL)も備えています。グラフィックスは LVGL によって処理されます:テキストフレームバッファ 128 × 50(ANSI 256 色)、スキャンラインあたり最大 32 スプライト(32 KB ビットマップメモリ)、1024 × 600 の背景フレームバッファでスクロール、PNG ローディング、デフォルト 30 FPS、解像度調整可能、256 色。 電力消費は 5 V で 575 mA(中程度の輝度)で、LiPo、18650、または USB バッテリーパックに対応しています。追加ソフトウェア機能として、ネイティブチャット/ファイル共有 BBS「TULIP ~ WORLD」、MIDI 入出力コールバック、およびクリエーションの共有用 Web バージョンがあります。 Tulip CC は市販ユニット、DIY ハードウェアキット、フル機能の Web アプリ、またはネイティブデスクトップアプリ(Mac/Linux/WSL)として入手可能です。開発リソース—完全な API ドキュメント、チュートリアル、Discord コミュニティ、およびオープンソース GitHub リポジトリ—が提供されており、埋め込みデバイスとデスクトップ環境の両方で動作するために貢献が必要です。将来のファームウェア更新では、合成モジュールの拡張、LVGL を介したグラフィックス解像度の向上、および電力効率の改善がコミュニティの入力を受けて行われる可能性があります。

2026/01/14 1:22

「二つの頭(=複数の視点)が一つより優れているのでしょうか?」

## Japanese Translation: ## 要約 コイントスの結果を時折だけ報告する人々がいる場合、報告者数が奇数であると予測精度が向上し、さらに1人追加して偶数にすると追加効果は得られないという点が主旨です。 シミュレーションと解析的な検証から次のように示されています:正直な友人(80 % 正解率)を1人だけ持つ場合、2人目を加えても精度は80 %のままであり、合意しても不一致が相殺されるため利益がありません。3人目が参加すると精度は90 %に上昇し、4人目が加わると再び90 %に戻ります。このパターンは奇数回報者ごとに繰り返されます。 この発見はコンドルセートの陪審理論を反映しており、偶数規模のグループでは多数決が引き分けになる可能性があるため、新たな情報を提供しないことを説明しています。著者は、創造的執筆プロジェクトを開催するプログラミングリトリート「Recurse Center」でベッティングシミュレーションを実行している際にこの現象に気付きました。 今後の研究では、この傾向がより複雑な投票設定や大規模グループでも維持されるかどうかを検証することが期待されます。グループサイズと偶奇性が意思決定品質に与える影響を理解することで、クラウドソーシングサイト、陪審制度、または人間の判断を集約するあらゆるプラットフォームの設計者が、不必要な偶数参加者を追加しないよう助けることができます。

**Show HN:** *FastScheduler* – Decorator‑first Python task scheduler with async support → **HNで紹介**:FastScheduler ― デコレータ優先のPythonタスクスケジューラ、非同期対応 | そっか~ニュース