check_sphinx_api_html.py

プログラムの動作

check_sphinx_api_html.py は、Sphinxによって生成されたHTMLファイル、特にAPIドキュメント (*_api.html のようなファイル) を走査し、autodocなどのAPI取り込みメカニズムが適切に機能しなかったために本文が実質的に空っぽ、または非常に短いHTMLページを検出することを目的としたPythonスクリプトです。

このプログラムは、指定されたディレクトリ以下のHTMLファイルを解析し、以下のような状態のファイルを「失敗」と判定します。

  • Sphinx autodocが生成する典型的なAPIマーカーやシグネチャ行がHTML内に存在しない。

  • メインコンテンツ領域のテキストが極端に短い。

  • タイトルのみで内容が不足しているように見えるAPIページ。

検出された「失敗」ファイルのパスは、指定された出力ファイルにリストとして書き出されます。

原理

このプログラムは以下のステップとアルゴリズムに基づいてAPIドキュメントの品質をチェックします。

  1. HTMLファイルの読み込み: read_text 関数は、与えられたHTMLファイルのテキスト内容を読み込みます。ファイルの文字コードは確定できないため、「utf-8」「cp932」「shift_jis」「latin-1」の順にデコードを試み、成功したエンコーディングで内容を返します。すべての試行が失敗した場合、utf-8 でエラーを置換しながら読み込みます。

  2. メインコンテンツ領域の抽出: extract_main_html 関数は、HTMLドキュメントの中から主要なコンテンツ(本文)が含まれると推測されるHTMLブロックを抽出します。これは、SphinxやReadTheDocsテーマでよく使用される特定のHTML構造(role="main"class="document"<section><main><article> タグなど)を正規表現で探索することで行われます。もしこれらのパターンに一致する部分が見つからない場合は、HTMLドキュメント全体がメインコンテンツとして扱われます。

  3. HTMLタグの除去とテキスト化: strip_html 関数は、抽出されたメインコンテンツのHTMLから不要な要素を除去し、純粋なテキストを抽出します。

    • まず、<script>, <style>, <nav>, <footer>, <header> といった、ページの構造や機能に関する要素を正規表現で完全に削除します。

    • 次に、残りのすべてのHTMLタグ(<[^>]+>)を空白に置き換えます。

    • html.unescape を使用して、&lt;, &gt;, &amp; などのHTMLエンティティを通常の文字に変換します。

    • 最後に、複数の連続する空白文字を単一の空白に統一し、前後の空白を除去してクリーンなテキストを生成します。

  4. API取り込み失敗の判定: check_api_html 関数が、クリーンなテキストと元のHTML構造に基づいて、APIドキュメントが失敗しているかどうかを判定します。判定ロジックは以下の条件に基づいています。

    • APIマーカーの存在確認: Sphinx autodocがAPI要素(関数、クラス、メソッドなど)を出力する際に付与する典型的なHTML文字列やクラス名(例: "py function", "sig-name", "dl class="py" など)がHTML内に含まれるかを確認します。これらのマーカーが一つも存在しない場合、失敗の理由とみなされます。

    • シグネチャ行の存在確認: <dt class="sig"> のような、Python APIのシグネチャ(関数名や引数リスト)を示すHTMLタグの有無を正規表現で確認します。

    • 本文テキストの長さチェック: strip_html で抽出されたメインテキストの長さが、指定された閾値 (min_text_len、デフォルト300文字) を下回る場合、内容が不足していると判断し、失敗の理由とみなされます。

    • タイトルのみのAPIページ判定: 本文中に「プログラム仕様」や「API」といった一般的なタイトルらしきキーワードが含まれるにもかかわらず、APIマーカーが全くなく、かつ本文の長さが比較的短い(1000文字未満)場合、単にタイトルが表示されているだけで中身がないページである可能性が高いと判断し、これも失敗の理由とみなされます。

これらのいずれかの条件に合致する場合、そのファイルは「失敗」としてフラグが立てられ、失敗理由のリストと共に返されます。

必要な非標準ライブラリとインストール方法

check_sphinx_api_html.py は、Pythonの標準ライブラリ(argparse, re, sys, pathlib, html)のみを使用しており、追加でインストールが必要な非標準ライブラリはありません。

必要な入力ファイル

  • Sphinxによって生成されたHTMLファイル: プログラムが解析する対象となるのは、SphinxによってビルドされたHTMLドキュメント群です。特に、デフォルトではファイル名が *_api.html のパターンに一致するファイルをターゲットとします。

    • 形式: HTML形式

    • 場所: 通常は _build/html ディレクトリ以下に生成されますが、--root 引数で任意のルートディレクトリを指定できます。

    • 構造: Sphinxが生成する一般的なHTML構造、特にReadTheDocsテーマに準拠した構造を想定していますが、他のテーマでも主要なコンテンツ領域の検出を試みます。

生成される出力ファイル

  • ファイル名: failed_api_html.txt (デフォルト。--outfile 引数で変更可能)

  • 内容: API取り込みに失敗したと判断された各HTMLファイルへの相対パスが、1行に1つずつ記載されます。 パスは、--root で指定された検索ルートディレクトリからの相対パスで表現されます。 ディレクトリの区切り文字は、Windows環境でも / に統一されて出力されます。

    例:

    my_module/my_class_api.html
    another_module/another_function_api.html
    

コマンドラインでの使用例 (Usage)

check_sphinx_api_html.py は、以下の引数を使用してコマンドラインから実行できます。

python check_sphinx_api_html.py [-h] [--root ROOT] [--files FILES] [--outfile OUTFILE] [--exclude EXCLUDE] [--min-text-len MIN_TEXT_LEN] [--show-ok {0,1}]
  • -h, --help: ヘルプメッセージを表示して終了します。

  • --root ROOT: 検索ルートディレクトリを指定します。デフォルトは ./build/html です。

  • --files FILES: ターゲットファイルのワイルドカードパターンを指定します。デフォルトは *_api.html です。

  • --outfile OUTFILE: 結果を書き込む出力ファイルのパスを指定します。デフォルトは failed_api_html.txt です。

  • --exclude EXCLUDE: パスに指定したキーワードが含まれるファイルを処理対象から除外します。複数回指定することで複数のキーワードを除外できます。

  • --min-text-len MIN_TEXT_LEN: メインテキストの最小長さを指定します。これより短いテキストのページは「失敗」と判定されます。デフォルトは 300 文字です。

  • --show-ok {0,1}: 「OK」と判定されたファイルも出力に表示するかどうかを指定します。0 は非表示 (デフォルト)、1 は表示です。

コマンドラインでの具体的な使用例

  1. デフォルト設定での実行: 現在のディレクトリの ./build/html 以下にある *_api.html ファイルをチェックし、失敗したファイルのリストを failed_api_html.txt に出力します。

    python check_sphinx_api_html.py
    

    実行結果の例:

    root    : /path/to/project/build/html
    pattern : *_api.html
    found   : 120 files
    
    [FAILED] module1/classA_api.html
             - no autodoc API markers
             - main text too short: 85 < 300
    [FAILED] module2/functionB_api.html
             - looks like title-only API page
    [OK]     module3/classC_api.html
    
    failed  : 2 / 120
    output  : /path/to/project/failed_api_html.txt
    

    この例では、module1/classA_api.htmlmodule2/functionB_api.html が失敗と判定され、その理由も表示されています。failed_api_html.txt にはこれらのファイルのパスが記録されます。

  2. 特定のルートディレクトリとファイルパターンを指定して実行: Sphinxの出力が docs/_build/html にあり、全てのHTMLファイルを対象にチェックする場合。

    python check_sphinx_api_html.py --root docs/_build/html --files "*.html" --outfile all_failed_html.txt
    

    実行結果の例:

    root    : /path/to/project/docs/_build/html
    pattern : *.html
    found   : 500 files
    
    [FAILED] index.html
             - no autodoc API markers
             - main text too short: 120 < 300
    [FAILED] tutorial/getting_started.html
             - main text too short: 250 < 300
    ...
    failed  : 15 / 500
    output  : /path/to/project/all_failed_html.txt
    

    この例では、docs/_build/html ディレクトリ内のすべてのHTMLファイルがチェックされ、結果が all_failed_html.txt に出力されます。

  3. 特定のパスを除外し、OKファイルも表示して実行: _modules ディレクトリにあるAPIページを除外し、min_text_len200 に設定し、成功したファイルも表示する場合。

    python check_sphinx_api_html.py --root _build/html --exclude _modules --min-text-len 200 --show-ok 1
    

    実行結果の例:

    root    : /path/to/project/_build/html
    pattern : *_api.html
    found   : 120 files
    
    [SKIP]   _modules/my_utility_api.html
    [OK]     module1/classA_api.html
    [FAILED] module2/functionB_api.html
             - looks like title-only API page
    ...
    failed  : 1 / 120
    output  : /path/to/project/failed_api_html.txt
    

    この例では、_modules ディレクトリ内のファイルはスキップされ、min_text_len200 に設定されているため、以前の例で失敗とされた module1/classA_api.html がOKになる可能性があります。また、--show-ok 1 により、OKと判定されたファイルも表示されています。