Poetry + Read the Docs でハマった話

pythonhosted.org でのホスティングはオワコン

以前は pythonhosted.org でホスティングしていた

Annictというアニメの視聴記録等ができるWebサービスがある。

annict.jp

REST APIが提供されているのでそのPython wrapperを作っていた。

github.com

で、このライブラリのドキュメント、Pipenvすら導入以前の requirements.txt で管理していた頃に一度 Read the Docs でホスティングしようと試したことがあるが、ビルドが上手くいってなかった。当時は色々試してみたもののよくわからなくて諦め、他の方法を探していたところ pythonhosted.org でホスティングする方法を見つけたのでそうしていた。

ホスティングサポート終了

前述のpython-annict、細々とメンテしたり放置したりしつつも、この度ひさびさに機能追加してリリースした。なのでドキュメントを更新したいのだけれど、どうにもそれらしきUIが見当たらない。

PyPI のドキュメントの管理画面を開くと、削除ボタンのところに「一度削除すると再アップロードはもはやサポートしていないので復元できない」とある。

Destroy documentation

Warning If you would like to DESTROY any existing documentation hosted athttps://pythonhosted.org/annict/

There is no undo as uploading new documentation is no longer supported.

同様の話題が pipy-legacy の issue でも見つかった。それによると代わりにRead the Docsとか使って欲しいとのこと。

github.com

どうやらお引越しが必要のようだ。

Read the Docs を再び試す

依存ライブラリの ImportError が発生する

Read the Docs に久々にログインし、ビルドを再び試すも ImportError が発生。furlが無いとのこと。

Running Sphinx v1.7.9

Traceback (most recent call last):
  File "/home/docs/checkouts/readthedocs.org/user_builds/python-annict/envs/latest/local/lib/python2.7/site-packages/sphinx/cmdline.py", line 303, in main
    args.warningiserror, args.tags, args.verbosity, args.jobs)
  File "/home/docs/checkouts/readthedocs.org/user_builds/python-annict/envs/latest/local/lib/python2.7/site-packages/sphinx/application.py", line 163, in __init__
    confoverrides or {}, self.tags)
  File "/home/docs/checkouts/readthedocs.org/user_builds/python-annict/envs/latest/local/lib/python2.7/site-packages/sphinx/config.py", line 167, in __init__
    raise ConfigError(CONFIG_ERROR % traceback.format_exc())
ConfigError: There is a programable error in your configuration file:

Traceback (most recent call last):
  File "/home/docs/checkouts/readthedocs.org/user_builds/python-annict/envs/latest/local/lib/python2.7/site-packages/sphinx/config.py", line 161, in __init__
    execfile_(filename, config)
  File "/home/docs/checkouts/readthedocs.org/user_builds/python-annict/envs/latest/local/lib/python2.7/site-packages/sphinx/util/pycompat.py", line 150, in execfile_
    exec_(code, _globals)
  File "/home/docs/checkouts/readthedocs.org/user_builds/python-annict/envs/latest/local/lib/python2.7/site-packages/six.py", line 709, in exec_
    exec("""exec _code_ in _globs_, _locs_""")
  File "<string>", line 1, in <module>
  File "conf.py", line 24, in <module>
    from annict import __version__, __author__
  File "/home/docs/checkouts/readthedocs.org/user_builds/python-annict/checkouts/latest/annict/__init__.py", line 16, in <module>
    from .api import API  # noqa
  File "/home/docs/checkouts/readthedocs.org/user_builds/python-annict/checkouts/latest/annict/api.py", line 2, in <module>
    from .services import APIMethod
  File "/home/docs/checkouts/readthedocs.org/user_builds/python-annict/checkouts/latest/annict/services.py", line 2, in <module>
    from furl import furl
ImportError: No module named furl

これはもしや requirements.txt が必要なやつなのでは…。

あとPython2.7でビルドしようとしているのでRead the Docsのプロジェクトの管理画面より使用するPythonのバージョンを CPython3.x に変更しておいた。

この辺いろいろやってて記憶が定かではないが、たしか「管理 > 高度な設定」の 「setup.py installでvirtualenv環境にあなたのプロジェクトをインストールします」のチェックを入れるとエラー内容が代わり、Python3.6から使えるようになっているf-stringsのところでSyntaxErrorで落ちた。CPython3.xとは3.5のことだったのだ…。これどうしたらいいんだ。

他のリポジトリを参考にする

poetry はどうやってるんだろうと思ったら Sphinx ではなく Mkdocs を使ってたので参考にならず。blackはPoetry使っててドキュメントはRead the Docs を使っていたので参考になりそう。

github.com

リポジトリ内を念入りに見て回ると、どうやら readthedocs.ymldocs/environment.yml というファイルに秘密がありそう。

ググると Read the Docs のドキュメントがヒットした。

Read the Docs YAML Config — Read the Docs 2.7 documentation

どうやらWEBの管理画面でできるのと同じような設定をYamlから指定することもできるらしい。しかもこちらだとPython3.6を使うよう指定したりcondaを利用したりできる模様。

Yamlにビルドの設定を書く

なんとなく把握したところで black の readthedocs.ymldocs/environment.yml を参考に以下のようにした

readthedocs.yml

name: annict
type: sphinx
conda:
     file: docs/environment.yml
python:
  version: 3

condaを使用するよう指定する。ちなみにPythonのバージョンはyaml経由だと3.6ではなく3でも問題なかった。

docs/environment.yml

name: annict_docs
channels:
  - conda-forge
dependencies:
- python>=3.6
- Sphinx==1.8.2
- pip:
  - sphinx-rtd-theme==0.4.2
  - arrow==0.12.1
  - furl==2.0.0
  - rauth==0.7.3
  - requests==2.21.0
  - requests-cache==0.4.13
  - annict==0.7.0

condaがインストールするライブラリたちを指定する。そうかここでPython3.6以上を指定してるからそれがはいるのか。

dependenciesのトップレベルに指定できるのはcondaでインストールできるものだけ。最初 sphinx-rtd-theme をトップレベル(Sphinxとpipの間の行)に記載したらResolvePackageNotFound というエラーでビルド失敗した。condaよく知らないけどcondaはPyPIからなんでもインストールできるわけではないんだったような気がする。condaでインストールできないものは pip のしたにインデントして列挙する。これでpip経由でのインストールになるのでpipでインストールできるものなら何でも入る。

無事ビルド成功

2つのYamlをmasterにcommit&pushしたら無事Read the Docsでビルド成功した。というわけで requirements.txt が無くてもビルドすることができた。たぶん setup.py が無くてもいけると思う。

まとめ

Poetryでパッケージ管理していると setup.py とか requirements.txt ファイルが無いので Read the Docs 側がPoetryに対応してくれるまで利用できないのかと思ったけど、そんなことはなくてRead the Docsのドキュメントしっかり読むと結構色々できそうな感じだった、というお話でした。