自作Pythonライブラリをインストールするまで

Pythonで自作ライブラリをインストールする手順を解説します。
PyPIに公開はせず、チーム内での使用を想定します。
自作ライブラリ名: mylibrary

### ディレクトリ構成
最終的なディレクトリ構成は以下のようになります。

```
./mylibrary
--- /mylibrary
    ---/__init__.py
        file1.py
        file2.py
--- /docs
    /makefile
     make.bat
     index.rst
     api.rst
     page1.rst
    ---/_static
       ---/icon.png
    ----/_build
        ---/html
--- /example
    ---/example1.py
        example2.py
lisence.txt
setpu.py
```
#### ディレクトリの説明
mylibraryディレクトリ
ソースファイルを置きます。

__docsディレクトリ__
ライブラリのドキュメントを置くディレクトリです。
作成時点では空ディレクトリです。ソースファイル作成後にSphinxを使用してソース内のdocstringからドキュメントを自動で作成します。

__exampledeディレクトリ__
ライブラリのサンプルコードを置いておきます。

__setpu.pyファイル__
インストール時の構成を記述するファイルです。

__その他必要ファイル__
lisence.txt ライセンスを記述したファイルです。

### ソースファイルの記述
ライブラリを作成する場合、\__init__.pyファイルを作成しましょう。
\__init__.pyファイルを作成することで、ライブラリ内のクラス、関数をインポートする際に絶対パスを使用せずともインポートすることができるようになります。

```notexist__init__.py
#__init__.pyを作成せずにインストールした場合
from mylibrary.file1 import class1
```
ライブラリ内の当該クラスが記述されているフォルダ名を記述しないと、そのクラスをインポートできません。

```_exist_init__.py
#__init__.pyを作成した場合
from mylibrary import class1
```
当該クラスをライブラリ名+クラス名でインポートできます。 
\__init__.py

```__init__.py
from .file1 import class1
from .file2 import class2
from .file3 import * 


__copyright__    = 'Copyright (C) 2018 Your Name'
__version__      = '1.0.0'
__license__      = 'BSD-3-Clause'
__author__       = 'Your Name'
__author_email__ = 'Your@Email'
__url__          = 'http://github.com/account/repository'
```
### setup.pyの記述
setpy.pyのsetup関数を実行してインストールを行います。
インストール時に必要な情報を付加しておきます。
https://qiita.com/shinichi-takii/items/6d1063e0aa3f79e599f0
\__init__.py

```setup.py
from setuptools import setup
from os import path
import re

package_name = "パッケージ名"

root_dir = path.abspath(path.dirname(__file__))

def _requirements():
    return [name.rstrip() for name in open(path.join(root_dir, 'requirements.txt')).readlines()]


def _test_requirements():
    return [name.rstrip() for name in open(path.join(root_dir, 'test-requirements.txt')).readlines()]

with open(path.join(root_dir, package_name, '__init__.py')) as f:
    init_text = f.read()
    version = re.search(r'__version__\s*=\s*[\'\"](.+?)[\'\"]', init_text).group(1)
    license = re.search(r'__license__\s*=\s*[\'\"](.+?)[\'\"]', init_text).group(1)
    author = re.search(r'__author__\s*=\s*[\'\"](.+?)[\'\"]', init_text).group(1)
    author_email = re.search(r'__author_email__\s*=\s*[\'\"](.+?)[\'\"]', init_text).group(1)
    url = re.search(r'__url__\s*=\s*[\'\"](.+?)[\'\"]', init_text).group(1)

```

### docstringからドキュメントを自動生成する
docstringはgoogleスタイルまたはnumpyスタイルで記述しておくと良いでしょう。
https://qiita.com/11ohina017/items/118b3b42b612e527dc1d

pipで[sphinx](https://www.sphinx-doc.org/ja/master/)をインストールします。
https://qiita.com/futakuchi0117/items/4d3997c1ca1323259844
次に./mylibraryディレクトリ(ソースが含まれていない方の)で以下のコマンドを打ちます。

```
sphinx-quickstart docs
```
プロジェクトと作者の名前だけは適宜入力し、それ以外はデフォルトで問題ありません。

__docsディレクトリに移動__
conf.pyファイルが作成されてると思います。
__これはsphinxで作成するhtmlの設定を記述したファイルです。__

```setup.py
import os
import sys
#ソースディレクトリの追加
sys.path.insert(0, os.path.abspath('../mylibrary'))
#docstring作成機能を有効化
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.napoleon','sphinx.ext.viewcode',
]
#htmlテーマの選択
html_theme = "blue"

```
setu.pyの書き方はflaskが参考になります。
https://github.com/pallets/flask/blob/master/docs/conf.py
htmlテーマは以下のサイトで好みのものをダウンロードできます。
https://sphinx-themes.org/

#### apidocを作成する
APIリファレンスを作成します。

```
sphinx-apidoc -f -o ./docs .
```
これにより、ソースファイルが存在する./mylibraryディレクトリをsphinxがスキャンしてクラスを抽出してくれます。

### index, apidocの編集
apidocの中でAPIとして公開する必要のないクラスや、apidocにまとめるのではなく、クラスごとに別のページに分割したいと思うことがあると思います。
その際はrstファイルを編集してしまいましょう
rstファイルの編集は簡単でapidocにあるクラス一覧から不要なクラスを削除します。

__また、index.rstファイルからapidocにリンクを貼ります.__
__この作業を忘れるとsphinxをビルドしても、APIリファレンスが作成されません__

```index.rst
.. toctree::
   :maxdepth: 2
   :caption: Contents:

   apidoc
```

### ドキュメントのビルド
docsディレクトリでhtmlファイルを作成します。

```
make html
#windowsならば make.bat html
```

これでdocs/_build/htmlにsphinxでビルドされたhmtlページが作成されます。
このディレクトリをnetlifyやgithubで公開することでAPIリファレンスページとして使用できます。
より美しいAPIリファレンスを作成する場合はfalskのrstファイル作成方法が参考になります。
https://github.com/pallets/flask/tree/master/docs

### ライブラリのインストール
あとはライブラリをインストールするだけです.

```
python setup.py install
```

お疲れ様でした!