Liturgical calendar library for calculating Catholic liturgical dates and calendars
Project description
Romcal
A Python library for calculating Catholic liturgical dates and generating liturgical calendars. Powered by Rust via UniFFI bindings.
For the Rust library, see romcal. For command-line usage, see the CLI documentation.
Installation
pip install romcal
Or with uv:
uv add romcal
Quick Start
from romcal import Romcal
# Create a default instance
romcal = Romcal()
# Get a specific liturgical date
easter = romcal.get_date("easter_sunday", 2026)
print(easter) # "2026-04-05"
# Generate the liturgical calendar for year 2026
calendar = romcal.liturgical_calendar(2026)
# Access a specific date
christmas = calendar.get("2026-12-25")
if christmas:
print(christmas[0]["fullname"]) # "The Nativity of the Lord"
Configuration
Using Keyword Arguments
from romcal import Romcal
# With calendar and locale
romcal1 = Romcal(calendar="france", locale="fr")
# With full configuration
romcal2 = Romcal(
calendar="france",
locale="fr",
context="LITURGICAL",
epiphany_on_sunday=True,
ascension_on_sunday=True,
corpus_christi_on_sunday=True,
)
Configuration Options
| Option | Type | Default | Description |
|---|---|---|---|
calendar |
str |
"general_roman" |
Calendar ID (e.g., "france", "united_states") |
locale |
str |
"en" |
Locale code (e.g., "fr", "es") |
context |
str |
"GREGORIAN" |
"GREGORIAN" (Jan-Dec) or "LITURGICAL" (Advent-Advent) |
epiphany_on_sunday |
bool |
False |
Celebrate Epiphany on Sunday (Jan 2-8) instead of Jan 6 |
ascension_on_sunday |
bool |
False |
Celebrate Ascension on Sunday instead of Thursday |
corpus_christi_on_sunday |
bool |
True |
Celebrate Corpus Christi on Sunday instead of Thursday |
easter_calculation_type |
str |
"GREGORIAN" |
"GREGORIAN" or "JULIAN" Easter calculation |
calendar_definitions_json |
str |
None |
JSON string of calendar definitions |
resources_json |
str |
None |
JSON string of locale resources |
Loading Calendar Data
Without loading data, only the Proper of Time is available. To include the General Roman Calendar, particular calendars, and localized names, load calendar definitions and resources:
import json
from pathlib import Path
from romcal import Romcal
DATA_DIR = Path("data")
def load_calendar_definitions():
"""Load all calendar definitions from the data folder."""
definitions = []
for json_file in (DATA_DIR / "definitions").rglob("*.json"):
with open(json_file) as f:
definitions.append(json.load(f))
return definitions
def load_resources():
"""Load all resources from the data folder."""
resources_dir = DATA_DIR / "resources"
resources = []
# Group files by locale
files_by_locale = {}
for json_file in resources_dir.rglob("*.json"):
locale = json_file.parent.name
files_by_locale.setdefault(locale, []).append(json_file)
# Merge files for each locale
for locale, locale_files in files_by_locale.items():
metadata = None
entities = {}
for file in locale_files:
with open(file) as f:
content = json.load(f)
if file.name == "meta.json":
metadata = content.get("metadata")
elif file.name.startswith("entities.") and "entities" in content:
entities.update(content["entities"])
resources.append({
"locale": locale,
"metadata": metadata,
"entities": entities if entities else None,
})
return resources
# Create instance with loaded data
romcal = Romcal(
calendar="france",
locale="fr",
calendar_definitions_json=json.dumps(load_calendar_definitions()),
resources_json=json.dumps(load_resources()),
)
API
Romcal()
Creates a new Romcal instance.
from romcal import Romcal
# Default configuration
romcal1 = Romcal()
# With calendar and locale
romcal2 = Romcal(calendar="france", locale="fr")
# With partial configuration
romcal3 = Romcal(
calendar="france",
locale="fr",
epiphany_on_sunday=True,
)
Romcal Instance
liturgical_calendar(year)
Generate the complete liturgical calendar for a given year.
calendar = romcal.liturgical_calendar(2026)
# calendar is dict[str, list[dict]]
# Keys are dates in "YYYY-MM-DD" format
for date, days in calendar.items():
for day in days:
print(f"{date}: {day['fullname']} ({day['rank']})")
mass_calendar(year)
Generate a mass-centric view of the calendar organized by civil date and mass time.
mass_calendar = romcal.mass_calendar(2026)
# mass_calendar is dict[str, list[dict]]
# Evening masses appear on the previous civil day
easter_vigil_day = mass_calendar.get("2026-04-04")
if easter_vigil_day:
vigil = next((m for m in easter_vigil_day if m["mass_time"] == "EASTER_VIGIL"), None)
if vigil:
print(vigil["liturgical_date"]) # "2026-04-05"
get_date(id, year)
Get a liturgical date by its ID.
easter = romcal.get_date("easter_sunday", 2026) # "2026-04-05"
ash_wed = romcal.get_date("ash_wednesday", 2026) # "2026-02-18"
pentecost = romcal.get_date("pentecost_sunday", 2026) # "2026-05-24"
christmas = romcal.get_date("christmas", 2026) # "2026-12-25"
Any date ID from the liturgical calendar can be used (e.g., easter_sunday, christmas, ordinary_time_5_monday).
Properties
Access the resolved configuration:
print(romcal.calendar) # "france"
print(romcal.locale) # "fr"
print(romcal.epiphany_on_sunday) # True
print(romcal.ascension_on_sunday) # False
print(romcal.corpus_christi_on_sunday) # True
print(romcal.easter_calculation_type) # "GREGORIAN"
print(romcal.context) # "GREGORIAN"
Key Types
For detailed documentation on liturgical types (seasons, ranks, precedence, colors, cycles, mass times), see the romcal documentation.
Error Handling
All operations may raise RomcalError:
from romcal import Romcal, RomcalError
try:
romcal = Romcal()
# Year must be >= 1583 (Gregorian calendar adoption)
calendar = romcal.liturgical_calendar(1500)
except RomcalError as e:
print(f"Romcal error: {e}")
Development
Requirements
Setup
cd bindings/python
# Create virtual environment
uv venv
# Install build tools
uv pip install maturin uniffi-bindgen
# Build and install the native extension
uv run maturin develop
# Install dev dependencies (pytest, ruff, etc.)
uv pip install pytest taskipy ruff mypy
Available Tasks
Using taskipy:
task build # maturin build --release
task develop # maturin develop
task generate-types # Generate Pydantic types from JSON schema
task test # pytest tests/ -v
task test-run # pytest tests/ (without verbose)
task format # ruff format .
task format-check # ruff format --check .
task lint # ruff check .
task lint-fix # ruff check --fix .
task typecheck # mypy src/
Testing
task test # Run tests with verbose output
task test-run # Run tests once
Project Structure
bindings/python/
├── src/
│ └── romcal/
│ ├── __init__.py # Main entry point, API wrapper
│ ├── types.py # Generated types from JSON schema (Pydantic)
│ └── _uniffi/ # Generated UniFFI bindings
├── tests/
│ ├── conftest.py # Pytest fixtures (data loading)
│ ├── test_config.py # Configuration tests
│ ├── test_calendar.py # Calendar generation tests
│ └── test_data_loading.py # Data loading tests
├── examples/
│ └── basic_usage.py # Usage example with data loading
└── pyproject.toml # Project configuration
Running Examples
# Basic usage example (loads data from /data folder)
python examples/basic_usage.py
Related
- romcal - Main Romcal project
- romcal - Core Rust library
- romcal-cli - Command-line interface
- romcal (TypeScript) - TypeScript/JavaScript binding
License
Apache License 2.0. See LICENSE for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file romcal-4.0.0b3.tar.gz.
File metadata
- Download URL: romcal-4.0.0b3.tar.gz
- Upload date:
- Size: 183.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.10.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6543eaeece9ee69f65a8154bf8ac8a496a31264b615cab078c7b4d89f8f75987
|
|
| MD5 |
116479621778beefdf78e5b7be68522e
|
|
| BLAKE2b-256 |
fa749d279e1a2400bab34a92573fdbe7d3dcbcdbb6b9afbff7af4ded5ae69cf0
|
File details
Details for the file romcal-4.0.0b3-py3-none-macosx_11_0_arm64.whl.
File metadata
- Download URL: romcal-4.0.0b3-py3-none-macosx_11_0_arm64.whl
- Upload date:
- Size: 711.0 kB
- Tags: Python 3, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.10.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ef964356a093cbe210163cabc56c8e05dbade6309f92cb3978d28a80c799e116
|
|
| MD5 |
82af975ec1491936dc9e392940c1bfc0
|
|
| BLAKE2b-256 |
e9b86a0e48059262196454d552dbf6d7273c40e7e038fb4aa19f2fb458c88b1b
|