Кейс · Бэкенд · Python

ical-forge: iCalendar (RFC 5545), RRULE и подписка

Сервис iCalendar на Python (FastAPI + SQLite, без сторонних библиотек для календаря). Собирает корректный .ics (складывание строк, экранирование, VTIMEZONE из zoneinfo), проверяет чужой файл с номерами строк, разворачивает повторяющиеся события по RRULE и публикует ленты для подписки по ссылке с ETag и ответом 304.

  • Python
  • FastAPI
  • uvicorn
  • SQLite
  • RFC 5545
  • ETag
  • hypothesis
  • mypy --strict
  • ruff
  • Docker
  • GitHub Actions

01 · Как выглядит

Скриншоты

Скриншот проекта «ical-forge: iCalendar (RFC 5545), RRULE и подписка» на экране 1280 пикселей
Десктоп, 1280 px
Скриншот проекта «ical-forge: iCalendar (RFC 5545), RRULE и подписка» на экране телефона, 390 пикселей
Телефон, 390 px

02 · О проекте

Что это и зачем

Сервис iCalendar на Python (FastAPI + SQLite, без сторонних библиотек для календаря). Собирает корректный .ics (складывание строк, экранирование, VTIMEZONE из zoneinfo), проверяет чужой файл с номерами строк, разворачивает повторяющиеся события по RRULE и публикует ленты для подписки по ссылке с ETag и ответом 304.

Ограничения

Не развёртываются частоты SECONDLY, MINUTELY, HOURLY и часть BYWEEKNO, BYYEARDAY, BYHOUR, BYMINUTE, BYSECOND: синтаксис принимается, развёртка возвращает ошибку.

События с TZID не из IANA (например, имена Windows) проверяются, но не разворачиваются.

Это демо-хранилище без аккаунтов; лимит частоты в памяти процесса.

Проект работает на небольшом VPS с демо-данными: без отказоустойчивости и резервных копий.

Что внутри

  • 28 примеров повторов из RFC 5545 §3.8.5.3 сверяются по спискам дат (BYSETPOS, «предпоследний понедельник», пятница 13-е с EXDATE)
  • 119 тестов; hypothesis: круговой проход событие → .ics → событие на произвольном Unicode, unfold(fold(x)) == x, строки не длиннее 75 октетов
  • POST /api/expand на 500 вхождений за 0,2 с; лента около 640 запросов в секунду, p95 45 мс
  • Ключ редактирования хранится только как SHA-256, сравнение за постоянное время

03 · Как запустить

Запуск одной командой

git clone <репозиторий по запросу> ical-forge
cd ical-forge
python -m app

04 · Код

Репозиторий приватный

Исходники лежат в приватном репозитории. Напишите в Telegram, открою доступ.

Запросить код