venvのJupyter Notebook利用時にModuleNotFoundErrorが出てきてしまった時の対処

Google Cloud Pubsubを利用した簡単なシステムを作成したので、動作確認のために手元のWindows機からJupyter Notebook上で動作確認しようとしていました。その際きちんと

ただ、 `pip install google-cloud-pubsub` を行ったはずなのに、importに失敗します。

```python
from google.cloud import pubsub_v1
publisher = pubsub_v1.PublisherClient()
topic_path = publisher.topic_path("project-name", "name")
publisher.publish(topic_path, data=b'{"data": "sample"}')
```

PythonのコンソールやiPython上ではimportできるため、AnacondaかJupyter Notebookに関する問題だと考えられます。ちょっと調べてみました。

## 結論

結論から書いてしまうと、venv環境のJupyter Notebookを使うためには予めkernelを追加する必要がありました。

* [jupyter notebookでvenvを使う](https://qiita.com/Mujica/items/80a5d36673ba2b6ef7f0)
* [Using jupyter notebooks with a virtual environment](https://qiita.com/Mujica/items/80a5d36673ba2b6ef7f0)

ただ、自分の場合、実はpipenvの内部でvenvを利用してしまっていたため、venvのプロジェクト名がややこしく、仮想環境を使わずに直接 `pip install` して使うことにしました。ちょっとイケてないですが、手元のWindows環境は程度にしか使わないので…（言い訳）。

## 調査方法

せっかくなので自分が調査した方法もメモに残しておきます。まず、Pythonのimport対象のディレクトリパスを確認します。

このあたりの記事を読んでください。

* [Pythonでimportの対象ディレクトリのパスを確認・追加（sys.pathなど）](https://note.nkmk.me/python-import-module-search-path/)
* [Python Tips：ライブラリ・モジュールの場所を調べたい](https://www.lifewithpython.com/2014/07/python-get-location-of-libraries-modules-packages.html)

```python
>>> import sys
>>> sys.path
['', 'C:\\Users\\ninomiyt\\.virtualenvs\\Desktop-5H1ZMg56\\Scripts\\python37.zip', 'C:\\Users\\ninomiyt\\.virtualenvs\\Desktop-5H1ZMg56\\DLLs', 'C:\\Users\\ninomiyt\\.virtualenvs\\Desktop-5H1ZMg56\\lib', 'C:\\Users\\ninomiyt\\.virtualenvs\\Desktop-5H1ZMg56\\Scripts', 'c:\\users\\ninomiyt\\appdata\\local\\continuum\\anaconda3\\Lib', 'c:\\users\\ninomiyt\\appdata\\local\\continuum\\anaconda3\\DLLs', 'C:\\Users\\ninomiyt\\.virtualenvs\\Desktop-5H1ZMg56', 'C:\\Users\\ninomiyt\\.virtualenvs\\Desktop-5H1ZMg56\\lib\\site-packages']
>>> from google.cloud import pubsub_v1
>>> pubsub_v1.__file__
'C:\\Users\\ninomiyt\\.virtualenvs\\Desktop-5H1ZMg56\\lib\\site-packages\\google\\cloud\\pubsub_v1\\__init__.py'
```

Jupyter Notebook上ではこのようになります。

```python
In [1]: import sys; sys.path
Out[1]: ['C:\\Users\\ninomiyt\\Desktop',
 'C:\\Users\\ninomiyt\\AppData\\Local\\Continuum\\anaconda3\\python37.zip',
 'C:\\Users\\ninomiyt\\AppData\\Local\\Continuum\\anaconda3\\DLLs',
 'C:\\Users\\ninomiyt\\AppData\\Local\\Continuum\\anaconda3\\lib',
 'C:\\Users\\ninomiyt\\AppData\\Local\\Continuum\\anaconda3',
 '',
 'C:\\Users\\ninomiyt\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages',
 'C:\\Users\\ninomiyt\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\win32',
 'C:\\Users\\ninomiyt\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\win32\\lib',
 'C:\\Users\\ninomiyt\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\Pythonwin',
 'C:\\Users\\ninomiyt\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\IPython\\extensions',
 'C:\\Users\\ninomiyt\\.ipython']
```

`pubsub_v1` のファイルパス（ ` 'C:\\Users\\ninomiyt\\.virtualenvs\\Desktop-5H1ZMg56\\lib\\site-packages'` ）がJupyter Notebook上では存在しないことが分かります。これはvenvの環境のパスなので、Jupyter Notebookでvenvのパスであることが分かりました。

ちなみにsys.pathに直接追加してもimportできるようになりました。

```python
import sys
sys.path.append('C:\\Users\\ninomiyt\\.virtualenvs\\Desktop-5H1ZMg56\\lib\\site-packages')
from google.cloud import pubsub_v1
```

厄介な問題かもしれないと考えて記事を書きながら対処したのですが、思ったより単純な問題でした。