自分で作ったPythonの野球ライブラリをパッケージング&PyPIに公開してみた

2016年初エントリーですね.

今年もPythonと野球ネタ中心で学びをストックしたいと思います.

よろしくお願いします！

# やったこと

* MLB一球速報データを取得&前処理してデータセット(CSVファイル)に落とすPythonライブラリを開発
* コマンドラインアプリ化
* パッケージング
* PyPIに登録&公開
* pipで入れて動かす

パッケージング&PyPI公開はこちらの書籍を参考にさせて頂きました.

[Pythonプロフェッショナルプログラミング第2版（通称：Pyプロ本・Python黒本）](http://www.amazon.co.jp/dp/479804315X "Pythonプロフェッショナルプログラミング第2版")

## MLB一球速報データを取得&前処理してデータセット(CSVファイル)に落とすPythonライブラリを開発

[MLBAM](http://www.mlbam.com/ "MLB Advanced Media")の一球速報データ(XML)を取得、スクレイピングしてCSVとしてダウンロードするスクリプトを作りました.

[pitchpx(GitHub)](https://github.com/Shinichi-Nakagawa/pitchpx "pitchpx")

何が出来るのかはこちらの投稿を参照ください.

[メジャーリーグの一球速報データをPyDataできるようにしてみました(まだ途中) #大晦日ハッカソン](http://shinyorke.hatenablog.com/entry/2015/12/31/234436 "メジャーリーグの一球速報データをPyDataできるようにしてみました(まだ途中) #大晦日ハッカソン")

まだ出来は荒っぽいですが最低限使える所までできました.

## コマンドラインアプリ化

何となくデータ分析に使える所までいったので、せっかくだからパッケージにして野球好きが気軽に使えるようにしよう！ということで、

* 作ったライブラリ「pitchpx」をコマンドライン化
* PyPIに登録して気軽に利用可能に

という感じで公開することにしました.

コマンドライン化については、元々そのつもりで作っていたのでアッサリ出来ました.

コマンドラインオプションの定義と制御はclickという超便利なライブラリのおかげで楽に出来ました.

[click(Python)](http://click.pocoo.org/5/ "click")

click(とfabricの合わせ技)については以下のスライドに実例があります（大変わかり易い！）

[3分でサーバオペレーションコマンドを作る技術(slideshare)](http://www.slideshare.net/laughk/3-53764813 "3分でサーバオペレーションコマンドを作る技術")

## パッケージング

Python歴5年目にして初めてチャレンジしました（震え声）

配布形式はWheelです.

手順はこんな感じ.

1. wheelライブラリをインストール
2. setup.pyを書く・テストする
3. 配布パッケージを作る

### wheelライブラリをインストール

> pip install wheel

以上

### setup.pyを書く・テストする

Pyプロ本の第三章および、Python公式の「[setup スクリプトを書く](http://docs.python.jp/3.5/distutils/setupscript.html "setup スクリプトを書く")」を参考に記述しました.

```py3:setup.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from setuptools import setup, find_packages

__author__ = 'Shinichi Nakagawa'


setup(
    name='pitchpx',  # ライブラリの名前
    version='1.0',  # バージョン
    description='Tools for Acquiring MLBAM Gameday dataset',  # 解説
    author='Shinichi Nakagawa',  # 作った人
    author_email='hogefuga@gmail.com',  # 作った人の連絡先
    url='https://github.com/Shinichi-Nakagawa/pitchpx',  # URL(Githubリポジトリ)
    classifiers=[  # 注記事項(開発ステータス,利用目的,LICENSEなど)
        'Development Status :: 4 - Beta',
        'Intended Audience :: Science/Research',
        'License :: OSI Approved :: MIT License',
        'Natural Language :: English',
        'Programming Language :: Python :: 3.5',
        'Programming Language :: Python :: 3 :: Only',
    ],
    packages=find_packages(),  # 梱包するコードの場所. setuptoolsのfind_packages()でパッケージなdirectoryを捜索&よしなに突っ込んでくれます
    include_package_data=True,  # ソースコード(*.py)以外のファイルも入れるか否か
    keywords=['baseball', 'MLB', 'MLBAM'],  # キーワード
    license='MIT License',  # ライセンス
    install_requires=[  # 依存ライブラリ
        'beautifulsoup4',
        'click',
        'FormEncode',
        'lxml',
        'python-dateutil',
        'pytz',
        'PyYAML',
    ],
    entry_points="""  # コマンドラインにするときのエントリーポイント、pitchpx/__init__.pyの関数をエントリーポイントにしました.
        [console_scripts]
        pitchpx = pitchpx:main
    """,
)
```

できたら試しに動かしてみます

> $ pip install -e .

何事も無くインストール終了&コマンドが無事使えたらOKです.

> $ pitchpx -s 20150812 -e 20150813 -o ~/Download  # 2015/8/12-8/13までの試合結果を~/Downloadに落とす

### 配布パッケージを作る

Wheelでの配布なのでコマンドはこんな感じ.

> $ python setup.py bdist_wheel

上手く行ったっぽいです.

> $ ls ./dist
> pitchpx-1.0-py3-none-any.whl

他の言語も含め、パッケージ作って公開なんてしたことが無かったのでビビっていたのですが、ここまで割とアッサリできました.

## 作ったライブラリをPyPIに登録&公開

### PyPIにユーザー登録

登録フォーム（[https://pypi.python.org/pypi?%3Aaction=register_form](https://pypi.python.org/pypi?%3Aaction=register_form "Manual user registration")）に名前とメアド、パスワードを入れて終了.

### パッケージを登録

> $ python setup.py register

選択肢が出てきたら「2」を選択、先ほど登録したユーザー名とパスワードで登録を行います.

### パッケージをアップロード

> $ python setup.py bdist_wheel upload

パッケージ登録にしくじっていなければこれでイケます.

これで上手く行っていればpip installで動くはず！

## pipで入れて動かす

別のdirectoryに動いてvirtualenvで環境を準備、試しに動かしてみます.

> $ pyenv virtualenv 3.5.1 pitchpx-test  # pyenv install 3.5.1 ですでにPython 3.5.1が入ってる前提
> Ignoring indexes: https://pypi.python.org/simple
> Requirement already satisfied (use --upgrade to upgrade): setuptools in /usr/local/Cellar/pyenv/20151222/versions/3.5.1/envs/pitchpx-test/lib/python3.5/site-packages
> Requirement already satisfied (use --upgrade to upgrade): pip in /usr/local/Cellar/pyenv/20151222/versions/3.5.1/envs/pitchpx-test/lib/python3.5/site-packages
> pyenv-virtualenv: deactivate
> pyenv-virtualenv: activate pitchpx-test
> $ pip install pitchpx
> Collecting pitchpx
>   Using cached pitchpx-1.0-py3-none-any.whl
> Collecting python-dateutil (from pitchpx)
>   Using cached python_dateutil-2.4.2-py2.py3-none-any.whl
> Collecting lxml (from pitchpx)
> Collecting FormEncode (from pitchpx)
> Collecting beautifulsoup4 (from pitchpx)
>   Using cached beautifulsoup4-4.4.1-py3-none-any.whl
> Collecting pytz (from pitchpx)
>   Using cached pytz-2015.7-py2.py3-none-any.whl
> Collecting click (from pitchpx)
>   Using cached click-6.2-py2.py3-none-any.whl
> Collecting PyYAML (from pitchpx)
> Collecting six>=1.5 (from python-dateutil->pitchpx)
>   Using cached six-1.10.0-py2.py3-none-any.whl
> Installing collected packages: six, python-dateutil, lxml, FormEncode, beautifulsoup4, pytz, click, PyYAML, pitchpx
> Successfully installed FormEncode-1.3.0 PyYAML-3.11 beautifulsoup4-4.4.1 click-6.2 lxml-3.5.0 pitchpx-1.0 python-dateutil-2.4.2 pytz-2015.7 six-1.10.0
> $ pip freeze
> beautifulsoup4==4.4.1
> click==6.2
> FormEncode==1.3.0
> lxml==3.5.0
> pitchpx==1.0
> python-dateutil==2.4.2
> pytz==2015.7
> PyYAML==3.11
> six==1.10.0
> $ pitchpx -s 20150812 -e 20150813 -o ~/Downloads/

無事にダウンロード出来ました(^O^)

> $ ls -l ~/Downloads/ | grep mlbam*
> -rw-r--r--  1 hoge  staff     334766  1  2 17:22 mlbam_atbat_20150812.csv
> -rw-r--r--  1 hoge  staff     208526  1  2 17:23 mlbam_atbat_20150813.csv
> -rw-r--r--  1 hoge  staff    1695169  1  2 17:22 mlbam_pitch_20150812.csv
> -rw-r--r--  1 hoge  staff    1078535  1  2 17:23 mlbam_pitch_20150813.csv

## 学び&今後

### コマンド&パッケージ&配布

* clickくっそ便利.
* パッケージ化は思ったより楽だった.
* 今後はなにか作る時は必ずsetup.pyを書く癖をつけよう.
* 困ったときのPyプロ本、Pythonistaなら確実に役立つネタだらけで素晴らしい.

### ライブラリ

* 目的どおり動いてるっぽくて良かった.
* 打席(atbat)および投球(pitch)のテストが済んでいないのでちゃんとやりたい.
* それ以上にPython3.5.x専用なのを何とかせねば.
* なお、Python2対応はしない模様.

### etc

* 次はデータ分析と可視化頑張る.
* 年末年始休みの宿題が無事終わって良かった.
* やっぱプログラミング楽しい.