Python bindings and integrations for the Rust hangulang document conversion engine
Project description
hangulang-python
hangulang-python은 HWP 5.0 및 HWPX 문서(한컴오피스 / 한글)를
Python에서 다루기 위한 hangulang Rust core의 Python binding / integration
package입니다.
Rust hangulang은 rhwp 파서 코어 위에서
문서를 semantic IR로 낮추고, DocLang XML, semantic payload, Markdown, resource
asset/URI 참조를 생성합니다. hangulang-python은 이 엔진을 Python wheel,
Pythonic API, typed error, CLI, optional integration 형태로 제공합니다.
상태: v0.1.0 initial release — 활발히 개발 중입니다. 현재 native extension은
vendor/hangulangsubmodule의 Rusthangulang엔진을 연결합니다. crates.io dependency 전환과 wheel release 정책 고도화는 후속 릴리즈에서 다룹니다.
왜 만들었나
HWP/HWPX는 한국 공공기관, 법무, 교육, 기업 문서 워크플로에서 여전히 중요합니다. 하지만 Python 문서 처리 생태계에서는 PDF/DOCX에 비해 HWP/HWPX의 구조화된 extraction 도구가 부족합니다.
hangulang-python은 이 공백을 다음 역할로 채웁니다:
- Rust parser/exporter를 재사용합니다. HWP 파싱을 Python에서 다시 구현하지
않고, Rust
hangulang이 검증한 semantic extraction 결과를 Python으로 노출합니다. - 텍스트가 아니라 구조를 전달합니다. DocLang XML, Markdown, semantic payload, asset reference, layout metadata를 first-class output으로 다룹니다.
- Python workflow에 맞춥니다.
dict,str, dataclass option, typed exception, CLI entrypoint를 제공합니다. - 무거운 통합은 선택 사항입니다. LangChain, Docling adapter는 core conversion API와 분리합니다.
rhwpraw model을 직접 노출하지 않습니다. 저수준 parser 구조가 아니라, downstream pipeline에서 바로 쓰기 쉬운 semantic export 계약을 제공합니다.
프로젝트 범위
hangulang-python은 Rust hangulang의 대체제가 아니라, Python 배포와 통합을 위한
wrapper layer입니다.
| 레이어 | 책임 |
|---|---|
rhwp |
HWP/HWPX 파일 포맷 파싱, 내부 문서 모델, 렌더 트리 제공 |
hangulang Rust core |
rhwp 모델을 semantic IR로 낮추고 DocLang / payload / Markdown / asset을 생성 |
hangulang-python native extension |
PyO3 경계에서 Rust core 호출, JSON/문자열/asset 반환 |
| Python API | Pythonic 함수, 옵션 dataclass, typed exception, asset write 정책 |
| Integrations | LangChain, Docling 등 외부 adapter |
rhwp-python이 저수준 parser binding에 가깝다면, hangulang-python은 바로 사용할
수 있는 고수준 문서 변환 API를 지향합니다.
설치
현재는 alpha 개발 상태입니다. Python 3.10+와 Rust toolchain이 필요합니다.
개발 환경:
git submodule update --init --recursive
uv venv --python 3.12 .venv
uv pip install -e '.[dev]'
native extension을 명시적으로 다시 빌드할 때:
VIRTUAL_ENV=.venv .venv/bin/maturin develop
wheel build:
.venv/bin/maturin build --interpreter .venv/bin/python
의존성 참고: Rust core는
vendor/hangulangGit submodule로 고정합니다. Cargo dependency는 package 이름hangulang을hangulang-enginealias로 가져옵니다.hangulang-engine = { package = "hangulang", path = "vendor/hangulang", features = ["serde"] }
빠른 시작
Python API
from hangulang import convert_to_doclang, convert_to_markdown, convert_to_payload
xml = convert_to_doclang("document.hwp")
markdown = convert_to_markdown("document.hwpx")
payload = convert_to_payload("document.hwp", include_locations=True)
입력은 파일 경로 또는 bytes를 받을 수 있습니다:
from pathlib import Path
from hangulang import convert_to_payload
data = Path("document.hwp").read_bytes()
payload = convert_to_payload(data)
옵션이 늘어나는 경우 ConversionOptions를 사용할 수 있습니다:
from hangulang import ConversionOptions, convert_to_doclang
options = ConversionOptions(include_locations=True)
xml = convert_to_doclang("document.hwp", options)
출력 API
| API | 출력 | 비고 |
|---|---|---|
convert_to_doclang |
str |
DocLang v0.6 XML |
convert_to_markdown |
str |
같은 Rust semantic IR에서 직접 생성 |
convert_to_payload |
dict |
stable semantic payload JSON을 Python dict로 반환 |
extract_assets |
list[ExtractedAsset] |
embedded image/resource asset 추출 또는 참조 |
Asset 처리
이미지는 Rust core의 resource policy를 통해 data URI, asset file, URI prefix로 다룰 수 있습니다.
from hangulang import AssetPolicy, extract_assets
assets = extract_assets(
"document.hwp",
asset_policy=AssetPolicy.WRITE,
output_dir="assets",
)
for asset in assets:
print(asset.path, asset.mime_type, asset.uri)
CLI
Python package는 hangulang console script를 제공합니다.
hangulang convert document.hwp --format doclang
hangulang convert document.hwp --format markdown
hangulang convert document.hwp --format payload --locations
hangulang assets document.hwp --out assets/
CLI는 별도 변환 구현을 갖지 않습니다. public Python API를 얇게 호출하므로, API와 CLI의 동작은 같은 Rust core를 공유합니다.
옵션과 오류
ConversionOptions
from hangulang import AssetPolicy, ConversionOptions
options = ConversionOptions(
include_locations=True,
asset_policy=AssetPolicy.INLINE,
report_losses=False,
)
| 옵션 | 기본값 | 의미 |
|---|---|---|
include_locations |
False |
layout location / bbox metadata 요청 |
bbox_resolution |
"none" |
Python API용 bbox 해상도 의도 표현 |
asset_policy |
AssetPolicy.INLINE |
inline, write, URI reference 등 asset 처리 방식 |
asset_output_dir |
None |
asset write 정책에서 사용할 출력 디렉터리 |
uri_prefix |
None |
downstream storage용 asset URI prefix |
report_losses |
False |
loss reporting API 확장용 예약 필드 |
예외
| 예외 | 의미 |
|---|---|
HangulangError |
모든 package error의 base class |
UnsupportedFormatError |
지원하지 않는 입력 형식, 암호화/배포용 문서 등 |
ParseError |
파일 읽기 또는 parser 단계 실패 |
ConversionError |
XML/JSON/asset 직렬화 등 변환 단계 실패 |
Optional integrations
Core package는 LangChain이나 Docling을 필수 의존성으로 설치하지 않습니다.
| 모듈 | 상태 | 역할 |
|---|---|---|
hangulang.integrations.langchain |
implemented | block/document 단위 LangChain Document loader |
hangulang.integrations.docling |
implemented | Docling handoff / payload / DocLang / Markdown adapter |
LangChain integration은 langchain-core>=1.0,<2.0을 기준으로 분리합니다:
uv pip install -e '.[langchain]'
LangChain loader는 기본적으로 semantic payload의 텍스트 블록을 각각 하나의
Document로 반환하고, source, schema_version, doclang_version, block_id,
block_kind, page_number, bbox, resource metadata를 가능한 범위에서 보존합니다.
from hangulang.integrations.langchain import HangulangLoader
docs = HangulangLoader("document.hwp", include_locations=True).load()
문서 전체를 하나의 Document로 받아야 하는 경우:
docs = HangulangLoader("document.hwp", mode="document").load()
Docling adapter는 특정 Docling runtime class에 hard dependency를 두지 않고, framework-neutral handoff dict를 반환합니다. 필요하면 payload, DocLang XML, Markdown만 따로 받을 수 있습니다.
from hangulang.integrations.docling import HangulangDoclingAdapter
adapter = HangulangDoclingAdapter(include_locations=True)
handoff = adapter.convert("document.hwp", format="handoff")
xml = adapter.convert("document.hwp", format="doclang")
아키텍처
HWP 5.0 (.hwp) ─┐
├─► hangulang Rust core ─┬─► DocLang XML ───────► Python str
HWPX (.hwpx) ──┘ ├─► semantic payload ─► Python dict
├─► Markdown ─────────► Python str
└─► resource assets ──► ExtractedAsset
Python API / CLI ─► PyO3 native extension ─► Rust convert APIs
Python layer의 원칙:
- parser logic은 Rust에 둡니다.
- Python은 API 안정성, packaging, typing, 오류 매핑, integration을 담당합니다.
- heavy downstream dependency는 optional extra 또는 별도 adapter에 둡니다.
- public API는 procedural function을 먼저 안정화하고, 반복 변환/상태가 필요해질 때 object-oriented API를 추가합니다.
개발
.venv/bin/python -m pytest
.venv/bin/python -m ruff check .
.venv/bin/python -m mypy python/hangulang
cargo test
.venv/bin/maturin build --interpreter .venv/bin/python
현재 Python 테스트는 vendor/hangulang/tests/fixtures의 Rust hangulang fixture
corpus를 재사용합니다.
로드맵
hangulangRust submodule을 CI와 wheel build 흐름에 포함.- CI에서 Python test, Rust extension build, type check, wheel smoke test 실행.
convert_to_payloadloss reporting과 Python option model 정교화.- asset URI/write 정책의 downstream contract 확정.
- LangChain loader chunking strategy와 metadata schema 안정화.
- Docling runtime plugin contract가 확정되면 handoff adapter를 공식 backend로 연결.
- macOS, Linux, Windows wheel build matrix 구성.
hangulang/rhwpcrates.io publish 이후 PyPI 안정 배포.
라이선스
MIT. 자세한 내용은 LICENSE를 참고하세요.
본 프로젝트는 독립적인 오픈소스 프로젝트입니다. HWP/HWPX는 한글과컴퓨터(Hancom
Inc.)의 포맷이며, 본 프로젝트는 한컴과 제휴 관계가 없습니다. DocLang은 LF AI &
Data Foundation의 프로젝트입니다. rhwp는 © Edward Kim (MIT)입니다.
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 Distributions
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 hangulang-0.1.0.tar.gz.
File metadata
- Download URL: hangulang-0.1.0.tar.gz
- Upload date:
- Size: 4.4 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5d59a8edf0617e01ca8032a7d7001604d50d42b52021db4c7f84f2861af03910
|
|
| MD5 |
428730cc2a60c4242631d7f348e3c6bb
|
|
| BLAKE2b-256 |
051ae2bc5548342170e81748c0e7d20e44e33f01a4a0cd039298be6dc4d3399d
|
Provenance
The following attestation bundles were made for hangulang-0.1.0.tar.gz:
Publisher:
release.yml on myeolinmalchi/hangulang-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
hangulang-0.1.0.tar.gz -
Subject digest:
5d59a8edf0617e01ca8032a7d7001604d50d42b52021db4c7f84f2861af03910 - Sigstore transparency entry: 1818918574
- Sigstore integration time:
-
Permalink:
myeolinmalchi/hangulang-python@ab3aba89634a9c0bca547d24618150c87a7db4a9 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/myeolinmalchi
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@ab3aba89634a9c0bca547d24618150c87a7db4a9 -
Trigger Event:
push
-
Statement type:
File details
Details for the file hangulang-0.1.0-cp310-abi3-win_amd64.whl.
File metadata
- Download URL: hangulang-0.1.0-cp310-abi3-win_amd64.whl
- Upload date:
- Size: 2.4 MB
- Tags: CPython 3.10+, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cbf4eae3a27eddbbb65b3176917d5364184a3321f3108004085c00ccc73b0182
|
|
| MD5 |
acbf382a26fa2299dcf54826863aeba7
|
|
| BLAKE2b-256 |
8842b177cd101403c2fd6f53bf689b2bc15489ff70ca03fa5687da18ce196065
|
Provenance
The following attestation bundles were made for hangulang-0.1.0-cp310-abi3-win_amd64.whl:
Publisher:
release.yml on myeolinmalchi/hangulang-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
hangulang-0.1.0-cp310-abi3-win_amd64.whl -
Subject digest:
cbf4eae3a27eddbbb65b3176917d5364184a3321f3108004085c00ccc73b0182 - Sigstore transparency entry: 1818918689
- Sigstore integration time:
-
Permalink:
myeolinmalchi/hangulang-python@ab3aba89634a9c0bca547d24618150c87a7db4a9 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/myeolinmalchi
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@ab3aba89634a9c0bca547d24618150c87a7db4a9 -
Trigger Event:
push
-
Statement type:
File details
Details for the file hangulang-0.1.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: hangulang-0.1.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 2.9 MB
- Tags: CPython 3.10+, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9403d4941980ec50af2f88950ac57e47129cfcf658ccb6166f2104e11647ed46
|
|
| MD5 |
af459755fd1d1f47e61eb9d9a6f98843
|
|
| BLAKE2b-256 |
2d65b1cc4e11e03fcd20920fa0701c76ee1953631d0426dcdd03d141fce0636f
|
Provenance
The following attestation bundles were made for hangulang-0.1.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:
Publisher:
release.yml on myeolinmalchi/hangulang-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
hangulang-0.1.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl -
Subject digest:
9403d4941980ec50af2f88950ac57e47129cfcf658ccb6166f2104e11647ed46 - Sigstore transparency entry: 1818918615
- Sigstore integration time:
-
Permalink:
myeolinmalchi/hangulang-python@ab3aba89634a9c0bca547d24618150c87a7db4a9 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/myeolinmalchi
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@ab3aba89634a9c0bca547d24618150c87a7db4a9 -
Trigger Event:
push
-
Statement type:
File details
Details for the file hangulang-0.1.0-cp310-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: hangulang-0.1.0-cp310-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 2.6 MB
- Tags: CPython 3.10+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5c95ea1c468bf64df525daf085b50b60f78f2a2a5fb53b86f65d73713c928eae
|
|
| MD5 |
ccdcb1b8aef102bf07d897751da12abb
|
|
| BLAKE2b-256 |
797810f6a4b759ec5815ddfe01d9b444305e11daacf30d35b45349e18a8758f9
|
Provenance
The following attestation bundles were made for hangulang-0.1.0-cp310-abi3-macosx_11_0_arm64.whl:
Publisher:
release.yml on myeolinmalchi/hangulang-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
hangulang-0.1.0-cp310-abi3-macosx_11_0_arm64.whl -
Subject digest:
5c95ea1c468bf64df525daf085b50b60f78f2a2a5fb53b86f65d73713c928eae - Sigstore transparency entry: 1818918655
- Sigstore integration time:
-
Permalink:
myeolinmalchi/hangulang-python@ab3aba89634a9c0bca547d24618150c87a7db4a9 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/myeolinmalchi
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@ab3aba89634a9c0bca547d24618150c87a7db4a9 -
Trigger Event:
push
-
Statement type: