postext for Python
Typeset books from Python with Postext: a print-ready
PDF, HTML pages, an EPUB, page images, a Word document or an InDesign package
from a .postext book, a book folder or loose Markdown files.
pip install postext
import postext
report = postext.pdf("book.postext", out="book.pdf", set={"page.dpi": 300})
print(report.output.pages, "pages")
for warning in report.warnings:
print(warning) # warning missingFont (chapters/02.md:14): …
pdf = postext.pdf_bytes(open("book.postext", "rb").read()) # bytes in, bytes out
The package drives the self-contained postext command line, the same
executable as brew install drnachio/postext/postext or npx postext-cli:
the layout is the Sandbox's, and the same book breaks into the same pages.
The wheel is pure Python with no dependencies. The executable of your
system (185 to 230 MB, too large for a wheel) is downloaded on first use
from the GitHub Release of the package's version, checked against the
release's SHA256SUMS and kept in the cache:
| System | Executable |
|---|---|
| macOS, Apple silicon / Intel | postext-macos-arm64 / postext-macos-x64 |
| Linux x86-64 / ARM64 (glibc) | postext-linux-x64 / postext-linux-arm64 |
| Linux x86-64, musl (Alpine) | postext-linux-x64-musl |
| Windows x64 (and ARM, emulated) | postext-windows-x64.exe |
| Environment variable | Effect |
|---|---|
POSTEXT_BIN |
Run this executable instead (Homebrew, Scoop, a local build); nothing is downloaded |
POSTEXT_CACHE_DIR |
Cache folder (default ~/.cache/postext, %LOCALAPPDATA%\postext\cache on Windows); executables go in bin/<version>/, downloaded fonts in fonts/ |
POSTEXT_RELEASE_URL |
Download from a mirror: a URL with {version} where the release's files are |
python -m postext pdf book.postext -o book.pdf runs the command line
itself.
Commands
Every command of the command line is a function. Each runs the command with
--json and returns its report.
| Function | Command | Returns |
|---|---|---|
pdf(book, out=…, pdfx=…, profile=…, color_space=…) |
postext pdf |
Report |
html(book, out=…, mode=…, assets=…) |
postext html |
Report |
epub(book, out=…, layout=…, cover=…) |
postext epub |
Report |
image(book, page="#1", out=…, dpi=…, format=…) |
postext image |
ImageReport |
images(book, out="pages/", pages=…, pattern=…) |
postext images |
Report |
docx(book, out=…, variant=…) |
postext docx |
Report |
import_docx(docx, book=None, out=…, dry_run=…) |
postext import-docx |
ImportDocxReport |
idml(book, out=…, images=…, lines=…, spreads=…, fonts=…) |
postext idml |
Report |
import_idml(idml, out=…, layout=…, links=…, document=…) |
postext import-idml |
ImportIdmlReport |
pack(book, out=…) / unpack(bundle, out=…) |
postext pack / unpack |
Report / UnpackReport |
design(book, out=…, parts=…, design_name=…) |
postext design |
DesignReport |
info(book, pages=True) |
postext info |
InfoReport |
check(book, strict=True) |
postext check |
CheckReport |
build(book, pdf=…, html=…, epub=…, images=…, docx=…, idml=…) |
postext build |
Report |
book is a path (a .postext file, a book folder, a Markdown file), a list
of Markdown files (the chapters, in order), or the bytes of a .postext
bundle. The commands that read a book take the book options:
postext.pdf(
["01.md", "02.md"],
out="notes.pdf",
name="Notes", # --name
config={"page": {"sizePreset": "A5"}}, # --config (a dict or a file)
set={"bodyText.fontSize.value": 11}, # --set, one per key
locale="es", # --locale
chapters=range(1, 3), # --chapters 1-2 (also 3, "1,3-5", [1, 3])
resources="img/", fonts="fonts/", # --resources, --fonts
font_dirs=["~/Fonts"], # --font-dir
offline=True, # --offline: never download fonts
design="novel.postext", # --design: a design file (a path or bytes), or another book
design_parts=["page", "text"], # --design-parts page,text
composition="auto", # --composition: the composition rules of the book's language (or "es", "en-GB"…)
)
design(book, out="novel.postext", parts=["page", "text", "headings"])
takes a book's design into a design file, and design= puts it on any
other book. In idml, fonts=True is the switch that writes the font
files beside the package, not the book option. import_idml reads a bare
.idml or a zipped InDesign package, as a path or as bytes (then give
out, and links for the linked pictures).
Reports and warnings
A Report has ok, command, version, exit_code, pages, book
(name, id, locale, chapters), outputs (Output: kind, path, size,
pages), warnings (Diagnostic: kind, message, severity, at, page, data),
timings and raw, the whole JSON object. InfoReport adds chapters,
resources and fonts; CheckReport adds passed, error_count,
warning_count, contrast, reflow and preflight; DesignReport adds
name and parts; ImportIdmlReport adds layout (pages or flow),
reason, chapters, quality (the import report), fonts,
missing_links and package.
Bytes out
out="-" (or postext.STDOUT) writes to stdout and returns the bytes in
report.content; pdf_bytes, html_bytes, epub_bytes, image_bytes,
docx_bytes, idml_bytes, pack_bytes and design_bytes return them
directly (idml with linked pictures or fonts=True needs a file). A book given as bytes
with no out comes back as bytes.
Errors
| Exception | When |
|---|---|
PostextError |
The command failed (exit code 1); err.report and err.stderr say why |
UsageError |
A wrong option or value (exit code 2) |
ProblemsFound |
check found an error (any warning with strict), or import_docx could not apply an edit (exit code 3); raise_on_problems=False returns the report instead |
BinaryNotFound |
No executable for this system, a failed download or checksum, or a POSTEXT_BIN that is not a file |
One executable, many runs
postext.Postext(binary=None, cwd=None, env=None, timeout=None, offline=None, font_dirs=None)
has the same methods with its own executable, folder, environment and
timeout. Postext().run(["build", "book/", "--pdf", "b.pdf", "--watch"], capture=False)
runs any command as typed.
Each call starts the executable again. A mode that keeps one engine running between calls is planned.
Docs
- Command line: https://postext.dev/en/docs/command-line#python
- Source: https://github.com/drnachio/postext/tree/main/packages/postext-python
MIT licence.
Metadata
Release files for postext 1.81.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 | Provenance | Actions |
|---|---|---|---|---|
| postext-1.81.0.tar.gz | 27.7 kB | With provenance | Details for postext-1.81.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| postext-1.81.0-py3-none-any.whl | Python 3 | none | any | Details for postext-1.81.0-py3-none-any.whl |
Total release size: 54.2 kB
Release files / postext-1.81.0.tar.gz
| Download URL | postext-1.81.0.tar.gz |
|---|---|
| Size | 27.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
cca2e7e895c8dab1f1759fc1c986b87f36828690804c6b7f7a4e0a81c412b7a5
|
|
BLAKE2b-256 checksum How to use checksums |
c0afaced80b646ed0f7e85ec9a4972c24290a9a26a6370f012f9ab1c2bb7bb54
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 13, 2026.
Transparency logRelease files / postext-1.81.0-py3-none-any.whl
| Download URL | postext-1.81.0-py3-none-any.whl |
|---|---|
| Size | 26.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
3547f1254b9776a466ce2792aa632d70eb991dcb1309db4f9f9e13e64a239e7a
|
|
BLAKE2b-256 checksum How to use checksums |
282bc35fcfc945dcb64ef71dcb037935d200b9607733711682925b2452fbf788
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 13, 2026.
Transparency logSecurity for postext 1.81.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
Both files in this release have been uploaded with provenance metadata.
Attestation for postext-1.81.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 13, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.