元記事(日本語)
PyMuPDFがAGPLだと気づいた日 — OSSライセンス見落としから学んだこと
「便利だから」で選んだライブラリが、プロジェクト全体のソースコード公開義務を発生させていた。
PythonでPDF処理をするなら、PyMuPDF(fitz)は定番の選択肢です。高速で、テキスト抽出・図形解析・PDF生成・マージまで1つのライブラリで完結する。私たちのチームも、当然のようにrequirements.txtに追加していました。
ある日、依存ライブラリのライセンス棚卸しをしていて気づきました。
PyMuPDFのライセンスは AGPL-3.0。
■ AGPLが商用サービスに与える影響
MITやBSDに慣れていると見落としがちですが、AGPLはGPLよりさらに厳しいライセンスです。
通常のGPLは「配布時にソースコード公開」が条件ですが、AGPLはそれに加えて「ネットワーク経由でサービスを提供する場合」にもソースコード公開義務が発生します。
つまり、サーバーサイドでPyMuPDFを使ってPDF処理をしているWebアプリケーションは、そのアプリケーション全体のソースコードをAGPLで公開する義務がある、ということです。
選択肢は3つでした:
- ソースコード全体をAGPLで公開する → 商用サービスでは現実的でない
- Artifex社から商用ライセンスを購入する → コスト次第
- PyMuPDFを使わない代替ライブラリに移行する
私たちは 3 を選びました。
■ 「1ライブラリで全部できる」からの脱却
PyMuPDFの便利さは、PDF処理のほぼ全てを1つのライブラリでカバーできる点にありました。移行にあたり、この「全部入り」を機能ごとに分解する必要がありました。
最終的な構成はこうなりました:
- PDF解析(テキスト・図形の抽出) → pdfplumber(MIT)
- PDF生成(テキスト描画) → reportlab(BSD)
- PDF操作(マージ・ページ結合) → pypdf(BSD-3)
3つのライブラリを組み合わせることになりますが、いずれもMIT/BSDライセンスで、商用利用に制約はありません。
■ 移行で最も苦労したポイント
技術的に最も難しかったのは、座標系の違いへの対応です。
PyMuPDFは「左上原点」(画面と同じ感覚)ですが、reportlabは「左下原点」(PDF仕様の本来の座標系)です。Y座標を全て変換する必要がありました。
もう1つは、テキスト抽出のデータ構造の違い。PyMuPDFはPDF内部のスパン構造をそのまま返してくれますが、pdfplumberは文字単位のデータを返します。表組みの中のテキストを正確にグループ化するには、罫線の座標情報と組み合わせた独自のロジックが必要でした。
一方、意外にもスムーズだったのがPDFマージ(ページの結合・クリッピング)です。事前に「最も移行難易度が高い」と見積もっていましたが、pypdfのcropboxとTransformationの組み合わせで、PyMuPDFと完全に同じ出力を得ることができました。
■ 移行の進め方:段階的に、検証ファーストで
全6フェーズに分けて段階的に移行しました。
Phase 1: 最も小さく独立したモジュールから着手(約300行のユーティリティ) Phase 2-3: 中核の解析・マージ処理(アダプターパターンで既存ロジックを維持) Phase 4: デッドコード発見 → 不要な移行作業がゼロに Phase 5: PDF結合処理の移行 Phase 6: PyMuPDFの完全除去とDockerイメージのクリーンアップ
各フェーズの前に、PyMuPDFと代替ライブラリの出力を定量的に比較する検証を行いました。8つの帳票PDF(15ページ)に対して、テキスト・図形・マージの全てで合格基準をクリアしたことを確認してから、本番コードの移行に着手しています。
特にPhase 4では、移行対象と思っていたテキスト描画機能が実は使われていない「デッドコード」だったことが判明しました。移行前の棚卸しの重要性を痛感した瞬間です。
■ 学んだこと
-
ライセンスチェックは最初にやる pip installの前に、PyPIやGitHubでライセンスを確認する習慣をつけましょう。特にAGPL・GPL・LGPLは商用利用時の条件が大きく異なります。
-
「便利な全部入り」にはリスクがある 1つのライブラリに依存しすぎると、そのライブラリが使えなくなった時の影響が大きくなります。機能ごとに分離可能な設計を意識しておくと、いざという時の移行がスムーズです。
-
移行前の定量比較が安心感を生む 「動くはず」ではなく「同じ出力が得られることを数値で確認した」という事実が、チームの意思決定を後押しします。
-
デッドコードは移行前に見つけよう 使われていないコードを移行する必要はありません。移行作業の前に、実際の呼び出し関係を丁寧にトレースすることで、工数を大幅に削減できました。
■ まとめ
OSSライセンスの見落としは、技術的負債の中でも特に気づきにくいものです。PyMuPDFは素晴らしいライブラリですが、AGPLの条件を受け入れられない場合は代替手段があります。
pdfplumber + reportlab + pypdf の組み合わせは、PyMuPDFの主要機能をカバーでき、全てMIT/BSDライセンスです。移行コストはゼロではありませんが、計画的に進めれば十分に実現可能でした。
あなたのプロジェクトのrequirements.txt、最後にライセンスを確認したのはいつですか?
#OSS #ライセンス #Python #PDF #AGPL #ソフトウェア開発 #技術的負債