chancellery
Канцелярия — библиотека русского склонения и сборки служебных
документов. Склоняет по падежам ФИО, должности и воинские звания (с
автоопределением рода и согласованием слов во фразе) и собирает готовый
docx по шаблону с русской разметкой, где падеж задаётся местом
подстановки, а не данными.
Изначальное видение и границы — в CONCEPT.md.
Статус: 0.1.0. Движок переехал из
«Дьяка» 0.3.3, где обкатан на настоящих
кадровых документах; поведение сверено с эталоном донора поабзацно.
План переноса — в
specs/T001-engine-extraction/spec.md.
Потребители: «Дьяк» (кадровые документы пачкой из таблицы) и «Летопись» (приказы из кадровой базы).
Быстрый старт
uv add chancellery
Сценарий целиком — таблица со строками данных плюс размеченный шаблон
docx дают папку готовых документов, по одному на строку:
from chancellery import generate_documents
written = generate_documents(
table='employees.xlsx',
template='order_template.docx',
out='out',
filename='{{ Фамилия }}.docx', # необязательно: по умолчанию — по ФИО
)
Если сценарий не подходит (источник данных не таблица, свой цикл, своя
обработка ошибок) — те же слои доступны по отдельности: read_table,
build_context, render_document, check_table. А если документы не
нужны вовсе, а нужно только склонение:
from chancellery import Case, Person, PetrovichInflector, PhraseInflector, build_context
context = build_context(
Person(
cells={
'Фамилия': 'Иванов',
'Имя': 'Пётр',
'Отчество': 'Семёнович',
'Должность': 'старший механик-водитель',
}
),
roles={
'surname': 'Фамилия',
'name': 'Имя',
'patronymic': 'Отчество',
'position': 'Должность',
},
inflector=PetrovichInflector(),
position_inflector=PhraseInflector(),
)
context['ФИО'].inflect(Case.DATV) # Иванову Петру Семёновичу
context['Должность'].inflect(Case.DATV) # старшему механику-водителю
Разметка шаблона
Падеж задаётся местом подстановки, а не данными: один и тот же человек в шапке стоит в именительном, а в теле приказа — в дательном, и шаблон говорит об этом фильтром.
Падежные фильтры:
{{ ФИО | ип }} именительный Иванов Пётр Семёнович
{{ ФИО | рд }} родительный Иванова Петра Семёновича
{{ ФИО | дт }} дательный Иванову Петру Семёновичу
{{ ФИО | вн }} винительный Иванова Петра Семёновича
{{ ФИО | тв }} творительный Ивановым Петром Семёновичем
{{ ФИО | пр }} предложный Иванове Петре Семёновиче
Тег без фильтра даёт именительный. Фильтр применим к любому склоняемому значению — ФИО, части имени, должности, званию, произвольной колонке.
Согласование по полу — фильтр согл, мужская форма первой; пол
берётся из ФИО (определяется автоматически по имени и отчеству):
{{ ФИО | согл('ознакомлен', 'ознакомлена') }}
Теги ФИО. Колонка «ФИО» разбирается на части, а части собираются обратно, поэтому доступны сразу все формы:
{{ ФИО }} Иванов Пётр Семёнович
{{ Фамилия }} Иванов {{ Имя }}, {{ Отчество }} — так же
{{ Инициалы }} Иванов П. С.
{{ Инициалы_впереди }} П. С. Иванов
{{ Инициалы_слитно }} Иванов П.С.
{{ Имя_инициал }} П. одна буква с точкой
Инициалы тоже склоняются: {{ Инициалы | рд }} → «Иванова П. С.».
Пустое отчество не роняет рендер — форма просто становится короче.
Остальные колонки доступны по своему заголовку: {{ Должность | дт }},
{{ Номер приказа }}. Заголовок нормализуется (пробелы → подчёркивания,
спецсимволы вычищаются), поэтому «л/н» в таблице пишется в шаблоне как
{{ л_н }}.
Неизвестная переменная — ошибка, а не пустое место в готовом приказе: шаблон рендерится в строгом режиме. Пустое значение, наоборот, убирается вместе с осиротевшей пунктуацией.
Разработка
Менеджер зависимостей и окружения: uv.
uv sync # поставить зависимости
uv run pytest # прогнать тесты
Зависимости
uv add <pkg> # runtime
uv add --dev <pkg> # dev
Выпуск версии
scripts/publish.sh --test # репетиция на TestPyPI (нужен PYPI_TEST_TOKEN)
scripts/publish.sh # боевой PyPI
Скрипт сам гоняет четыре гейта, собирает колесо и архив исходников,
проверяет артефакты twine и выкладывает. Токен читается из .secrets
(под git-ignore, образец — .secrets.example) и машину не покидает.
Порядок: закрыть версию в CHANGELOG.md, поднять version в
pyproject.toml, слить, поставить git-тег вида 0.1.0, выложить.
Проверки перед push
uv run ruff check .
uv run ruff format --check .
uv run mypy src
scripts/pytest-guard.sh --cov=src --cov-report=term-missing --cov-fail-under=80
Все четыре должны проходить с 0 ошибок. Обходные манёвры (# noqa,
# type: ignore, расширение ignore-секции) — только по согласованию.
Структура проекта
src/— корень исходников.CONCEPT.md— изначальное видение проекта (immutable).DECISIONS.md— архитектурные решения с обоснованиями (ADR-Lite).BOARD.md— рабочая Kanban-доска (To Do / Doing / Done).BACKLOG.md— парковка идей и побочных находок.CHANGELOG.md— журнал заметных изменений.specs/— спецификации крупных фич.CLAUDE.md— проектные правила для Claude (Claude Code).
Методика работы
Проект создан из шаблона vlakir/dreamteam. Подробное описание методики (scope discipline, ритуал spec/clarify/analyze для крупных фич, pre-push контроль) — см. репозиторий шаблона.
Release files for chancellery 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| chancellery-0.1.0.tar.gz | 187.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| chancellery-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 260.7 kB
Release files / chancellery-0.1.0.tar.gz
| Download URL | chancellery-0.1.0.tar.gz |
|---|---|
| Size | 187.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2fcb07d5224d4bc90e6c189518bb7f3777ee421b36ed706f6762a7c15551aec5
|
|
BLAKE2b-256 checksum How to use checksums |
bcfc27778b90f0dd6f3b064a25fe0aa0dbefb4d7e1d76bae457cdf0d3839bcca
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.14 {"installer":{"name":"uv","version":"0.11.14","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / chancellery-0.1.0-py3-none-any.whl
| Download URL | chancellery-0.1.0-py3-none-any.whl |
|---|---|
| Size | 73.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
af2c8b997d3b03b1f14154dafabf96aacb34f21c723c9e85f0556aa5312f63ea
|
|
BLAKE2b-256 checksum How to use checksums |
4f2ec02b4c98a3c61bb356bdf82d7bed13be9c251eb4e75070dbe23e342ef2dc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.14 {"installer":{"name":"uv","version":"0.11.14","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|