Кейс · Бэкенд · 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 · Как выглядит
Скриншоты


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 app04 · Код
Репозиторий приватный
Исходники лежат в приватном репозитории. Напишите в Telegram, открою доступ.
Запросить код