cmi-docx is a Python library (by Child Mind Institute) that extends
python-docx with additional tooling for .docx file manipulation: find/replace,
paragraph insertion, style formatting, comments, table formatting, and a
declarative async-first API for document construction.
src/cmi_docx/ # Main package (src layout)
__init__.py # Barrel exports for all public symbols
document.py # ExtendDocument: document-level find/replace/insert
paragraph.py # ExtendParagraph, FindParagraph: paragraph-level ops
run.py # ExtendRun, FindRun: run-level find/replace/format
table.py # ExtendTable, ExtendCell: table/cell formatting
styles.py # Style dataclasses (RunStyle, ParagraphStyle, CellStyle, etc.)
comment.py # add_comment(), CommentPreserver, CommentRange
declarative/ # Declarative async component-based API
base.py # Component base class (async resolve, lazy fields, conditions)
document.py # Document, DocumentTemplate, packing functions
paragraph.py # Paragraph, TextRun, Tab, Break
section.py # Section, Header, Footer, SectionProperties
table.py # Table, TableRow, TableCell
image.py # ImageRun
tests/ # pytest test suite
test_document.py
test_paragraph.py
test_run.py
test_table.py
test_comment.py
declarative/ # Tests for declarative API
test_declarative_basic.py
test_async.py
test_condition.py
test_declarative_table.py
test_template_replacement.py
pyproject.toml # Project metadata, dependencies, and all tool config
justfile # Task runner (agentcheck recipe)
.pre-commit-config.yaml # Pre-commit hooks
docs/pdoc-theme/ # Custom CSS for pdoc-generated API docs
local/ # Gitignored scratch space for local experiments
Always use uv run to execute any command. The project uses uv for package
management. Do not use pip, python, or pytest directly.
# Run tests
uv run pytest
# Run tests with coverage
uv run pytest --cov=src tests --verbose
# Lint (with autofix)
uv run ruff check . --fix
# Format
uv run ruff format .
# Type check
uv run ty check .
# Run all agent checks (lint + typecheck + sergey)
just agentcheck- Framework:
pytestwithpytest-asynciofor async tests. - Test path:
tests/(configured inpyproject.toml). - Source path is
src/(configured viapythonpath = ["src"]). - No
conftest.py; fixtures are defined inline in test files. - Run the full suite with
uv run pytest. Run a single file withuv run pytest tests/test_document.py.
- Ruff handles both linting and formatting. Config selects
ALLrules with specific ignores for formatter conflicts. Google-style docstrings are required. - ty is the primary type checker (not mypy).
- sergey-lint runs additional custom checks.
- Target Python version: 3.12. The project supports 3.12, 3.13, and 3.14.
- src layout: all library code lives under
src/cmi_docx/. - Docstrings: Google convention. Every public function/class needs one.
- Formatting: double quotes, 4-space indent, 88-char line length.
- Types: use specific type hints everywhere; avoid
Any. - Dataclasses: used extensively for styles, find results, and declarative components.
- Async: the declarative API uses
asynciowithasync/awaitthroughout. Components have an asyncresolve()method and children are gathered concurrently. - YAML files: must use
.yamlextension, never.yml(enforced by pre-commit).
- Wrapper/extension classes:
ExtendDocument,ExtendParagraph,ExtendRun,ExtendTable,ExtendCellwrappython-docxobjects and add functionality. - Declarative components:
Componentbase class indeclarative/base.pysupports lazy field evaluation, conditional rendering, and async resolution. - Barrel exports:
__init__.pyre-exports all public symbols so consumers can dofrom cmi_docx import ExtendDocument.
- Runtime:
python-docx(>=1.1.2),lxml(>=6.0.2). - Dev:
pytest,pytest-cov,pytest-asyncio,ruff,ty,pdoc,prek,sergey-lint. - Do not add new dependencies without justification.
uv run ruff check . --fix-- fix lint issues.uv run ruff format .-- format code.uv run ty check .-- ensure no type errors.uv run pytest-- ensure all tests pass.
Or run just agentcheck for the lint/typecheck checks, then
uv run pytest for tests.