Jours fériés (nationaux & religieux) et jours ouvrables du Maroc.
Intégrez en quelques lignes dans vos pipelines data, orchestrateurs et applications.
Inscription gratuite · Pas de carte bancaire
from pycalendar_api import CalendarApi, to_date
api = CalendarApi('YOUR_API_KEY')
# Vérifier si une date est férié
result = api.holidays.is_holiday(to_date('14/01/2025'))
# → HolidayCheckResult(is_holiday=True,
# description="Nouvel An Amazigh",
# holiday_type='National', status='Official')
# Prochain jour ouvrable
nxt = api.bdays.next_date(to_date('13/01/2025'))
# → NextDate(
# date=datetime.date(2025, 1, 13),
# next_date=datetime.date(2025, 1, 15))
# Span du 3ème trimestre 2025
span = api.bdays.span(2025, quarter=3)
# → CalSpan(start_date=datetime.date(2025, 6, 30),
# end_date=datetime.date(2025, 9, 30),
# year=2025, semester=None, quarter=3, month=None)
pycalendar-api — modèles dataclasses, zéro dépendances lourdes.toml — timeout, proxy, certificatsUn problème récurrent nécessite forcément une solution pérenne!
Tous les cas d'usage couverts par une API claire et des modèles pleinement typés.
from pycalendar_api import CalendarApi, to_date
api = CalendarApi.from_env() ## export PYCALENDAR_APIKEY = YOUR_API_KEY
# ── Vérifier une date ──
r = api.holidays.is_holiday(to_date('14/01/2025'))
# HolidayCheckResult(is_holiday=True, description="Nouvel An Amazigh",
# holiday_type='National', status='Official')
# ── Lister tous les jours fériés de 2025 ──
holidays = api.holidays.year(2025)
# [Holiday(...), Holiday(...), ...]
# ── Fêtes religieuses: statut peut être 'Estimated' ──
religious = api.holidays.year(2025, holiday_type='Religious'))
# Or religious = [h for h in holidays if h.holiday_type == 'Religious']
estimated = [h for h in religious if h.status == 'Estimated']
# Polling recommandé (toutes les heures) jusqu'à confirmation
from pycalendar_api import CalendarApi, to_date
api = CalendarApi.from_env() ## export PYCALENDAR_APIKEY = YOUR_API_KEY
# ── Prochain / précédent jour ouvrable ──
nxt = api.bdays.next_date(to_date('13/01/2025'))
# → NextDate(
# date=datetime.date(2025, 1, 13),
# next_date=datetime.date(2025, 1, 15))
prev = api.bdays.previous_date(to_date('15/01/2025'))
# → PreviousDate(
# date=datetime.date(2025, 1, 15),
# previous_date=datetime.date(2025, 1, 13))
# ── Compter les jours ouvrables ──
count = api.bdays.count(to_date('02/01/2025'), to_date('31/12/2025'))
# → DaysCount(
# start_date=datetime.date(2025, 1, 2),
# end_date=datetime.date(2025, 12, 31),
# count=247)
# ── Lister les jours ouvrables (juin 2025) ──
june = api.bdays.bdays_of(2025, month=6)
# → DateSeries(ref='bdays-2025-06
# min_date=datetime.date(2025, 6, 2),
# max_date=datetime.date(2025, 6, 30),
# items=19,
# serie=SortedSet([datetime.date(2025, 6, 2), ..., datetime.date(2025, 6, 30)]))
from pycalendar_api import CalendarApi
api = CalendarApi.from_env() ## export PYCALENDAR_APIKEY = YOUR_API_KEY
# ── Bornes ouvrables d'une période (start/end = open business days) ──
# Année complète 2025
y = api.bdays.span(2025)
# → CalSpan(start_date=datetime.date(2024, 12, 31),
# end_date=datetime.date(2025, 12, 31),
# year=2025, semester=None, quarter=None, month=None)
# 3ème trimestre 2025
q3 = api.bdays.span(2025, quarter=3)
# → CalSpan(start_date=datetime.date(2025, 6, 30),
# end_date=datetime.date(2025, 9, 30),
# year=2025, semester=None, quarter=3, month=None)
# Juillet 2025
jul = api.bdays.span(2025, month=7)
# → CalSpan(start_date=datetime.date(2025, 6, 30),
# end_date=datetime.date(2025, 7, 31),
# year=2025, semester=None, quarter=None, month=7)
# Idéal pour les requêtes de type :
# WHERE date BETWEEN :start AND :end (intervalles enchaînables)
# Airflow 3 Task sdk
from airflow.sdk import dag, task
from pycalendar_api import CalendarApi, to_date
from datetime import date
# Utiliser Airflow Variables ou get_connection
api = CalendarApi.from_env()
def is_business_day(d: date) -> bool:
r = api.holidays.is_holiday(d)
return not r.is_holiday and d.weekday() < 5
# Exemple : skip le DAG les jours non ouvrables
@dag(schedule="0 8 * * *")
def daily_etl():
@task.short_circuit
def check_business_day():
return is_business_day(date.today())
check_business_day() >> ... # reste du pipeline
Airflow, Dagster, PGQueuer — votre orchestrateur sait désormais qu'un jour est férié. Fini les scripts fragiles if date in [...].
Détectez les observations manquantes dans vos séries chronologiques. Alignez plusieurs sources sur le même calendrier ouvrable.
CalSpan génère des bornes ouvrables enchaînables par mois, trimestre ou semestre — parfait pour vos requêtes VNI et reporting réglementaire.
Désactivez les jours fériés dans vos sélecteurs de dates. L'API répond en JSON ; consommez-la depuis n'importe quel frontend.
Les fêtes religieuses sont d'abord estimées (avant l'observation de la lune), puis confirmées officielles. L'API expose ce statut explicitement. Mettez en place un polling horaire sur les dates estimées — Calendar API mettra à jour le statut dès confirmation.
Inscription en 30 secondes, pas de carte bancaire. Obtenez jusqu'à 5 clés API depuis la console.
$ pip install pycalendar-apifrom pycalendar_api importCalendarApi
api = CalendarApi('YOUR_KEY')
print(api.health()) # ApiHealth(api_status="UP", ...)Tout ce qu'il faut savoir avant de démarrer.
Estimated / Official pour les fêtes religieuses. La fiabilité est structurelle, pas conjoncturelle. Estimated. Dès que l'annonce officielle du Ministère des Habous est publiée, leur statut bascule automatiquement vers Official — sans mise à jour manuelle de vos applications. Un polling horaire sur les dates estimées est le pattern recommandé. [start_date, end_date]. Les intervalles sont enchaînables sans trou ni chevauchement, directement utilisables dans une clause SQL BETWEEN. Exemple : le T3 2025 retourne start_date = 2025-06-30 (dernier ouvrable de juin) et end_date = 2025-09-30 (dernier ouvrable de septembre). Fonctionnalité permanentemente gratuite. $ pip install pycalendar-apipycalendar-api n'a pas de dépendances lourdes — modèles dataclasses standard, client HTTP httpxyz configurable via .toml (timeout, proxy, certificats). Python 3.10+ requis. Documentation →