Generate hierarchical calendar pages in Notion (Year > Quarter > Month > Week > Day) with optional recurring tasks.
Project description
Notion Calendar Generator
Generate a full hierarchical calendar in Notion with interconnected databases: Year > Quarters > Months > Weeks > Days.
Installation
pip install notion-calendar-generator
Setup
1. Create a Notion integration
Create an integration at notion.so/my-integrations and copy the API key.
2. Create Notion databases
Create five databases in Notion (yearly, quarterly, monthly, weekly, daily) and share them with your integration. Each database needs at minimum:
- A title property
- A Date property
- Relation properties linking to parent databases:
- Quarterly →
🕯 annual-data(relates to yearly) - Monthly →
🕯 annual-data+❄ quarterly-data - Weekly →
🌘 monthly-data - Daily →
🏁 weekly-data
- Quarterly →
3. Configure environment
Create a .env file:
NOTION_KEY=secret_xxx
YEARLY_DATA_ID=xxx
QUARTERLY_DATA_ID=xxx
MONTHLY_DATA_ID=xxx
WEEKLY_DATA_ID=xxx
DAILY_DATA_ID=xxx
STEPS_DATA_ID=xxx
For test databases, use the same keys prefixed with TEST_ (e.g. TEST_NOTION_KEY).
STEPS_DATA_ID is only required if you use the --tasks feature.
Usage
# Generate calendar for a year
nocage 2025
# Use a custom .env path
nocage 2025 --env-path /path/to/.env
# Run against test databases
nocage 2025 --test
Caching
Page IDs are cached locally in .nocage/cache.db (SQLite) to make operations idempotent -- running the same year twice won't create duplicates.
Stale cache handling
If pages were deleted from Notion but still exist in cache:
# Default: error and exit with a message
nocage 2025
# Delete stale entries from cache and recreate pages
nocage 2025 --refresh-cache
# Recreate missing pages in Notion and update cache
nocage 2025 --refresh-notion
# Skip caching entirely (original behavior, will create duplicates)
nocage 2025 --no-cache
Generated structure
For year 2025, the tool creates:
| Type | Count | Name format | Example |
|---|---|---|---|
| Year | 1 | YYYY |
2025 |
| Quarter | 4 | YY-QN |
25-Q1 |
| Month | 12 | YY-Month |
25-January |
| Week | ~52 | YY-week-N |
25-week-1 |
| Day | 365/366 | YY-day-N |
25-day-1 |
Recurring tasks
Generate recurring task pages in Notion's steps database, with relations to pages in trees, seas, and/or hikes databases.
Setup
- Create a steps database in Notion with:
- A title property
- A Date property
- Relation properties:
🌲 trees,🌊 seas,🧗 hike
- Add
STEPS_DATA_IDto your.env
Task config (tasks.yaml)
The config has two sections: aliases (friendly names for Notion page IDs) and tasks (what to generate).
aliases:
trees:
programming: "notion-page-id-for-programming-tree"
fitness: "notion-page-id-for-fitness-tree"
seas:
work: "notion-page-id-for-work-sea"
hikes:
wellness: "notion-page-id-for-wellness-hike"
Under relations in each task, reference aliases by name instead of raw IDs. Relations are optional and variable — a task can relate to any combination of trees, seas, and hikes.
Frequency types
There are four frequency types. Each task uses exactly one.
1. Interval: every + unit
Repeat every N days, weeks, months, quarters, or years. Use start_date to control when the first occurrence lands (defaults to Jan 1).
# Every 2 days starting Jan 1
- name: "Clean cat litter"
frequency:
every: 2
unit: days
start_date: 2025-01-01
# Every 2 weeks starting Jan 6 (a Monday)
- name: "Biweekly retro"
frequency:
every: 2
unit: weeks
start_date: 2025-01-06
# Monthly on the 15th
- name: "Monthly review"
frequency:
every: 1
unit: months
start_date: 2025-01-15
# Quarterly on the 1st
- name: "Quarterly goals"
frequency:
every: 1
unit: quarters
start_date: 2025-01-01
For monthly/quarterly frequencies, the day from start_date is preserved. Days that don't exist in a month are clamped (e.g. the 31st becomes the 28th in February).
2. Days of week: days_of_week
Repeat on specific weekdays, every week.
# Every Monday and Thursday
- name: "Weekly standup"
frequency:
days_of_week: [monday, thursday]
# Every Saturday
- name: "Weekly reset"
frequency:
days_of_week: [saturday]
3. Even/odd day of month: day_of_month
Repeat on every even or odd day-of-month (2nd, 4th, 6th... or 1st, 3rd, 5th...).
# Every even day (2nd, 4th, 6th, 8th, ... 28th, 30th)
- name: "Alom pucolas"
frequency:
day_of_month: even
4. Nth weekday of month: weekday_of_month
Repeat on a specific weekday position within a month. Optionally restrict to specific months.
Positions: first, second, third, fourth, last.
# Last Saturday of every month
- name: "Monthly reset"
frequency:
weekday_of_month:
position: last
day: saturday
# First Saturday of each quarter (Jan, Apr, Jul, Oct)
- name: "Quarterly reset"
frequency:
weekday_of_month:
position: first
day: saturday
months: [january, april, july, october]
# Second Wednesday of every month
- name: "Book club"
frequency:
weekday_of_month:
position: second
day: wednesday
Running
# Generate calendar + recurring tasks
nocage 2025 --tasks tasks.yaml
# With caching options
nocage 2025 --tasks tasks.yaml --refresh-cache
Each step is created as "Task name - YYYY-MM-DD" in the steps database, with its Date property set and relations linked.
Development
Running tests
poetry install
poetry run pytest tests/ --cov=notion_calendar_generator
Releasing a new version
# 1. Bump version (patch/minor/major)
poetry version minor
# 2. Build
poetry build
# 3. Test on TestPyPI first
poetry publish -r testpypi
# 4. Publish to PyPI
poetry publish
Project details
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 notion_calendar_generator-0.1.0.tar.gz.
File metadata
- Download URL: notion_calendar_generator-0.1.0.tar.gz
- Upload date:
- Size: 17.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.2.1 CPython/3.14.0 Darwin/25.2.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dc60167663020baf431d13aee1232f1b42087de4e2e7bd38e0da264c1798a918
|
|
| MD5 |
328d7fd039238cff7919b49bdaa439ba
|
|
| BLAKE2b-256 |
9dd9fa9c065616e5ca3c208b0c6d8d3297dd3f2048756685914b44875a3f9039
|
File details
Details for the file notion_calendar_generator-0.1.0-py3-none-any.whl.
File metadata
- Download URL: notion_calendar_generator-0.1.0-py3-none-any.whl
- Upload date:
- Size: 19.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.2.1 CPython/3.14.0 Darwin/25.2.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
897991c7307381e47ba488d3ead6b20914a71ed1266fbe5ac83acc4285b76bcc
|
|
| MD5 |
55c69a005c236538c3091856fda76d48
|
|
| BLAKE2b-256 |
2c0712a9ba572e320c35bc70893c882e80c9bb6031bf814778ed4a6fc4fe2835
|