Drive a running Microsoft Word instance from Python — xlwings, but for Word, and LLM-friendly.
Project description
wordlive
Drive a running Microsoft Word instance from Python — xlwings, but for Word.
Built for both human scripting and LLM agents. Windows-only.
Install
pip install wordlive
(Requires Python 3.13+ and pywin32 on Windows.)
Python
import wordlive as wl
with wl.attach() as word:
doc = word.documents.active
# Reads
outline = doc.outline()
bookmarks = doc.bookmarks.list()
# Polite writes — preserves the user's cursor and view, atomic Ctrl-Z.
with doc.edit("Update address block"):
doc.bookmarks["Address"].set_text("123 Main St")
doc.content_controls["Signatory"].set_text("Jane Doe")
doc.heading("Introduction").insert_paragraph_after("New context paragraph.")
CLI
JSON in, JSON out — designed to drop straight into an LLM tool-use loop:
wordlive status
wordlive outline # heading structure (heading:N)
wordlive outline --all # every paragraph (para:N) — alias of `paragraphs`
wordlive paragraphs # same: para:N, level, offsets, text
wordlive read bookmark Address
wordlive write bookmark Address --text "123 Main St"
# Insert a new paragraph relative to ANY anchor (heading, paragraph, bookmark, …):
wordlive insert --anchor-id heading:1 --text "..." # after (default)
wordlive insert --anchor-id para:3 --text "..." --before
# Address anchors by ID (the IDs `outline`/`paragraphs` emit — `heading:N`, `para:N`, `bookmark:NAME`, `cc:NAME`):
wordlive replace --anchor-id heading:3 --text "Updated section text"
wordlive go-to --anchor-id bookmark:Address
# Explicit cursor surface (the non-preferred mode — deliberately moves the cursor):
wordlive cursor read # where is the cursor? which para:N?
wordlive cursor write --text "inserted here" # type at the cursor
# Styles + paragraph formatting (atomic-undo):
wordlive style list
wordlive style apply --anchor-id heading:3 --name "Heading 2"
wordlive format-paragraph --anchor-id heading:3 --alignment center --space-before 6
# Tables (cells are anchors: table:N:R:C):
wordlive table list
wordlive table read 1
wordlive replace --anchor-id table:1:2:2 --text "$450"
wordlive table add-row --table 1 --values '["Lodging", "$600"]'
# Collaboration: comments + track changes (the polite, non-destructive surface):
wordlive comment add --anchor-id heading:3 --text "Please expand this." --author Bot
wordlive comment list
wordlive comment resolve --index 1
wordlive track on # record edits as revisions; `track off` to stop
# Lists & numbering (any anchor's paragraphs):
wordlive list apply --anchor-id heading:6 --type numbered
wordlive list restart --anchor-id heading:6
# Sections, headers & footers (header:S:WHICH / footer:S:WHICH):
wordlive section list
wordlive header write --section 1 --text "ACME Corporation"
wordlive footer read --section 1
# Batch multiple ops in a single Ctrl-Z:
wordlive exec --script ops.json
Where ops.json looks like:
{
"label": "Update report",
"ops": [
{"op": "write_bookmark", "name": "Address", "text": "123 Main St"},
{"op": "write_cc", "name": "Signatory", "text": "Jane Doe"},
{"op": "insert_paragraph", "anchor_id": "heading:3", "text": "New risk paragraph."},
{"op": "replace", "anchor_id": "heading:3", "text": "Updated section text"},
{"op": "apply_style", "anchor_id": "heading:3", "name": "Heading 2"},
{"op": "format_paragraph", "anchor_id": "heading:3", "alignment": "center", "space_before": 6}
]
}
Exit codes: 0 ok, 2 anchor-not-found, 3 Word-busy, 4 Word-not-running, 1 other.
Design
- Politeness first — operations preserve the user's
Selection, view, and scroll. The user keeps editing alongside you. - Semantic anchors over
Selection— operations target bookmarks, content controls, or headings — never the live cursor unless you ask. - Atomic undo — every
doc.edit()opens a WordUndoRecord, so a single Ctrl-Z reverts the whole block. - Escape hatch — every wrapper exposes
.comfor the raw COM object; you're never blocked by missing coverage.
See spec.md for the full design.
Project details
Release history Release notifications | RSS feed
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 wordlive-0.8.0.tar.gz.
File metadata
- Download URL: wordlive-0.8.0.tar.gz
- Upload date:
- Size: 158.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
608df7c5f6a78c8746928b815447dbaf2aff1618fc1ca6fbfd83bd740376881d
|
|
| MD5 |
44419754224bb43ec80d172a5d6a0b86
|
|
| BLAKE2b-256 |
f0f44c8577c1d0f1404f21388159318830479e348f0e486f189532a8c2db4806
|
Provenance
The following attestation bundles were made for wordlive-0.8.0.tar.gz:
Publisher:
release.yml on thomas-villani/wordlive
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
wordlive-0.8.0.tar.gz -
Subject digest:
608df7c5f6a78c8746928b815447dbaf2aff1618fc1ca6fbfd83bd740376881d - Sigstore transparency entry: 1592327869
- Sigstore integration time:
-
Permalink:
thomas-villani/wordlive@519ab4f203a5bad527c63fad7142f8e10a7328d4 -
Branch / Tag:
refs/tags/v0.8.0 - Owner: https://github.com/thomas-villani
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@519ab4f203a5bad527c63fad7142f8e10a7328d4 -
Trigger Event:
push
-
Statement type:
File details
Details for the file wordlive-0.8.0-py3-none-any.whl.
File metadata
- Download URL: wordlive-0.8.0-py3-none-any.whl
- Upload date:
- Size: 55.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
891fd416b0703631c5d681692a71193aa0dddd4181ad18e76c516feade7182dc
|
|
| MD5 |
e3c7170f2b5be8fb38aca0847e8b7940
|
|
| BLAKE2b-256 |
e0b93a59bca2b4fad4d014de3b1a22244aa29fe11a9ba49d52d65e5a46d98883
|
Provenance
The following attestation bundles were made for wordlive-0.8.0-py3-none-any.whl:
Publisher:
release.yml on thomas-villani/wordlive
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
wordlive-0.8.0-py3-none-any.whl -
Subject digest:
891fd416b0703631c5d681692a71193aa0dddd4181ad18e76c516feade7182dc - Sigstore transparency entry: 1592327896
- Sigstore integration time:
-
Permalink:
thomas-villani/wordlive@519ab4f203a5bad527c63fad7142f8e10a7328d4 -
Branch / Tag:
refs/tags/v0.8.0 - Owner: https://github.com/thomas-villani
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@519ab4f203a5bad527c63fad7142f8e10a7328d4 -
Trigger Event:
push
-
Statement type: