Commands icon
Process icon
Log icon
Schedule icon

Advanced Scheduling Automation, Run Tasks Only on Business Days by Country

Schedule Kestra tasks to run only on business days using Python and country holiday calendars. An advanced scheduling pattern for enterprise and financial jobs.

Categories
Core

Most schedulers fire on a fixed cron and have no idea whether the date is a weekend or a national holiday. This blueprint adds a business-day gate to your schedule: a Python script checks the run date against a country-specific holiday calendar (using the workalendar library) and stops the flow cleanly when the date is not a working day. It is a practical pattern for billing runs, financial processing, reporting jobs, and data pipelines that must follow local business calendars rather than a naive every-day trigger.

How it works

  1. The io.kestra.plugin.core.trigger.Schedule trigger fires on the cron 0 14 25 12 * and passes the execution date into the flow.
  2. The check_if_business_date task (io.kestra.plugin.scripts.python.Commands) runs python schedule.py "{{trigger.date ?? inputs.date}}" {{inputs.country}} on the io.kestra.plugin.core.runner.Process runner with namespaceFiles enabled, installing the workalendar dependency at runtime.
  3. The {{ trigger.date ?? inputs.date }} expression uses the scheduled date in production and falls back to the date input for manual testing.
  4. If the date is a working day, the script exits 0 and the log task (io.kestra.plugin.core.log.Log) confirms the flow continues. If it is a weekend or public holiday, the script exits with an error and downstream tasks never run.

What you get

  • A reusable business-day guard you can drop in front of any scheduled workflow.
  • Country-aware holiday handling driven by the country input (US and FR provided, easily extended).
  • A single cron schedule that behaves correctly across weekends and holidays without extra trigger logic.
  • Manual testability through the date input without changing production behavior.

Who it's for

  • Data engineers building pipelines that must respect business calendars.
  • Finance and operations teams running billing, settlement, or reporting jobs.
  • Platform teams standardizing scheduling patterns across many flows.

Why orchestrate this with Kestra

A plain cron scheduler cannot answer "is today actually a working day in this country?" Kestra fills that gap by letting an event-driven Schedule trigger hand the date to a real Python check, then express the whole pipeline as declarative YAML. You also get automatic retries, full execution lineage and logs, and the ability to chain real downstream work after the gate, none of which a bare cron entry provides.

Prerequisites

  • A Kestra instance with the Python script plugin available.
  • The workalendar Python package (installed automatically via the task dependencies).
  • A schedule.py Namespace File (see Quick start).

Secrets

This blueprint uses no secrets. The flow runs entirely on the schedule date and the country input.

Quick start

  1. In the Kestra UI, open the built-in VS Code Editor and add schedule.py as a Namespace File:
import sys
from datetime import datetime
from workalendar.europe import France
from workalendar.usa import UnitedStates

def is_business_day(date_str, country_calendar):
    date = datetime.fromisoformat(date_str.replace("Z", ""))
    return country_calendar.is_working_day(date)

def main():
    if len(sys.argv) != 3:
        print("Usage: script.py <date> <country_code>")
        sys.exit(1)
    date_str, country_code = sys.argv[1], sys.argv[2]
    calendars = {"FR": France(), "US": UnitedStates()}
    country_calendar = calendars.get(country_code.upper())
    if not country_calendar:
        print(f"Calendar for '{country_code}' not supported or not found.")
        sys.exit(1)
    try:
        if not is_business_day(date_str, country_calendar):
            print(f"{date_str} is not a business day in {country_code}.")
            sys.exit(1)
        print(f"{date_str} is a business day in {country_code}.")
    except Exception as e:
        print(f"Error: {e}")
        sys.exit(1)

if __name__ == "__main__":
    main()
  1. Set the country input (defaults to US) and optionally a date for manual runs.
  2. Execute the flow manually to verify the gate, then enable the schedule.

How to extend

  • Add more countries to the calendars dictionary in schedule.py using other workalendar regions.
  • Replace the log task with your real downstream work (a dbt run, a data load, a report).
  • Adjust the cron to your cadence (daily, weekday-only) and let the calendar check handle holidays.
  • Add a notification task in an errors branch to alert when a run is skipped.

Links

Share this Blueprint
See How

New to Kestra?

Use blueprints to kickstart your first workflows.