元記事(日本語)

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つでした:

  1. ソースコード全体をAGPLで公開する → 商用サービスでは現実的でない
  2. Artifex社から商用ライセンスを購入する → コスト次第
  3. PyMuPDFを使わない代替ライブラリに移行する

私たちは 3 を選びました。

■ 「1ライブラリで全部できる」からの脱却

PyMuPDFの便利さは、PDF処理のほぼ全てを1つのライブラリでカバーできる点にありました。移行にあたり、この「全部入り」を機能ごとに分解する必要がありました。

最終的な構成はこうなりました:

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では、移行対象と思っていたテキスト描画機能が実は使われていない「デッドコード」だったことが判明しました。移行前の棚卸しの重要性を痛感した瞬間です。

■ 学んだこと

  1. ライセンスチェックは最初にやる pip installの前に、PyPIやGitHubでライセンスを確認する習慣をつけましょう。特にAGPL・GPL・LGPLは商用利用時の条件が大きく異なります。

  2. 「便利な全部入り」にはリスクがある 1つのライブラリに依存しすぎると、そのライブラリが使えなくなった時の影響が大きくなります。機能ごとに分離可能な設計を意識しておくと、いざという時の移行がスムーズです。

  3. 移行前の定量比較が安心感を生む 「動くはず」ではなく「同じ出力が得られることを数値で確認した」という事実が、チームの意思決定を後押しします。

  4. デッドコードは移行前に見つけよう 使われていないコードを移行する必要はありません。移行作業の前に、実際の呼び出し関係を丁寧にトレースすることで、工数を大幅に削減できました。

■ まとめ

OSSライセンスの見落としは、技術的負債の中でも特に気づきにくいものです。PyMuPDFは素晴らしいライブラリですが、AGPLの条件を受け入れられない場合は代替手段があります。

pdfplumber + reportlab + pypdf の組み合わせは、PyMuPDFの主要機能をカバーでき、全てMIT/BSDライセンスです。移行コストはゼロではありませんが、計画的に進めれば十分に実現可能でした。

あなたのプロジェクトのrequirements.txt、最後にライセンスを確認したのはいつですか?

#OSS #ライセンス #Python #PDF #AGPL #ソフトウェア開発 #技術的負債