Skip to main content

PyO3 Python bindings for rhwp — parser and renderer for HWP/HWPX documents (Korean word processor format)

Project description

rhwp-python

한국어 | English

PyPI Python CI License: MIT

⚠️ 비공식 커뮤니티 패키지입니다. 본 프로젝트는 edwardkim/rhwp공식 배포가 아니며, rhwp 메인테이너가 직접 PyPI 에 올릴 경우를 대비해 이름을 rhwp-python 으로 양보해 둔 상태입니다. rhwp 코어 버그는 업스트림 에 보고해 주세요.

rhwp — Rust 기반 HWP/HWPX(한컴오피스 문서) 파서·렌더러 — 의 PyO3 Python 바인딩.

  • PyPI 패키지명: rhwp-python
  • Python import: import rhwp
  • Rust 코어: edwardkim/rhwp

왜 rhwp-python 인가

  • HWP + HWPX 동시 지원 — 대표 대안인 pyhwp 는 HWP5 만 지원하고 2016년 이후 유지보수 중단 상태. rhwp 는 두 포맷을 같은 API 로 처리.
  • 텍스트 추출 62배 빠름 — HWP5 기준 pyhwp 대비 96 ms vs 5,980 ms (sandbox 벤치).
  • LangChain 즉시 연동rhwp.integrations.langchain.HwpLoader 를 extras 로 제공, RAG 파이프라인에 바로 플러그인 가능.
  • 타입 완비py.typed + .pyi 스텁, pyright clean.

요구 사항

  • Python 3.10+ (abi3-py310 wheel 하나로 3.10 ~ 3.13+ 커버)
  • 코어 API 는 런타임 Python 의존성 없음
  • rhwp-python[langchain] extras 는 langchain-core>=0.2 하나만 추가 설치

설치

pip install rhwp-python
# 또는
uv add rhwp-python

사용법

import rhwp

# HWP / HWPX 파싱 — 파일 I/O + 파싱 단계에서 GIL 해제
doc = rhwp.parse("report.hwp")
print(doc.section_count, doc.paragraph_count, doc.page_count)

# 텍스트
full_text: str = doc.extract_text()          # 빈 문단 제외, "\n" 으로 join
paragraphs: list[str] = doc.paragraphs()      # 빈 문단 포함 원본 리스트

# SVG 렌더링 — 단일 페이지 또는 전체
svg_page0: str = doc.render_svg(page=0)
all_svgs: list[str] = doc.render_all_svg()
written: list[str] = doc.export_svg("output/", prefix="page")
# → page_001.svg, page_002.svg, ... (단일 페이지면 page.svg)

# PDF 렌더링 — list[int] 가 아니라 Python `bytes` 반환
pdf: bytes = doc.render_pdf()
byte_size: int = doc.export_pdf("output.pdf")

rhwp.Document(path)rhwp.parse(path) 와 동일하게 동작.

LangChain 통합

pip install "rhwp-python[langchain]"
from rhwp.integrations.langchain import HwpLoader

# 문서 전체를 단일 Document 로 (기본 — single 모드)
docs = HwpLoader("report.hwp").load()

# 빈 문단 제외, 문단 1개당 Document 1개 (RAG 청킹용 — paragraph 모드)
docs = HwpLoader("report.hwp", mode="paragraph").load()

# lazy_load: Document 를 on-the-fly 로 yield (paragraph 모드에서 O(1) peak memory)
for d in HwpLoader("report.hwp", mode="paragraph").lazy_load():
    index_into_vector_store(d)   # 사용자 파이프라인

# 표준 LangChain 텍스트 스플리터에 바로 연결
from langchain_text_splitters import RecursiveCharacterTextSplitter
chunks = RecursiveCharacterTextSplitter(chunk_size=500).split_documents(docs)

모든 Document 메타데이터: source, section_count, paragraph_count, page_count, rhwp_version. paragraph 모드에서는 paragraph_index 추가.

Document IR

RAG / LLM 파이프라인이 직접 소비하는 구조화 문서 모델. Pydantic V2 모델 + JSON Schema (Draft 2020-12) — HWP 의 구역 / 단락 / 표 / 그림 / 수식 / 각주 / 목록 / 캡션 / 목차 / 필드를 손실 없이 노출한다.

from rhwp.ir.nodes import ParagraphBlock, TableBlock

doc = rhwp.parse("report.hwp")
ir = doc.to_ir()                       # -> rhwp.ir.nodes.HwpDocument (Pydantic, frozen)
json_str = doc.to_ir_json(indent=2)    # JSON 직렬화

# 본문 블록을 순서대로 스트리밍 (표/문단 혼합, TableCell.blocks 까지 재귀)
for block in ir.iter_blocks(scope="body"):
    if isinstance(block, ParagraphBlock):
        print("P", block.prov.section_idx, block.prov.para_idx, block.text)
    elif isinstance(block, TableBlock):
        print("T", block.rows, "x", block.cols, "cells=", len(block.cells))

표 3중 표현cells (구조화 SQL/순회용) + html (HtmlRAG 호환 LLM 프롬프트) + text (평문 검색 폴백) 가 병기된다. 중첩 표는 TableCell.blocks 재귀로 자연 지원.

LangChain 통합 — 기존 loader 에 mode="ir-blocks" 추가:

from rhwp.integrations.langchain import HwpLoader

docs = HwpLoader("report.hwp", mode="ir-blocks").load()
# ^ 단락은 page_content=text, 표는 page_content=HTML. 메타에 kind / section_idx /
#   para_idx / (표의 경우) rows / cols / text / caption 포함

JSON Schemarhwp.ir.schema.export_schema() / load_schema(). 공개 $id: https://danmeon.github.io/rhwp-python/schema/hwp_ir/v1/schema.json (불변 경로).

View 변환 (v0.4.0+)HwpDocument.to_markdown() / to_html(include_css=False) 인스턴스 메서드로 IR 을 외부 view 포맷으로 직접 변환:

ir = rhwp.parse("report.hwp").to_ir()

md = ir.to_markdown()                 # GFM (표 / 각주 / 수식 / 이미지 placeholder)
html = ir.to_html(include_css=True)   # 완전 HTML5 문서, <head> 안 단일 <style> 동봉

표는 모든 셀 span == 1 일 때 GFM |...|, 병합 셀 (rowspan/colspan > 1) 은 TableBlock.html 그대로 inline. 각주/미주는 본문 paragraph 안 [^N] reference + 끝 정의 (Markdown) / <aside id="fn-N"> 정의 (HTML). 이미지는 picture.image.uri (bin://N) pass-through — raw bytes 가 필요하면 Document.bytes_for_image(picture) 를 별도 호출 (embedded 모드 미지원). 머리글/꼬리말은 출력 미포함 (페이지 단위 장식).

호출은 IR 인스턴스를 변경하지 않아 (frozen=True) 동일 IR 에 대한 재호출은 byte-equal.

rhwp-py CLI

pip install "rhwp-python[cli]"          # parse / version / schema / ir / blocks
pip install "rhwp-python[cli-chunks]"    # + chunks (langchain text splitter)

rhwp-py parse report.hwp
rhwp-py blocks report.hwp --kind table --format ndjson | jq '.rows'
rhwp-py chunks report.hwp --size 1000 --format ndjson

rhwp-py 는 구조 추출 (IR / 블록 / 청크 / 스키마) 전담 — 시각 출력 (SVG/PDF) / 메타데이터 덤프는 상류 rhwp Rust 바이너리. 자세한 사용은 rhwp-py --help 또는 cli.md 참조.

MCP server (rhwp-mcp)

Model Context Protocol 서버 — Claude Desktop / Cursor / Cline / Continue.dev / Goose 등 LLM 에이전트가 HWP/HWPX 파일을 직접 파싱·요약·청크화할 수 있다. standalone fastmcp v3 기반 (2026-05 기준 MCP 서버 약 70% 시장 점유의 사실상 표준).

pip install "rhwp-python[mcp]"           # 도구 6 종 (parse / extract / IR / blocks / view×2)
pip install "rhwp-python[mcp-chunks]"    # + chunks (RAG 청킹 — langchain-text-splitters)

노출 도구 (7 종)

도구 입력 출력
parse_hwp_summary path sections / paragraphs / pages 카운트 + rhwp-core 버전
extract_text path 단락별 평문 (LF 결합)
get_ir path Document IR 전체 (JSON-serializable dict)
iter_blocks path, kind?, scope, limit? IR 블록 dict 리스트 (kind / scope 필터링)
to_markdown path GFM Markdown — v0.4.0 view API thin wrapper
to_html path, include_css HTML5 문서 — v0.4.0 view API thin wrapper
chunks path, mode, size, overlap, include_furniture LangChain RecursiveCharacterTextSplitter 적용 청크 — [mcp-chunks] extras 필요

Claude Desktop 등록

claude_desktop_config.json 에 추가:

{
  "mcpServers": {
    "rhwp": {
      "command": "rhwp-mcp"
    }
  }
}

(macOS: ~/Library/Application Support/Claude/claude_desktop_config.json. Windows: %APPDATA%\Claude\claude_desktop_config.json.) Claude Desktop 재시작 후 도구 아이콘에 7 개 도구 노출.

다른 클라이언트

클라이언트 stdio streamable-http 등록 방법
Claude Desktop claude_desktop_config.json (위 예시)
Cline (VSCode) VSCode 설정 → MCP servers
Cursor Settings → Features → Model Context Protocol
Continue.dev ⚠️ (실험) ~/.continue/config.json
Goose (Block) goose configure
자체 에이전트 Anthropic SDK 의 MCP client / fastmcp Client

Streamable HTTP (서버 배포)

서버 컨테이너 / 다중 클라이언트 시나리오는 streamable-http transport:

rhwp-mcp --transport streamable-http --port 8000
# 외부 노출 (보안: reverse proxy + 인증 운영자 책임)
rhwp-mcp --transport streamable-http --host 0.0.0.0 --port 8000

기본 --host 127.0.0.1 — 외부 노출 회피. rhwp-mcp 는 인증 / TLS / sandboxing 미내장 — Caddy / Nginx 등 reverse proxy 가 책임. 자세한 사용은 rhwp-mcp --help 또는 mcp.md 참조.

성능

Apple M2 (8 코어) release 빌드. Parse = 파일 읽기 + 전체 파싱 + Document 생성. 워크로드: 9 개 파일 (aift.hwp 5.5 MB + table-vpos-01.hwpx 359 KB + tac-img-02.hwpx 3.96 MB, ×3).

워커 수 Parse 시간 순차 대비 가속
1 268 ms 1.00× (기준)
2 141 ms 1.91×
4 97 ms 2.76×
8 67 ms 4.01×

parse() 와 PDF 변환 단계는 py.detach 로 GIL 을 해제하므로 ThreadPoolExecutor 가 코어 수에 비례해 스케일. PDF 렌더링 자체는 usvg + pdf-writer 내부에서 CPU/allocator 바운드라 2 ~ 3 워커에서 약 1.1× 정도만 향상됨 — 재현은 benches/bench_gil.py 참고.

알려진 제약 / 운영 노트

운영상 제약 (Document 의 단일 스레드 모델, async 진입점, PDF stdout 노이즈) 및 미구현 영역 요약은 KNOWN_ISSUES.md. 작업 중 / 계획 항목은 docs/roadmap/ 의 활성 spec 인덱스.

개발

소스에서 빌드·테스트·기여하는 절차는 CONTRIBUTING.md 참조.

버전 관리

이 Python 패키지와 rhwp Rust 코어는 독립적으로 버저닝됩니다. rhwp.version() 은 이 패키지 버전을, rhwp.rhwp_core_version() 은 번들된 Rust 코어 버전을 반환합니다.

라이선스

MIT. 저작권자: Edward Kim (rhwp Rust 코어) + DanMeon (rhwp-python 바인딩). 자세한 내용은 LICENSE.

프로젝트 홈

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

rhwp_python-0.5.0.tar.gz (62.8 MB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

rhwp_python-0.5.0-cp310-abi3-win_amd64.whl (3.8 MB view details)

Uploaded CPython 3.10+Windows x86-64

rhwp_python-0.5.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.8 MB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ x86-64

rhwp_python-0.5.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (3.6 MB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ ARM64

rhwp_python-0.5.0-cp310-abi3-macosx_11_0_arm64.whl (3.5 MB view details)

Uploaded CPython 3.10+macOS 11.0+ ARM64

rhwp_python-0.5.0-cp310-abi3-macosx_10_12_x86_64.whl (3.6 MB view details)

Uploaded CPython 3.10+macOS 10.12+ x86-64

File details

Details for the file rhwp_python-0.5.0.tar.gz.

File metadata

  • Download URL: rhwp_python-0.5.0.tar.gz
  • Upload date:
  • Size: 62.8 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for rhwp_python-0.5.0.tar.gz
Algorithm Hash digest
SHA256 d858f948f49938ebcf1c330249ec1e277f60aa352e27d33fddfa17442c6a6632
MD5 ead739b32fe6b5582547672a62e5155a
BLAKE2b-256 a2bd8c1b993fe61313da1355479707f8df98307bde71ce6caa8b0ae208f7be6a

See more details on using hashes here.

Provenance

The following attestation bundles were made for rhwp_python-0.5.0.tar.gz:

Publisher: publish.yml on DanMeon/rhwp-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rhwp_python-0.5.0-cp310-abi3-win_amd64.whl.

File metadata

  • Download URL: rhwp_python-0.5.0-cp310-abi3-win_amd64.whl
  • Upload date:
  • Size: 3.8 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

Hashes for rhwp_python-0.5.0-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 089e7c587afa846c915c62b41a210c5b1561c1759ac342d92b4b5272811a464a
MD5 47cc22ab551dbc05f7eaac6cff82237c
BLAKE2b-256 f493b3d28ac2fa09c0b62f32fa8708bfa312c0306b28b1d8f4b283d6001777ff

See more details on using hashes here.

Provenance

The following attestation bundles were made for rhwp_python-0.5.0-cp310-abi3-win_amd64.whl:

Publisher: publish.yml on DanMeon/rhwp-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rhwp_python-0.5.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for rhwp_python-0.5.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 d9b3f0b3cc0e2ba7ebff8a7447f7b0d4b3eb00c19096eaf1aa0308bfe896d47f
MD5 67dc9617c4c7c24889a9f73e33c7ebc4
BLAKE2b-256 0739ce85378876e66c0dfba8da4eaaa4cf663eb04adb270435a2ce3dff8f29c5

See more details on using hashes here.

Provenance

The following attestation bundles were made for rhwp_python-0.5.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: publish.yml on DanMeon/rhwp-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rhwp_python-0.5.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for rhwp_python-0.5.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 7d04fabf318fdcc694dc0c2ebf106c1f066d6ebe478add807cf8e3152e631caf
MD5 10c8729f4a46e06b764043dedb408842
BLAKE2b-256 4e9d25b6957028393c850bbfe67f6276cde5bd28be0027671b693a0bee5b1567

See more details on using hashes here.

Provenance

The following attestation bundles were made for rhwp_python-0.5.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: publish.yml on DanMeon/rhwp-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rhwp_python-0.5.0-cp310-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for rhwp_python-0.5.0-cp310-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 894eddf3e9f71c6e121c9b3eee43f5ce87e964c3f0d475600b2ffe2436416fe6
MD5 5492eebfaad50cecc98893dcde48de8c
BLAKE2b-256 5cc693900b17fa172dad87cbbdb163790cdb4db51b14bbe42db6677b9de4d635

See more details on using hashes here.

Provenance

The following attestation bundles were made for rhwp_python-0.5.0-cp310-abi3-macosx_11_0_arm64.whl:

Publisher: publish.yml on DanMeon/rhwp-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rhwp_python-0.5.0-cp310-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for rhwp_python-0.5.0-cp310-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 37d431e879ebf2d905295ea56bef65f0b9ad1ae5cefa4bd144dc135c1084cdfc
MD5 fc70c352e1f7c11452de7215ff4016e0
BLAKE2b-256 b7a85eb48fba05cfdbb43065499b28fd4b26d177d09a2d7821cc5553de7e7fed

See more details on using hashes here.

Provenance

The following attestation bundles were made for rhwp_python-0.5.0-cp310-abi3-macosx_10_12_x86_64.whl:

Publisher: publish.yml on DanMeon/rhwp-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page