Azure App Serviceにpipを使用できないパッケージをインストールする

## はじめに
Azure App ServiceにPythonアプリケーションをデプロイする際、wheelによるコンパイルが必要なパッケージのインストールに大変苦戦したので、メモを残しておきます :pencil2::notebook: 読者対象として、Azure App Serviceの概要やGitによるデプロイ方法について知っている方を想定しています。前提知識がない方は、[Azure App Service Web Apps による Python の構成](https://docs.microsoft.com/ja-jp/azure/app-service-web/web-sites-python-configure)や[Azure での Django を使用した Web アプリの作成](https://docs.microsoft.com/ja-jp/azure/app-service-web/web-sites-python-create-deploy-django-app)のページを最初にご覧ください。

なお、今回は以下の環境にパッケージをインストールしています。

- Python 3.4.1 32bit(既定でApp Serviceに用意されている環境)
- azure-storage 0.34.3
- django-pyodbc-azure 1.11
- django 1.11

## デプロイエラー

wheelが必要なパッケージをインストールする際、[公式ドキュメント](https://docs.microsoft.com/ja-jp/azure/app-service-web/web-sites-python-create-deploy-django-app#a-nametroubleshooting---package-installationa%E3%83%88%E3%83%A9%E3%83%96%E3%83%AB%E3%82%B7%E3%83%A5%E3%83%BC%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0---%E3%83%91%E3%83%83%E3%82%B1%E3%83%BC%E3%82%B8%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)を参考に何度デプロイしても、以下のようなエラーが発生して困っていました。今回はこのエラーを解消していきます。

```
remote:   Running setup.py install for pyodbc
remote:     building 'pyodbc' extension
remote:     error: Unable to find vcvarsall.bat
remote:     Complete output from command D:\home\site\wwwroot\env\Scripts\python.exe -c "import setuptools, tokenize;__file__='D:\\home\\site\\wwwroot\\env\\build\\pyodbc\\setup.py';exec(compile(getattr(tokenize, 'open', open)(__file__).read().replace('\r\n', '\n'), __file__, 'exec'))" install --record D:\local\Temp\pip-okpfh2du-record\install-record.txt --single-version-externally-managed --compile --install-headers D:\home\site\wwwroot\env\include\site\python3.4:
remote:     running install
remote:
remote: running build
remote:
remote: running build_ext
remote:
remote: building 'pyodbc' extension
remote:
remote: error: Unable to find vcvarsall.bat
remote:
remote: ----------------------------------------
```

## wheelによるローカルビルドとファイルリネーム
Azure App Serviceはサンドボックス環境となっています。そのため、CやC++をラッパーして作られたライブラリを**pipでインストールできません**。それらのパッケージをインストールするには、**wheelによる事前ビルド**が必要になります。また、ビルドするPython環境はApp Serviceと同一のプラットフォーム/アーキテクチャ/バージョンである必要があります。つまり、Windows上にPython 2.7 32bitか 3.4 32bitが求められます。また、C++の環境も[Python 2.7](https://www.microsoft.com/en-us/download/details.aspx?id=44266)用と[Python 3](https://www.microsoft.com/ja-jp/download/details.aspx?id=5555)用で異なるので注意してください。環境が準備できたら、以下のコマンドを実行します。

```
python -m pip install --upgrade pip
pip install wheel
pip wheel azure-storage
pip wheel django-pyodbc-azure
```

上記コマンドを実行すると、.whlファイルが生成されるので、デプロイ予定のアプリケーションのルートディレクトリに**wheelhouse**フォルダーを作成してそこにコピーします。

続いて、コピーした.whlファイルの一部をリネームします。ここが最大のつまずきポイントでしたが、**App Serviceのデプロイメントは`none`タグしかサポートされていません** :confounded: （Githubの[Issue](https://github.com/Azure/azure-storage-python/issues/219#issuecomment-250763151)を漁って、やっとたどり着きました。。。）そこで、`cryptography-1.5.2-cp34-cp34m-win32.whl => cryptography-1.5.2-cp34-none-win32.whl`といった形で、ファイル名に含まれる`cp34m`を`none`にリネームします。今回インストールしたパッケージでは、cryptographyとcffi、pyodbcがリネーム対象となりました。私と異なるパッケージをインストールする場合でも、.whlファイルにnoneが含まれていなければ怪しいと思っていください。

## requirements.txtの修正
次に、requirements.txtの先頭に`--find-links wheelhouse`を追加します。これでGitデプロイした際にパッケージをwheelhouse内から検索してくれるようになります。なお、requirements.txtは以下のようになります。

```
--find-links wheelhouse
django==1.11
azure-storage==0.34.3
django-pyodbc-azure==1.11
```

あとは、変更をGitでプルすれば、インストール環境です。

## 最後に
Azure App Serviceは大変便利ですがパッケージインストールに癖がありますね。。。C#やNode.jsで作成したアプリのデプロイの方がだいぶ簡単な印象を持ちました。