Skip to main content

ezsxf

A fast SXF parser and drawing converter for Python, implemented in Rust with PyO3.

ezsxf supports both SXF formats:

  • P21 (ISO-10303-21 based)
  • SFC (SXF feature blocks)

Status

The SFC parser covers all 34 feature types in the SXF Ver.3.1 SFC specification, including resolved drawing/compound-figure/composite-curve structure. The P21 reader currently exposes the generic Part 21 entity representation.

Features

  • Parse P21 and SFC from file path, text, or bytes
  • Decode SFC files as UTF-8 or Windows Shift-JIS/CP932 without lossy replacement
  • Strict and lenient parsing modes
  • Structured parse output (header, entities, typed_features, model, warnings)
  • Resolve layer/style code tables, compound-figure placements, and hatch boundaries
  • Decode ATRF/ATRU/ATRS attribute attachments separately from drawing groups
  • Validate compound-figure placement counts, hierarchy, and drawing-group transforms
  • Convert SFC drawings to AutoCAD 2007 ASCII DXF without another runtime dependency
  • Draw SFC drawings with the optional matplotlib backend
  • Python API + CLI (ezsxf / python -m ezsxf)

Installation

python -m venv .venv
source .venv/bin/activate
pip install maturin
maturin develop

Install the plotting extra when using the matplotlib backend:

pip install ".[plot]"

Quick Start

import ezsxf

result = ezsxf.parse_sfc("./data/D0LS004ZSFC/D0LS004Z.SFC", strict=True)
print(result["format"])          # "sfc"
print(len(result["typed_features"]))
print(result["model"]["sheet"]["component_ids"])

Title-block (sheet) attribute names

SXF represents title-block information in two related places. The drawing_attribute_feature stores the drawing-wide values and is returned in typed_features with kind == "drawing_attribute". Text drawn in the title block is linked to those values by an ATRS attribute attachment. By contrast, drawing_sheet_feature (kind == "drawing_sheet") describes the paper size and orientation; model["sheet"] is the resolved paper/container structure, not the title-block metadata.

The following strings are the exact, machine-readable predefined attribute names used in an ATRS attachment. They are case-sensitive literals and must not be translated or replaced by the S-xx catalogue identifier. All eleven attributes have the predefined SXF type STR.

Catalogue ID Exact attribute_name SFC field / Python key Meaning
S-05 表題_事業名 P_Name / project_name Project name
S-06 表題_工事名 C_Name / construction_name Construction name
S-07 表題_契約区分 C_type / contract_type Contract type
S-08 表題_図面番号 D_number / drawing_number (before $$) Drawing number
S-09 表題_図面総数 D_number / drawing_number (after $$) Total drawing count
S-10 表題_図面種別 D_type / drawing_type Drawing type
S-11 表題_尺度 D_Scale / drawing_scale Scale
S-12 表題_図面名 D_title / drawing_name Drawing name
S-13 表題_年月日 D_Year, D_Month, D_Day / drawing_year, drawing_month, drawing_day Drawing date
S-14 表題_会社名 C_Contractor / contractor_name Contractor name
S-15 表題_事務所名 C_Owner / owner_name Owner/commissioning organization name

An explicit-type attachment name has this form:

$$ATRS$$<figure-id>$$<attribute-name>$$STR

For example, $$ATRS$$9$$表題_事業名$$STR is exposed at model["attribute_attachments"][...]["attribute"] as:

{
    "mechanism": "ATRS",
    "figure_id": "9",
    "attribute_name": "表題_事業名",
    "attribute_type": "STR",
    "unit": None,
}

Because ATRS applies to a text feature, that feature's displayed text is the attribute value; there is no separate attribute_value key. The type and unit may be omitted from the encoded name, in which case their parsed values are None.

For a title-block value drawn on multiple lines, use the unsuffixed predefined name for a single line. For multiple lines, the SXF specification's published form appends an ASCII space and a 1-based ASCII line number, for example 表題_工事名 1 and 表題_工事名 2. ezsxf preserves this suffix verbatim and does not fold the line-specific names back to the base name.

There are two compound-field rules to keep separate from the ATRS names:

  • D_number / drawing_number stores <drawing-number>$$<total-count> when a total count is present, while title-block text uses separate 表題_図面番号 and 表題_図面総数 attachments.
  • 表題_年月日 is one text attribute, while drawing_attribute_feature exposes its date as the three integer keys drawing_year, drawing_month, and drawing_day.

Convert the original input or an already parsed result to DXF:

ezsxf.to_dxf("./data/D0LS004ZSFC/D0LS004Z.SFC", "drawing.dxf")

parsed = ezsxf.parse_sfc("./data/D0LS004ZSFC/D0LS004Z.SFC")
dxf_text = ezsxf.to_dxf(parsed)

Draw with matplotlib and save through the returned Axes:

ax = ezsxf.plot("./data/D0LS004ZSFC/D0LS004Z.SFC")
ax.figure.savefig("drawing.png", dpi=200, bbox_inches="tight")

Both backends share the same hierarchy, placement, layer, color, line type, line width, text, dimension, and hatch conversion. Curves are converted to polylines; use curve_segments to control the approximation resolution.

Converters that need true curves can read PathPrimitive.curve (CurveGeometry): for circle, arc, ellipse and elliptical-arc sources it holds the exact curve behind the sampled points, already transformed through compound-figure placements. The curve is center + axis_u*cos(t) + axis_v*sin(t) for t from start_param to end_param; axis_u/axis_v are conjugate semi-diameters, so a circle placed with unequal X/Y ratios is reported as the ellipse it becomes.

Drawing conversion currently targets SFC input. Externally defined symbols are shown as insertion markers, while externally defined and tiled hatch patterns retain only boundaries marked visible by the SXF data.

CLI

# smoke test
python -m ezsxf

# parse to JSON
python -m ezsxf parse sfc ./data/D0LS004ZSFC/D0LS004Z.SFC --pretty
python -m ezsxf parse p21 ./data/D0LS004ZP21/D0LS004Z.P21 --lenient

# convert SFC to DXF
python -m ezsxf to-dxf ./data/D0LS004ZSFC/D0LS004Z.SFC drawing.dxf

# save or interactively display a matplotlib drawing
python -m ezsxf plot ./data/D0LS004ZSFC/D0LS004Z.SFC drawing.png --dpi 200
python -m ezsxf plot ./data/D0LS004ZSFC/D0LS004Z.SFC

Development

cargo fmt --check
cargo clippy --all-targets --all-features -- -D warnings
cargo test

# Python-level tests
python -m unittest discover -s tests -p 'test_*.py' -v

Repository Layout

  • src/*.rs: Rust parser, resolved model, and PyO3 bindings
  • src/ezsxf/: Python API, CLI, DXF writer, matplotlib backend, and stubs
  • data/: SXF sample datasets used for validation

License

MIT License. See LICENSE.

Metadata

Release files for ezsxf 0.1.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for ezsxf 0.1.2
File Size Uploaded
ezsxf-0.1.2.tar.gz 79.3 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for ezsxf 0.1.2
File Interpreter ABI Platform
ezsxf-0.1.2-cp39-abi3-win_amd64.whl CPython 3.9 abi3 Windows x86-64 Details
ezsxf-0.1.2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.9 abi3 Linux glibc 2.17+ x86-64 Details
ezsxf-0.1.2-cp39-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl CPython 3.9 abi3 macOS 10.12+ universal2 (ARM64, x86-64), macOS 11.0+ ARM64, macOS 10.12+ x86-64 Details

Total release size: 2.2 MB

Release files / ezsxf-0.1.2.tar.gz

Download URL ezsxf-0.1.2.tar.gz
Size 79.3 kB
Tags Source
SHA-256 checksum
How to use checksums
5f5c23c3cd5628745b991f2aef3d6a1dbff343883385704bea24045b83de119b
BLAKE2b-256 checksum
How to use checksums
589ab9066fb267b351fe140bfeb2eeeb041762035cb7a9bac610d2c6e94abc85
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Sep 21, 2026.

Transparency log

Release files / ezsxf-0.1.2-cp39-abi3-win_amd64.whl

Download URL ezsxf-0.1.2-cp39-abi3-win_amd64.whl
Size 462.6 kB
Tags CPython 3.9 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
5680778e771b7defd7b51bd7f982287356fc15a316b7e916b8f8961fe4b0392c
BLAKE2b-256 checksum
How to use checksums
f61107de614346eb85b2aeb52ff7bdef433cca7c873b2028d2667f5998ca8409
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Sep 21, 2026.

Transparency log

Release files / ezsxf-0.1.2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL ezsxf-0.1.2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 593.6 kB
Tags CPython 3.9 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
f6563822c6ccf742b244eaa487770d3936df3f790f10a0a8540f5805914cc9a0
BLAKE2b-256 checksum
How to use checksums
847e0ff41850dae0dff859983fd6d689012972240cb80d13a0709af7e6f93fc5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Sep 21, 2026.

Transparency log

Release files / ezsxf-0.1.2-cp39-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl

Download URL ezsxf-0.1.2-cp39-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
Size 1.1 MB
Tags CPython 3.9 abi3 macOS 10.12+ universal2 (ARM64, x86-64) macOS 10.12+ x86-64 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
0a4f62ce5016478344f8a67e19175489a4806c5e71fcfb742ec4849261eb7a69
BLAKE2b-256 checksum
How to use checksums
bf5190167429f2ffd4d816fcda637bb4155e93e0d1455b4a98429aaec9e6dc24
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Sep 21, 2026.

Transparency log

Release history Release notifications | RSS feed

0.3.4

5 release files

0.3.3

4 release files

0.3.2

4 release files

0.3.1

4 release files

0.3.0

4 release files

0.2.0

4 release files

This release

0.1.2 This release

4 release files

0.1.1

4 release files

0.1.0

4 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page