3 of 10 files were uploaded without provenance metadata. View details.
fop-python
Python bindings for FOP — a high-performance, pure-Rust XSL-FO processor that converts XSL-FO (Extensible Stylesheet Language Formatting Objects) documents to PDF, SVG, and plain text output.
This crate is part of the COOLJAPAN FOP ecosystem and is built with PyO3, providing a native Python extension that runs 10–1200x faster than the original Java Apache FOP.
Description
fop-python exposes the full FOP conversion pipeline to Python via a native extension module. It compiles to a shared library (fop.so / fop.pyd) that can be imported directly from Python. The bindings cover:
- XSL-FO string to PDF bytes
- XSL-FO string to SVG string
- XSL-FO string to plain text string
- File-to-file conversion with automatic format detection
- XSL-FO document validation
- Stateful
FopConverterclass with configurable options - Module-level one-shot convenience functions
The implementation delegates to the same Rust pipeline used throughout the FOP workspace:
XSL-FO XML --> FO Tree --> Area Tree --> PDF / SVG / Text
(fop-core) (fop-layout) (fop-render)
Features
| Feature | Description |
|---|---|
FopConverter class |
Stateful converter object — instantiate once, convert many documents |
convert_to_pdf(fo_xml) |
Convert an XSL-FO string to raw PDF bytes |
convert_to_svg(fo_xml) |
Convert an XSL-FO string to an SVG string |
convert_to_text(fo_xml) |
Convert an XSL-FO string to plain text |
convert_file(input, output) |
Convert a .fo file to PDF/SVG/TXT (format inferred from extension) |
validate(fo_xml) |
Parse and validate an XSL-FO document; returns (valid, node_count, error) |
version() |
Return the crate version string |
| Module-level one-shot functions | fop.convert_to_pdf(), fop.convert_to_svg(), fop.version() |
verbose property |
Enable/disable verbose logging on the converter instance |
Installation
Via pip (maturin-built wheel)
If a pre-built wheel is available on PyPI:
pip install fop2
To build and install from source using maturin:
# Install maturin
pip install maturin
# Clone the repository
git clone https://github.com/cool-japan/fop.git
cd fop/crates/fop-python
# Build and install into the active virtual environment
maturin develop --features extension-module
As a Rust dependency
Add the following to your Cargo.toml:
[dependencies]
fop-python = "0.1.0"
Python Usage
Importing the module
import fop
Using the FopConverter class
FopConverter is the primary API. Instantiate it once and reuse it for multiple conversions:
import fop
# Create a converter instance
converter = fop.FopConverter()
# Inspect the object
print(repr(converter)) # FopConverter(verbose=False)
# Enable verbose mode
converter.verbose = True
Converting XSL-FO to PDF
import fop
fo_xml = """<?xml version="1.0" encoding="UTF-8"?>
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
<fo:simple-page-master master-name="A4"
page-width="210mm" page-height="297mm"
margin-top="20mm" margin-bottom="20mm"
margin-left="25mm" margin-right="25mm">
<fo:region-body/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="A4">
<fo:flow flow-name="xsl-region-body">
<fo:block font-size="18pt" font-weight="bold">Hello, FOP!</fo:block>
<fo:block font-size="12pt" space-before="6pt">
Generated by fop-python — a pure-Rust XSL-FO processor.
</fo:block>
</fo:flow>
</fo:page-sequence>
</fo:root>"""
converter = fop.FopConverter()
pdf_bytes = converter.convert_to_pdf(fo_xml)
with open("output.pdf", "wb") as f:
f.write(pdf_bytes)
print(f"PDF generated: {len(pdf_bytes)} bytes")
Converting XSL-FO to SVG
import fop
converter = fop.FopConverter()
svg_string = converter.convert_to_svg(fo_xml)
with open("output.svg", "w", encoding="utf-8") as f:
f.write(svg_string)
Converting XSL-FO to plain text
import fop
converter = fop.FopConverter()
text = converter.convert_to_text(fo_xml)
print(text)
File-to-file conversion
The output format is automatically detected from the file extension:
.pdf— PDF output (default).svg— SVG output.txt— Plain text output
import fop
converter = fop.FopConverter()
# Convert to PDF
converter.convert_file("document.fo", "document.pdf")
# Convert to SVG
converter.convert_file("document.fo", "document.svg")
# Convert to plain text
converter.convert_file("document.fo", "document.txt")
Validating an XSL-FO document
validate() always returns Ok at the Python level; parse errors are reported in the tuple rather than raised as exceptions:
import fop
converter = fop.FopConverter()
valid, node_count, error = converter.validate(fo_xml)
if valid:
print(f"Document is valid ({node_count} nodes)")
else:
print(f"Validation failed: {error}")
Module-level convenience functions
For one-shot conversions without creating a FopConverter instance:
import fop
# Convert directly
pdf_bytes = fop.convert_to_pdf(fo_xml)
svg_string = fop.convert_to_svg(fo_xml)
# Get version
print(fop.version()) # fop-python 0.1.0
Error handling
Conversion errors are raised as Python RuntimeError exceptions:
import fop
converter = fop.FopConverter()
try:
pdf_bytes = converter.convert_to_pdf("<<<not valid XSL-FO>>>")
except RuntimeError as e:
print(f"Conversion failed: {e}")
try:
converter.convert_file("/nonexistent/path.fo", "/tmp/out.pdf")
except IOError as e:
print(f"File error: {e}")
Building from Source
Prerequisites
- Rust toolchain (1.70+) — install via rustup
- Python 3.8+ with a virtual environment
- maturin (
pip install maturin)
Development build (editable install)
git clone https://github.com/cool-japan/fop.git
cd fop/crates/fop-python
# Activate your virtual environment first, then:
maturin develop --features extension-module
This builds the native extension and installs it directly into the active Python environment, making import fop available immediately.
Release wheel
# Build a release wheel for the current platform
maturin build --release --features extension-module
# The wheel is placed in target/wheels/
pip install target/wheels/fop_python-*.whl
Cargo build (library only, no Python install)
# Build as a cdylib (shared library) from the workspace root
cargo build --release -p fop-python
# Or from the crate directory
cargo build --release
Rust Usage
You can also use fop-python as a Rust library to access the FopConverter struct directly (e.g., in tests or when embedding):
use fop_python::converter::FopConverter;
fn main() {
let converter = FopConverter::new();
let fo_xml = r#"<?xml version="1.0" encoding="UTF-8"?>
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
<fo:simple-page-master master-name="A4"
page-width="210mm" page-height="297mm">
<fo:region-body/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="A4">
<fo:flow flow-name="xsl-region-body">
<fo:block>Hello from Rust!</fo:block>
</fo:flow>
</fo:page-sequence>
</fo:root>"#;
// Returns PyResult<Vec<u8>> — use pyo3::Python::with_gil to call from Rust
// For pure Rust usage, prefer the fop-core / fop-render crates directly.
println!("FopConverter created: {:?}", converter.version());
}
For pure Rust embedding without PyO3 overhead, use the underlying crates directly:
use fop_core::FoTreeBuilder;
use fop_layout::LayoutEngine;
use fop_render::PdfRenderer;
use std::io::Cursor;
let fo_tree = FoTreeBuilder::new().parse(Cursor::new(fo_xml)).unwrap();
let area_tree = LayoutEngine::new().layout(&fo_tree).unwrap();
let pdf_doc = PdfRenderer::new().render(&area_tree).unwrap();
let pdf_bytes = pdf_doc.to_bytes().unwrap();
Feature Flags
| Feature | Default | Description |
|---|---|---|
extension-module |
No | Enables PyO3's extension-module feature, required when building a Python native extension (.so/.pyd). Must be enabled when using maturin build or maturin develop. Do not enable this when using the crate as a pure Rust library dependency, as it links against the Python interpreter in a way that is incompatible with standalone binaries. |
# In Cargo.toml when building as a Python extension:
[features]
extension-module = ["pyo3/extension-module"]
Maturin activates this feature automatically when invoked as a build backend.
Architecture
fop-python is a thin PyO3 binding layer over the FOP Rust workspace crates:
fop-python (PyO3 bindings)
|
+-- fop-render (PdfRenderer, SvgRenderer, TextRenderer)
| |
| +-- fop-layout (LayoutEngine, area tree)
| |
| +-- fop-core (FoTreeBuilder, XML parsing)
| |
| +-- fop-types (Length, Color, FopError, ...)
Error propagation: FopError (Rust) is mapped to RuntimeError (Python) via fop_error_to_py. File I/O errors are mapped to IOError.
Supported XSL-FO Elements
The underlying rendering engine supports the following XSL-FO 1.1 elements:
fo:root,fo:layout-master-set,fo:simple-page-masterfo:region-body,fo:region-before,fo:region-afterfo:page-sequence,fo:flow,fo:static-contentfo:block,fo:inlinefo:table,fo:table-body,fo:table-row,fo:table-cell,fo:table-columnfo:list-block,fo:list-item,fo:list-item-label,fo:list-item-bodyfo:external-graphic,fo:basic-link
294 XSL-FO 1.1 properties are supported with full inheritance semantics.
Performance
| Metric | Java Apache FOP | fop-python (Rust) |
|---|---|---|
| Startup time | ~2000ms (JVM) | <10ms |
| Parse 1000-page doc | ~500ms | <50ms |
| Memory per page | ~50KB | <5KB |
| Throughput vs Java | 1x | 10–1200x faster |
Repository
- Source: https://github.com/cool-japan/fop
- Documentation: https://docs.rs/fop-python
- Issues: https://github.com/cool-japan/fop/issues
License
Copyright 2024 COOLJAPAN OU (Team Kitasan)
Licensed under the Apache License, Version 2.0.
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Metadata
Release files for fop2 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Incomplete provenance
3 of 10 files were uploaded without provenance metadata.
We recommend further investigation before installing these files. View details.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| fop2-0.1.0.tar.gz | 347.3 kB | Without provenance | Details for fop2-0.1.0.tar.gz |
Built distributions (wheels)
Total release size: 11.9 MB
Release files / fop2-0.1.0.tar.gz
Incomplete provenance
This file belongs to a release with incomplete provenance: while other files in this release have provenance metadata, this file does not.
We recommend further investigation before installing this file. View details.
| Download URL | fop2-0.1.0.tar.gz |
|---|---|
| Size | 347.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
399691779aabbcab66ae6bd8457925862c7124a36b756fc20d0dbfa22c221fc3
|
|
BLAKE2b-256 checksum How to use checksums |
4b4056a6a4e94a4092aaf646ab6d4ef79a971d8573e1b7feedb357645de59fad
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.8.7
|
Release files / fop2-0.1.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Incomplete provenance
This file belongs to a release with incomplete provenance: while this file has provenance metadata, other files in this release do not.
We recommend further investigation before installing this file. View details.
| Download URL | fop2-0.1.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 1.3 MB |
| Tags | Linux glibc 2.17+ x86-64 PyPy 3.11 PyPy 3.11 7.3 |
|
SHA-256 checksum How to use checksums |
c21c9cca30d07946f7ba5f95c8c091017061f63b982ff95cc756169541c46f66
|
|
BLAKE2b-256 checksum How to use checksums |
f376145a053259429e24f186a5ac990bc54446d96bf6dcaf79e1d879aac37999
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
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 Mar 2, 2026.
Transparency logRelease files / fop2-0.1.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Incomplete provenance
This file belongs to a release with incomplete provenance: while this file has provenance metadata, other files in this release do not.
We recommend further investigation before installing this file. View details.
| Download URL | fop2-0.1.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl |
|---|---|
| Size | 1.3 MB |
| Tags | Linux glibc 2.17+ ARM64 PyPy 3.10 PyPy 3.10 7.3 |
|
SHA-256 checksum How to use checksums |
3bd2968367ffa0193ddd9db75214c85f529f283e512256e4da12ab9711cfcd0e
|
|
BLAKE2b-256 checksum How to use checksums |
b372ee7f7ba34376ad68cb5c36309c1bb0f719ef94793feceb8552dacac6b6fb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
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 Mar 2, 2026.
Transparency logRelease files / fop2-0.1.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Incomplete provenance
This file belongs to a release with incomplete provenance: while this file has provenance metadata, other files in this release do not.
We recommend further investigation before installing this file. View details.
| Download URL | fop2-0.1.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl |
|---|---|
| Size | 1.3 MB |
| Tags | Linux glibc 2.17+ ARM64 PyPy 3.9 PyPy 3.9 7.3 |
|
SHA-256 checksum How to use checksums |
749f6a8aed6aa7ecfc51e6d9e2b7ecfb964c69dc049a04877ef818f0a89e66cc
|
|
BLAKE2b-256 checksum How to use checksums |
92cfb71aa6d4cde5f08b6ff02454ff6e8cfdcc56ce8e25ce58d801a01e2f5aff
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
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 Mar 2, 2026.
Transparency logRelease files / fop2-0.1.0-cp38-abi3-win_amd64.whl
Incomplete provenance
This file belongs to a release with incomplete provenance: while this file has provenance metadata, other files in this release do not.
We recommend further investigation before installing this file. View details.
| Download URL | fop2-0.1.0-cp38-abi3-win_amd64.whl |
|---|---|
| Size | 1.3 MB |
| Tags | CPython 3.8 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
09b91ea130050d974b1118090da4b90921b68513db66537ea39ac7fb60de46d4
|
|
BLAKE2b-256 checksum How to use checksums |
19ec2dccbcec735a65ac85e2c8c0683923b7d8c527d9486ff128e6e1a12a3a5a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
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 Mar 2, 2026.
Transparency logRelease files / fop2-0.1.0-cp38-abi3-manylinux_2_34_x86_64.whl
Incomplete provenance
This file belongs to a release with incomplete provenance: while other files in this release have provenance metadata, this file does not.
We recommend further investigation before installing this file. View details.
| Download URL | fop2-0.1.0-cp38-abi3-manylinux_2_34_x86_64.whl |
|---|---|
| Size | 1.3 MB |
| Tags | CPython 3.8 Linux glibc 2.34+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
69b51b9cad7585d2edf853b03e59a2bc2fb3d781014d7f2669717a1dc81b9c47
|
|
BLAKE2b-256 checksum How to use checksums |
2a879c0e47df89d41a34a672f21739ac0416c504f7ad01f13ca3e7fafaea449a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.8.3
|
Release files / fop2-0.1.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Incomplete provenance
This file belongs to a release with incomplete provenance: while this file has provenance metadata, other files in this release do not.
We recommend further investigation before installing this file. View details.
| Download URL | fop2-0.1.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 1.3 MB |
| Tags | CPython 3.8 Linux glibc 2.17+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
b3bc00e394bcefc8dfbc63d79d083d40c921f528c118c9b279c682c4fdb42cb2
|
|
BLAKE2b-256 checksum How to use checksums |
bda78c05b93c0f53125cba8ef5b55322d5a7f3b398b242601849cf7d252bb417
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
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 Mar 2, 2026.
Transparency logRelease files / fop2-0.1.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Incomplete provenance
This file belongs to a release with incomplete provenance: while this file has provenance metadata, other files in this release do not.
We recommend further investigation before installing this file. View details.
| Download URL | fop2-0.1.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl |
|---|---|
| Size | 1.3 MB |
| Tags | CPython 3.8 Linux glibc 2.17+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
47afb581a8b80b8ff43e94ae3f5c4814329fdc35328c7822ed23e4f3d1390ad5
|
|
BLAKE2b-256 checksum How to use checksums |
2df717d1e01eeb7aaa99e321bc9c8b059bb5e403e49db081a71a75f5201df85b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
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 Mar 2, 2026.
Transparency logRelease files / fop2-0.1.0-cp38-abi3-macosx_11_0_arm64.whl
Incomplete provenance
This file belongs to a release with incomplete provenance: while other files in this release have provenance metadata, this file does not.
We recommend further investigation before installing this file. View details.
| Download URL | fop2-0.1.0-cp38-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 1.2 MB |
| Tags | CPython 3.8 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
b402b819b807ef56e0b6a2da651a3f22f5510435d51633e22b3a6a5d80007cf5
|
|
BLAKE2b-256 checksum How to use checksums |
d0dc1a7fe062813ce4bbd896c12f6003f8c3413227775e19b2a4ec2dc3b75801
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.8.7
|
Release files / fop2-0.1.0-cp38-abi3-macosx_10_12_x86_64.whl
Incomplete provenance
This file belongs to a release with incomplete provenance: while this file has provenance metadata, other files in this release do not.
We recommend further investigation before installing this file. View details.
| Download URL | fop2-0.1.0-cp38-abi3-macosx_10_12_x86_64.whl |
|---|---|
| Size | 1.3 MB |
| Tags | CPython 3.8 abi3 macOS 10.12+ x86-64 |
|
SHA-256 checksum How to use checksums |
fadcf862f136673eb1cee4585da60be67c6088cf4153d27381ec548bbe1ee82e
|
|
BLAKE2b-256 checksum How to use checksums |
28a8016a24815bcbc4ab958822872f73a8442de830b8f798f25bee84d57aa79e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
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 Mar 2, 2026.
Transparency logSecurity for fop2 0.1.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.
Incomplete provenance
3 of 10 files were uploaded without provenance metadata.
Attestations for fop2-0.1.0.tar.gz
A 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.