汎用的に使えるPythonプロジェクトのテンプレートを作成しました

Pythonをよく使うのですが、毎回毎回同じようなコードを叩いて環境を構築していました。
これがかなり時間かかる&使う部分は同じなので、汎用目的に使えるプロジェクトテンプレートとしてリポジトリを公開しました。
https://github.com/odrum428/python_setup

## 目的
Pythonプロジェクトを始めるときに、CIやドキュメント周りなど、いつも同じようなコマンド入力して作ってました。

Pipenv使ってプロジェクト初期化して、CI定義して、テストとlint入れて、Sphinxでドキュメント化みたいな感じです。

これらを整えるのに毎回そこそこ時間がかかっていたので、どんなPythonプロジェクトでも使える構成を目指してプロジェクトのテンプレートを作成しました。

分析、アプリ、モデル生成でも一応対応可能に作ってあります。


## 構成概要

### パッケージ
パッケージや環境諸々管理にはpipenvを使用しています。
これら管理ツールについては以下の記事がまとまっているので、参照されるといいかと思います。
[Pythonのパッケージ周りのベストプラクティスを理解する](https://www.m3tech.blog/entry/python-packaging)

現状ではpipenvを使い、諸々の設定管理をsetup.pyとsetup.cfgで行うのが最適だと思います。
使ってみた感じ、かなり管理や構築は楽になりました。

今回作成したプロジェクトで使っているパッケージ等をまとめました。

- isort
- flake8
- Sphinx
- pytest
- sphinx-rtd-theme

 基本のlint系として、パッケージのimportなどを整える`isort`とコードスタイルを整える`flake8`を導入しました。
これ以外にも`yapf`などもありますが、標準であるPEP8を採用し、とりまわりのいい`flake8`にしました。こちらはエラー箇所のコードが表示
されるように設定を行っています。

 テストにはpytestを採用しました。
正直pythonのテストはpytestを使っておけば、まず問題ないと思います。標準のunittestよりもpytestの方ができることも多いし、取り回しも良いです。

 また、このテンプレートでは、Sphinxを用いたドキュメント生成を行っています。
ドキュメントは`tests`フォルダ内で定義されたテストコードやdocstringから生成されます。
テストケースのみからドキュメントを生成することで、積極的にテストケースが書かれ、かつドキュメントも充実していくことを目指しています。
ドキュメントのテーマには [sphinx-rtd-theme](https://pypi.org/project/sphinx-rtd-theme/)を使用しています。


### CI
Circle CIを用いたCIも導入しています。
コードのスタイルを保つために`isort`と`flake8`によるLintを実行し、`pytest`を用いてテストコードを実行します。
複数バージョンのテスト実行を可能にする`tox`やテストをランダムにする`pytest-randomly`などは汎用的には使用しないので除外しています。

また、これらに加え、ドキュメントの自動更新も実装しました。
`tests`フォルダに更新があった場合は、CIでドキュメントを更新してGitのコミットまでを行うようにしています。

```yaml
  is_docs_update:
    steps:
      - run:
          name: check tests folder is updated
          command: |
            if [[ ! $(git diff --diff-filter=d --name-only HEAD | grep tests/ ) = '' ]]; then
              echo "build and deploy"
            else
                echo "no need docs update"
                circleci step halt
            fi
      - run:
          name: make rst file
          command: |
            pipenv run sphinx-apidoc -f -o docs/ tests/
      - run:
          name: make html
          command: |
            pipenv run sphinx-build -a ./docs ./docs/public
      - run:
          name: git push
          command: | 
            git config --global user.email oxkeita@gmail.com
            git config --global user.name odrum428
            git add -A
            git commit -m 'updating docs [skip ci]'
            git push origin HEAD
```
### ファイル構成
以下にファイル構成を示します。

```
 ├ .circleci/
 ├ .envrc
 ├ .github/
 ├ .gitignore
 ├ docs/
 │  ├ Makefile
 │  ├ conf.py
 │  ├ index.rst
 │  ├ make.bat
 │  ├ modules.rst
 │  ├ public/
 │  └ tests.rst
 │
 ├ src/
 ├ tests/
 ├ LICENSE
 ├ Pipfile
 ├ Pipfile.lock
 ├ README.md
 ├ setup.cfg
 └ setup.py
```

簡単にソースとテスト、ドキュメントに構成を分けました。

アプリコード、機械学習、分析コードなどはすべて`src`内で、それぞれいい感じに管理。それと同じファイル構成でテストコードを書く。
テストコードからドキュメントが生成される。みたいなイメージです。

ここから用途に合わせて、拡張させていけばよいと考えています。

パッケージや諸々の設定はsetup.cfgで行います。
こうすることでかなりコードが簡素化でき、以下のように書くことができます。

```python:setup.py
from setuptools import setup

setup()

```

設定の実質的な中身はsetup.cfg内で設定します。

```ini
[metadata]
name = sample-package
version = '1.0'
auther = Keita Mizushima
auther_email = oxkeita@gmail.com
description = sample repogitory of python
description-file = file: README.md
url = http://example.com
license = MIT
license_file = LICENSE

[options]
install_requires=
packages = find:

[flake8]
show_source = True
max-line-length=120
max-complexity=15
```


## 使い方
シンプルにこのリポジトリをベースに新しいプロジェクトを登録するだけです。
1.GitHubのリポジトリを作成する。

今回は`new_project`というリポジトリを作成しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285875/f033e258-584b-2474-eba5-f5dba45a9f1e.png)


2. このリポジトリを元に、新しいプロジェクトを開始する

```
git clone git@github.com:odrum428/python_setup.git new_poject
cd new_project
git remote set-url origin git@github.com:user_name/new_project.git
git push origin master
```

これでこのリポジトリを引き継いだまま、新しいプロジェクトが作成できた。

3 pipenvをinstallする。

```
pip install pipenv
```

おまけですが、direnvを使うと仮想環境間を自動で切り替えてくれるので、おすすめです！
いちいち環境をactivateする必要がなくなります。
https://github.com/direnv/direnv

## まとめ
今後も環境が変わるたびにアップデートしていこうと思っているので、構成に困ったら使ってみてください。
また、リポジトリへのPRやまさかりもいただけると嬉しいです。

https://github.com/odrum428/python_setup